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

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: 
                     21: #define NO_QEMU_PROTOS
                     22: #include "../../hw/fw_cfg.h"
                     23: 
                     24: #define BIOS_CFG_IOPORT_CFG    0x510
                     25: #define BIOS_CFG_IOPORT_DATA   0x511
                     26: 
                     27: #define MULTIBOOT_MAGIC                0x2badb002
                     28: 
                     29: /* Read a variable from the fw_cfg device.
                     30:    Clobbers:   %edx
                     31:    Out:                %eax */
                     32: .macro read_fw VAR
                     33:        mov             $\VAR, %ax
                     34:        mov             $BIOS_CFG_IOPORT_CFG, %dx
                     35:        outw            %ax, (%dx)
                     36:        mov             $BIOS_CFG_IOPORT_DATA, %dx
                     37:        inb             (%dx), %al
                     38:        shl             $8, %eax
                     39:        inb             (%dx), %al
                     40:        shl             $8, %eax
                     41:        inb             (%dx), %al
                     42:        shl             $8, %eax
                     43:        inb             (%dx), %al
                     44:        bswap           %eax
                     45: .endm
                     46: 
                     47: .code16
                     48: .text
                     49:        .global         _start
                     50: _start:
                     51:        .short          0xaa55
                     52:        .byte           1 /* (_end - _start) / 512 */
                     53:        push            %eax
                     54:        push            %ds
                     55: 
                     56:        /* setup ds so we can access the IVT */
                     57:        xor             %ax, %ax
                     58:        mov             %ax, %ds
                     59: 
                     60:        /* save old int 19 */
                     61:        mov             (0x19*4), %eax
                     62:        mov             %eax, %cs:old_int19
                     63: 
                     64:        /* install our int 19 handler */
                     65:        movw            $int19_handler, (0x19*4)
                     66:        mov             %cs, (0x19*4+2)
                     67: 
                     68:        pop             %ds
                     69:        pop             %eax
                     70:        lret
                     71: 
                     72: int19_handler:
                     73:        /* DS = CS */
                     74:        movw            %cs, %ax
                     75:        movw            %ax, %ds
                     76: 
                     77:        /* fall through */
                     78: 
                     79: run_multiboot:
                     80: 
                     81:        cli
                     82:        cld
                     83: 
                     84:        mov             %cs, %eax
                     85:        shl             $0x4, %eax
                     86: 
                     87:        /* fix the gdt descriptor to be PC relative */
                     88:        mov             (gdt_desc+2), %ebx
                     89:        add             %eax, %ebx
                     90:        mov             %ebx, (gdt_desc+2)
                     91: 
                     92:        /* fix the prot mode indirect jump to be PC relative */
                     93:        mov             (prot_jump), %ebx
                     94:        add             %eax, %ebx
                     95:        mov             %ebx, (prot_jump)
                     96: 
                     97:        /* FS = bootinfo_struct */
                     98:        read_fw         FW_CFG_INITRD_ADDR
                     99:        shr             $4, %eax
                    100:        mov             %ax, %fs
                    101: 
                    102:        /* ES = mmap_addr */
                    103:        read_fw         FW_CFG_INITRD_SIZE
                    104:        shr             $4, %eax
                    105:        mov             %ax, %es
                    106: 
                    107:        /* Initialize multiboot mmap structs using int 0x15(e820) */
                    108:        xor             %ebx, %ebx
                    109:        /* mmap start after first size */
                    110:        movl            $4, %edi
                    111: 
                    112: mmap_loop:
                    113:        /* entry size (mmap struct) & max buffer size (int15) */
                    114:        movl            $20, %ecx
                    115:        /* store entry size */
                    116:        movl            %ecx, %es:-4(%edi)
                    117:        /* e820 */
                    118:        movl            $0x0000e820, %eax
                    119:        /* 'SMAP' magic */
                    120:        movl            $0x534d4150, %edx
                    121:        int             $0x15
                    122: 
                    123: mmap_check_entry:
                    124:        /* last entry? then we're done */
                    125:        jb              mmap_done
                    126:        and             %bx, %bx
                    127:        jz              mmap_done
                    128:        /* valid entry, so let's loop on */
                    129: 
                    130: mmap_store_entry:
                    131:        /* %ax = entry_number * 24 */
                    132:        mov             $24, %ax
                    133:        mul             %bx
                    134:        mov             %ax, %di
                    135:        movw            %di, %fs:0x2c
                    136:        /* %di = 4 + (entry_number * 24) */
                    137:        add             $4, %di
                    138:        jmp             mmap_loop
                    139: 
                    140: mmap_done:
                    141: real_to_prot:
                    142:        /* Load the GDT before going into protected mode */
                    143: lgdt:
                    144:        data32 lgdt     %cs:gdt_desc
                    145: 
                    146:        /* get us to protected mode now */
                    147:        movl            $1, %eax
                    148:        movl            %eax, %cr0
                    149: 
                    150:        /* the LJMP sets CS for us and gets us to 32-bit */
                    151: ljmp:
                    152:        data32 ljmp     *%cs:prot_jump
                    153: 
                    154: prot_mode:
                    155: .code32
                    156: 
                    157:        /* initialize all other segments */
                    158:        movl            $0x10, %eax
                    159:        movl            %eax, %ss
                    160:        movl            %eax, %ds
                    161:        movl            %eax, %es
                    162:        movl            %eax, %fs
                    163:        movl            %eax, %gs
                    164: 
                    165:        /* Jump off to the kernel */
                    166:        read_fw         FW_CFG_KERNEL_ADDR
                    167:        mov             %eax, %ecx
                    168: 
                    169:        /* EBX contains a pointer to the bootinfo struct */
                    170:        read_fw         FW_CFG_INITRD_ADDR
                    171:        movl            %eax, %ebx
                    172: 
                    173:        /* EAX has to contain the magic */
                    174:        movl            $MULTIBOOT_MAGIC, %eax
                    175: ljmp2:
                    176:        jmp             *%ecx
                    177: 
                    178: /* Variables */
                    179: .align 4, 0
                    180: old_int19:     .long 0
                    181: 
                    182: prot_jump:     .long prot_mode
                    183:                .short 8
                    184: 
                    185: .align 4, 0
                    186: gdt:
                    187:        /* 0x00 */
                    188: .byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
                    189: 
                    190:        /* 0x08: code segment (base=0, limit=0xfffff, type=32bit code exec/read, DPL=0, 4k) */
                    191: .byte  0xff, 0xff, 0x00, 0x00, 0x00, 0x9a, 0xcf, 0x00
                    192: 
                    193:        /* 0x10: data segment (base=0, limit=0xfffff, type=32bit data read/write, DPL=0, 4k) */
                    194: .byte  0xff, 0xff, 0x00, 0x00, 0x00, 0x92, 0xcf, 0x00
                    195: 
                    196:        /* 0x18: code segment (base=0, limit=0x0ffff, type=16bit code exec/read/conf, DPL=0, 1b) */
                    197: .byte  0xff, 0xff, 0x00, 0x00, 0x00, 0x9e, 0x00, 0x00
                    198: 
                    199:        /* 0x20: data segment (base=0, limit=0x0ffff, type=16bit data read/write, DPL=0, 1b) */
                    200: .byte  0xff, 0xff, 0x00, 0x00, 0x00, 0x92, 0x00, 0x00
                    201: 
                    202: gdt_desc:
                    203: .short (5 * 8) - 1
                    204: .long  gdt
                    205: 
                    206: .align 512, 0
                    207: _end:
                    208: 

unix.superglobalmegacorp.com

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