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

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