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

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: 
1.1.1.3 ! root       23: #define BOOT_ROM_PRODUCT "multiboot loader"
        !            24: 
1.1       root       25: #define MULTIBOOT_MAGIC                0x2badb002
                     26: 
1.1.1.2   root       27: #define GS_PROT_JUMP           0
                     28: #define GS_GDT_DESC            6
                     29: 
1.1       root       30: 
1.1.1.2   root       31: BOOT_ROM_START
1.1       root       32: 
                     33: run_multiboot:
                     34: 
                     35:        cli
                     36:        cld
                     37: 
                     38:        mov             %cs, %eax
                     39:        shl             $0x4, %eax
                     40: 
1.1.1.2   root       41:        /* set up a long jump descriptor that is PC relative */
1.1       root       42: 
1.1.1.2   root       43:        /* move stack memory to %gs */
                     44:        mov             %ss, %ecx
                     45:        shl             $0x4, %ecx
                     46:        mov             %esp, %ebx
                     47:        add             %ebx, %ecx
                     48:        sub             $0x20, %ecx
                     49:        sub             $0x30, %esp
                     50:        shr             $0x4, %ecx
                     51:        mov             %cx, %gs
                     52: 
                     53:        /* now push the indirect jump decriptor there */
1.1       root       54:        mov             (prot_jump), %ebx
                     55:        add             %eax, %ebx
1.1.1.2   root       56:        movl            %ebx, %gs:GS_PROT_JUMP
                     57:        mov             $8, %bx
                     58:        movw            %bx, %gs:GS_PROT_JUMP + 4
                     59: 
                     60:        /* fix the gdt descriptor to be PC relative */
                     61:        movw            (gdt_desc), %bx
                     62:        movw            %bx, %gs:GS_GDT_DESC
                     63:        movl            (gdt_desc+2), %ebx
                     64:        add             %eax, %ebx
                     65:        movl            %ebx, %gs:GS_GDT_DESC + 2
                     66: 
                     67:        xor             %eax, %eax
                     68:        mov             %eax, %es
                     69: 
                     70:        /* Read the bootinfo struct into RAM */
                     71:        read_fw_blob(FW_CFG_INITRD)
1.1       root       72: 
                     73:        /* FS = bootinfo_struct */
                     74:        read_fw         FW_CFG_INITRD_ADDR
                     75:        shr             $4, %eax
                     76:        mov             %ax, %fs
                     77: 
                     78:        /* ES = mmap_addr */
1.1.1.2   root       79:        mov             %fs:48, %eax
1.1       root       80:        shr             $4, %eax
                     81:        mov             %ax, %es
                     82: 
                     83:        /* Initialize multiboot mmap structs using int 0x15(e820) */
                     84:        xor             %ebx, %ebx
                     85:        /* mmap start after first size */
                     86:        movl            $4, %edi
                     87: 
                     88: mmap_loop:
                     89:        /* entry size (mmap struct) & max buffer size (int15) */
                     90:        movl            $20, %ecx
                     91:        /* store entry size */
1.1.1.2   root       92:        /* old as(1) doesn't like this insn so emit the bytes instead:
1.1       root       93:        movl            %ecx, %es:-4(%edi)
1.1.1.2   root       94:        */
                     95:        .dc.b           0x26,0x67,0x66,0x89,0x4f,0xfc
1.1       root       96:        /* e820 */
                     97:        movl            $0x0000e820, %eax
                     98:        /* 'SMAP' magic */
                     99:        movl            $0x534d4150, %edx
                    100:        int             $0x15
                    101: 
                    102: mmap_check_entry:
                    103:        /* last entry? then we're done */
                    104:        jb              mmap_done
                    105:        and             %bx, %bx
                    106:        jz              mmap_done
                    107:        /* valid entry, so let's loop on */
                    108: 
                    109: mmap_store_entry:
                    110:        /* %ax = entry_number * 24 */
                    111:        mov             $24, %ax
                    112:        mul             %bx
                    113:        mov             %ax, %di
                    114:        movw            %di, %fs:0x2c
                    115:        /* %di = 4 + (entry_number * 24) */
                    116:        add             $4, %di
                    117:        jmp             mmap_loop
                    118: 
                    119: mmap_done:
                    120: real_to_prot:
                    121:        /* Load the GDT before going into protected mode */
                    122: lgdt:
1.1.1.2   root      123:        data32 lgdt     %gs:GS_GDT_DESC
1.1       root      124: 
                    125:        /* get us to protected mode now */
                    126:        movl            $1, %eax
                    127:        movl            %eax, %cr0
                    128: 
                    129:        /* the LJMP sets CS for us and gets us to 32-bit */
                    130: ljmp:
1.1.1.2   root      131:        data32 ljmp     *%gs:GS_PROT_JUMP
1.1       root      132: 
                    133: prot_mode:
                    134: .code32
                    135: 
                    136:        /* initialize all other segments */
                    137:        movl            $0x10, %eax
                    138:        movl            %eax, %ss
                    139:        movl            %eax, %ds
                    140:        movl            %eax, %es
                    141:        movl            %eax, %fs
                    142:        movl            %eax, %gs
                    143: 
1.1.1.2   root      144:        /* Read the kernel and modules into RAM */
                    145:        read_fw_blob(FW_CFG_KERNEL)
                    146: 
1.1       root      147:        /* Jump off to the kernel */
1.1.1.2   root      148:        read_fw         FW_CFG_KERNEL_ENTRY
1.1       root      149:        mov             %eax, %ecx
                    150: 
                    151:        /* EBX contains a pointer to the bootinfo struct */
                    152:        read_fw         FW_CFG_INITRD_ADDR
                    153:        movl            %eax, %ebx
                    154: 
                    155:        /* EAX has to contain the magic */
                    156:        movl            $MULTIBOOT_MAGIC, %eax
                    157: ljmp2:
                    158:        jmp             *%ecx
                    159: 
                    160: /* Variables */
                    161: .align 4, 0
                    162: prot_jump:     .long prot_mode
                    163:                .short 8
                    164: 
                    165: .align 4, 0
                    166: gdt:
                    167:        /* 0x00 */
                    168: .byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
                    169: 
                    170:        /* 0x08: code segment (base=0, limit=0xfffff, type=32bit code exec/read, DPL=0, 4k) */
                    171: .byte  0xff, 0xff, 0x00, 0x00, 0x00, 0x9a, 0xcf, 0x00
                    172: 
                    173:        /* 0x10: data segment (base=0, limit=0xfffff, type=32bit data read/write, DPL=0, 4k) */
                    174: .byte  0xff, 0xff, 0x00, 0x00, 0x00, 0x92, 0xcf, 0x00
                    175: 
                    176:        /* 0x18: code segment (base=0, limit=0x0ffff, type=16bit code exec/read/conf, DPL=0, 1b) */
                    177: .byte  0xff, 0xff, 0x00, 0x00, 0x00, 0x9e, 0x00, 0x00
                    178: 
                    179:        /* 0x20: data segment (base=0, limit=0x0ffff, type=16bit data read/write, DPL=0, 1b) */
                    180: .byte  0xff, 0xff, 0x00, 0x00, 0x00, 0x92, 0x00, 0x00
                    181: 
                    182: gdt_desc:
                    183: .short (5 * 8) - 1
                    184: .long  gdt
                    185: 
1.1.1.2   root      186: 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.