|
|
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 ! 89: shl $4, %eax ! 90: addl $gdt, %ebx ! 91: movl %ebx, -14(%bp) ! 92: ! 93: /* And load the GDT */ ! 94: data32 lgdt -16(%bp) ! 95: mov %ebp, %esp ! 96: ! 97: /* Get us to protected mode now */ ! 98: mov $1, %eax ! 99: mov %eax, %cr0 ! 100: ! 101: /* So we can set ES to a 32-bit segment */ ! 102: mov $0x10, %eax ! 103: mov %eax, %es ! 104: ! 105: /* We're now running in 16-bit CS, but 32-bit ES! */ ! 106: ! 107: /* Load kernel and initrd */ ! 108: read_fw_blob(FW_CFG_KERNEL) ! 109: read_fw_blob(FW_CFG_INITRD) ! 110: read_fw_blob(FW_CFG_CMDLINE) ! 111: read_fw_blob(FW_CFG_SETUP) ! 112: ! 113: /* And now jump into Linux! */ ! 114: mov $0, %eax ! 115: mov %eax, %cr0 ! 116: ! 117: /* ES = CS */ ! 118: mov %cs, %ax ! 119: mov %ax, %es ! 120: ! 121: jmp boot_kernel ! 122: ! 123: /* Variables */ ! 124: ! 125: .align 4, 0 ! 126: gdt: ! 127: /* 0x00 */ ! 128: .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ! 129: ! 130: /* 0x08: code segment (base=0, limit=0xfffff, type=32bit code exec/read, DPL=0, 4k) */ ! 131: .byte 0xff, 0xff, 0x00, 0x00, 0x00, 0x9a, 0xcf, 0x00 ! 132: ! 133: /* 0x10: data segment (base=0, limit=0xfffff, type=32bit data read/write, DPL=0, 4k) */ ! 134: .byte 0xff, 0xff, 0x00, 0x00, 0x00, 0x92, 0xcf, 0x00 ! 135: ! 136: BOOT_ROM_END
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.