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

1.1       root        1: /*
                      2:  * Linux Boot 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:  * Based on code in hw/pc.c.
                     21:  */
                     22: 
                     23: #include "optionrom.h"
                     24: 
                     25: BOOT_ROM_START
                     26: 
                     27: run_linuxboot:
                     28: 
                     29:        cli
                     30:        cld
                     31: 
                     32:        jmp             copy_kernel
                     33: boot_kernel:
                     34: 
                     35:        read_fw         FW_CFG_SETUP_ADDR
                     36: 
                     37:        mov             %eax, %ebx
                     38:        shr             $4, %ebx
                     39: 
                     40:        /* All segments contain real_addr */
                     41:        mov             %bx, %ds
                     42:        mov             %bx, %es
                     43:        mov             %bx, %fs
                     44:        mov             %bx, %gs
                     45:        mov             %bx, %ss
                     46: 
                     47:        /* CX = CS we want to jump to */
                     48:        add             $0x20, %bx
                     49:        mov             %bx, %cx
                     50: 
                     51:        /* SP = cmdline_addr-real_addr-16 */
                     52:        read_fw         FW_CFG_CMDLINE_ADDR
                     53:        mov             %eax, %ebx
                     54:        read_fw         FW_CFG_SETUP_ADDR
                     55:        sub             %eax, %ebx
                     56:        sub             $16, %ebx
                     57:        mov             %ebx, %esp
                     58: 
                     59:        /* Build indirect lret descriptor */
                     60:        pushw           %cx             /* CS */
                     61:        xor             %ax, %ax
                     62:        pushw           %ax             /* IP = 0 */
                     63: 
                     64:        /* Clear registers */
                     65:        xor             %eax, %eax
                     66:        xor             %ebx, %ebx
                     67:        xor             %ecx, %ecx
                     68:        xor             %edx, %edx
                     69:        xor             %edi, %edi
                     70:        xor             %ebp, %ebp
                     71: 
                     72:        /* Jump to Linux */
                     73:        lret
                     74: 
                     75: 
                     76: copy_kernel:
                     77: 
                     78:        /* We need to load the kernel into memory we can't access in 16 bit
                     79:           mode, so let's get into 32 bit mode, write the kernel and jump
                     80:           back again. */
                     81: 
                     82:        /* Reserve space on the stack for our GDT descriptor. */
                     83:        mov             %esp, %ebp
                     84:        sub             $16, %esp
                     85: 
                     86:        /* Now create the GDT descriptor */
                     87:        movw            $((3 * 8) - 1), -16(%bp)
                     88:        mov             %cs, %eax
1.1.1.2   root       89:        movzwl          %ax, %eax
1.1       root       90:        shl             $4, %eax
1.1.1.2   root       91:        addl            $gdt, %eax
                     92:        movl            %eax, -14(%bp)
1.1       root       93: 
                     94:        /* And load the GDT */
                     95:        data32 lgdt     -16(%bp)
                     96:        mov             %ebp, %esp
                     97: 
                     98:        /* Get us to protected mode now */
                     99:        mov             $1, %eax
                    100:        mov             %eax, %cr0
                    101: 
                    102:        /* So we can set ES to a 32-bit segment */
                    103:        mov             $0x10, %eax
                    104:        mov             %eax, %es
                    105: 
                    106:        /* We're now running in 16-bit CS, but 32-bit ES! */
                    107: 
                    108:        /* Load kernel and initrd */
1.1.1.3 ! root      109:        read_fw_blob_addr32(FW_CFG_KERNEL)
        !           110:        read_fw_blob_addr32(FW_CFG_INITRD)
        !           111:        read_fw_blob_addr32(FW_CFG_CMDLINE)
        !           112:        read_fw_blob_addr32(FW_CFG_SETUP)
1.1       root      113: 
                    114:        /* And now jump into Linux! */
                    115:        mov             $0, %eax
                    116:        mov             %eax, %cr0
                    117: 
                    118:        /* ES = CS */
                    119:        mov             %cs, %ax
                    120:        mov             %ax, %es
                    121: 
                    122:        jmp             boot_kernel
                    123: 
                    124: /* Variables */
                    125: 
                    126: .align 4, 0
                    127: gdt:
                    128:        /* 0x00 */
                    129: .byte  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
                    130: 
                    131:        /* 0x08: code segment (base=0, limit=0xfffff, type=32bit code exec/read, DPL=0, 4k) */
                    132: .byte  0xff, 0xff, 0x00, 0x00, 0x00, 0x9a, 0xcf, 0x00
                    133: 
                    134:        /* 0x10: data segment (base=0, limit=0xfffff, type=32bit data read/write, DPL=0, 4k) */
                    135: .byte  0xff, 0xff, 0x00, 0x00, 0x00, 0x92, 0xcf, 0x00
                    136: 
                    137: 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.