Annotation of qemu/pc-bios/optionrom/multiboot.S, revision 1.1.1.2

1.1       root        1: /*
                      2:  * Multiboot Option ROM
                      3:  *
                      4:  * This program is free software; you can redistribute it and/or modify
                      5:  * it under the terms of the GNU General Public License as published by
                      6:  * the Free Software Foundation; either version 2 of the License, or
                      7:  * (at your option) any later version.
                      8:  *
                      9:  * This program is distributed in the hope that it will be useful,
                     10:  * but WITHOUT ANY WARRANTY; without even the implied warranty of
                     11:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
                     12:  * GNU General Public License for more details.
                     13:  *
                     14:  * You should have received a copy of the GNU General Public License
                     15:  * along with this program; if not, see <http://www.gnu.org/licenses/>.
                     16:  *
                     17:  * Copyright Novell Inc, 2009
                     18:  *   Authors: Alexander Graf <[email protected]>
                     19:  */
                     20: 
1.1.1.2 ! root       21: #include "optionrom.h"
1.1       root       22: 
                     23: #define MULTIBOOT_MAGIC                0x2badb002
                     24: 
1.1.1.2 ! root       25: #define GS_PROT_JUMP           0
        !            26: #define GS_GDT_DESC            6
        !            27: 
1.1       root       28: 
1.1.1.2 ! root       29: BOOT_ROM_START
1.1       root       30: 
                     31: run_multiboot:
                     32: 
                     33:        cli
                     34:        cld
                     35: 
                     36:        mov             %cs, %eax
                     37:        shl             $0x4, %eax
                     38: 
1.1.1.2 ! root       39:        /* set up a long jump descriptor that is PC relative */
1.1       root       40: 
1.1.1.2 ! root       41:        /* move stack memory to %gs */
        !            42:        mov             %ss, %ecx
        !            43:        shl             $0x4, %ecx
        !            44:        mov             %esp, %ebx
        !            45:        add             %ebx, %ecx
        !            46:        sub             $0x20, %ecx
        !            47:        sub             $0x30, %esp
        !            48:        shr             $0x4, %ecx
        !            49:        mov             %cx, %gs
        !            50: 
        !            51:        /* now push the indirect jump decriptor there */
1.1       root       52:        mov             (prot_jump), %ebx
                     53:        add             %eax, %ebx
1.1.1.2 ! root       54:        movl            %ebx, %gs:GS_PROT_JUMP
        !            55:        mov             $8, %bx
        !            56:        movw            %bx, %gs:GS_PROT_JUMP + 4
        !            57: 
        !            58:        /* fix the gdt descriptor to be PC relative */
        !            59:        movw            (gdt_desc), %bx
        !            60:        movw            %bx, %gs:GS_GDT_DESC
        !            61:        movl            (gdt_desc+2), %ebx
        !            62:        add             %eax, %ebx
        !            63:        movl            %ebx, %gs:GS_GDT_DESC + 2
        !            64: 
        !            65:        xor             %eax, %eax
        !            66:        mov             %eax, %es
        !            67: 
        !            68:        /* Read the bootinfo struct into RAM */
        !            69:        read_fw_blob(FW_CFG_INITRD)
1.1       root       70: 
                     71:        /* FS = bootinfo_struct */
                     72:        read_fw         FW_CFG_INITRD_ADDR
                     73:        shr             $4, %eax
                     74:        mov             %ax, %fs
                     75: 
                     76:        /* ES = mmap_addr */
1.1.1.2 ! root       77:        mov             %fs:48, %eax
1.1       root       78:        shr             $4, %eax
                     79:        mov             %ax, %es
                     80: 
                     81:        /* Initialize multiboot mmap structs using int 0x15(e820) */
                     82:        xor             %ebx, %ebx
                     83:        /* mmap start after first size */
                     84:        movl            $4, %edi
                     85: 
                     86: mmap_loop:
                     87:        /* entry size (mmap struct) & max buffer size (int15) */
                     88:        movl            $20, %ecx
                     89:        /* store entry size */
1.1.1.2 ! root       90:        /* old as(1) doesn't like this insn so emit the bytes instead:
1.1       root       91:        movl            %ecx, %es:-4(%edi)
1.1.1.2 ! root       92:        */
        !            93:        .dc.b           0x26,0x67,0x66,0x89,0x4f,0xfc
1.1       root       94:        /* e820 */
                     95:        movl            $0x0000e820, %eax
                     96:        /* 'SMAP' magic */
                     97:        movl            $0x534d4150, %edx
                     98:        int             $0x15
                     99: 
                    100: mmap_check_entry:
                    101:        /* last entry? then we're done */
                    102:        jb              mmap_done
                    103:        and             %bx, %bx
                    104:        jz              mmap_done
                    105:        /* valid entry, so let's loop on */
                    106: 
                    107: mmap_store_entry:
                    108:        /* %ax = entry_number * 24 */
                    109:        mov             $24, %ax
                    110:        mul             %bx
                    111:        mov             %ax, %di
                    112:        movw            %di, %fs:0x2c
                    113:        /* %di = 4 + (entry_number * 24) */
                    114:        add             $4, %di
                    115:        jmp             mmap_loop
                    116: 
                    117: mmap_done:
                    118: real_to_prot:
                    119:        /* Load the GDT before going into protected mode */
                    120: lgdt:
1.1.1.2 ! root      121:        data32 lgdt     %gs:GS_GDT_DESC
1.1       root      122: 
                    123:        /* get us to protected mode now */
                    124:        movl            $1, %eax
                    125:        movl            %eax, %cr0
                    126: 
                    127:        /* the LJMP sets CS for us and gets us to 32-bit */
                    128: ljmp:
1.1.1.2 ! root      129:        data32 ljmp     *%gs:GS_PROT_JUMP
1.1       root      130: 
                    131: prot_mode:
                    132: .code32
                    133: 
                    134:        /* initialize all other segments */
                    135:        movl            $0x10, %eax
                    136:        movl            %eax, %ss
                    137:        movl            %eax, %ds
                    138:        movl            %eax, %es
                    139:        movl            %eax, %fs
                    140:        movl            %eax, %gs
                    141: 
1.1.1.2 ! root      142:        /* Read the kernel and modules into RAM */
        !           143:        read_fw_blob(FW_CFG_KERNEL)
        !           144: 
1.1       root      145:        /* Jump off to the kernel */
1.1.1.2 ! root      146:        read_fw         FW_CFG_KERNEL_ENTRY
1.1       root      147:        mov             %eax, %ecx
                    148: 
                    149:        /* EBX contains a pointer to the bootinfo struct */
                    150:        read_fw         FW_CFG_INITRD_ADDR
                    151:        movl            %eax, %ebx
                    152: 
                    153:        /* EAX has to contain the magic */
                    154:        movl            $MULTIBOOT_MAGIC, %eax
                    155: ljmp2:
                    156:        jmp             *%ecx
                    157: 
                    158: /* Variables */
                    159: .align 4, 0
                    160: prot_jump:     .long prot_mode
                    161:                .short 8
                    162: 
                    163: .align 4, 0
                    164: gdt:
                    165:        /* 0x00 */
                    166: .byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
                    167: 
                    168:        /* 0x08: code segment (base=0, limit=0xfffff, type=32bit code exec/read, DPL=0, 4k) */
                    169: .byte  0xff, 0xff, 0x00, 0x00, 0x00, 0x9a, 0xcf, 0x00
                    170: 
                    171:        /* 0x10: data segment (base=0, limit=0xfffff, type=32bit data read/write, DPL=0, 4k) */
                    172: .byte  0xff, 0xff, 0x00, 0x00, 0x00, 0x92, 0xcf, 0x00
                    173: 
                    174:        /* 0x18: code segment (base=0, limit=0x0ffff, type=16bit code exec/read/conf, DPL=0, 1b) */
                    175: .byte  0xff, 0xff, 0x00, 0x00, 0x00, 0x9e, 0x00, 0x00
                    176: 
                    177:        /* 0x20: data segment (base=0, limit=0x0ffff, type=16bit data read/write, DPL=0, 1b) */
                    178: .byte  0xff, 0xff, 0x00, 0x00, 0x00, 0x92, 0x00, 0x00
                    179: 
                    180: gdt_desc:
                    181: .short (5 * 8) - 1
                    182: .long  gdt
                    183: 
1.1.1.2 ! root      184: BOOT_ROM_END

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.