Annotation of qemu/pc-bios/optionrom/multiboot.S, revision 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.