|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.