|
|
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:
1.1.1.2 ! root 21: #include "optionrom.h"
1.1 root 22:
23: #define MULTIBOOT_MAGIC 0x2badb002
24:
1.1.1.2 ! root 25: #define GS_PROT_JUMP 0
! 26: #define GS_GDT_DESC 6
! 27:
1.1 root 28:
1.1.1.2 ! root 29: BOOT_ROM_START
1.1 root 30:
31: run_multiboot:
32:
33: cli
34: cld
35:
36: mov %cs, %eax
37: shl $0x4, %eax
38:
1.1.1.2 ! root 39: /* set up a long jump descriptor that is PC relative */
1.1 root 40:
1.1.1.2 ! root 41: /* move stack memory to %gs */
! 42: mov %ss, %ecx
! 43: shl $0x4, %ecx
! 44: mov %esp, %ebx
! 45: add %ebx, %ecx
! 46: sub $0x20, %ecx
! 47: sub $0x30, %esp
! 48: shr $0x4, %ecx
! 49: mov %cx, %gs
! 50:
! 51: /* now push the indirect jump decriptor there */
1.1 root 52: mov (prot_jump), %ebx
53: add %eax, %ebx
1.1.1.2 ! root 54: movl %ebx, %gs:GS_PROT_JUMP
! 55: mov $8, %bx
! 56: movw %bx, %gs:GS_PROT_JUMP + 4
! 57:
! 58: /* fix the gdt descriptor to be PC relative */
! 59: movw (gdt_desc), %bx
! 60: movw %bx, %gs:GS_GDT_DESC
! 61: movl (gdt_desc+2), %ebx
! 62: add %eax, %ebx
! 63: movl %ebx, %gs:GS_GDT_DESC + 2
! 64:
! 65: xor %eax, %eax
! 66: mov %eax, %es
! 67:
! 68: /* Read the bootinfo struct into RAM */
! 69: read_fw_blob(FW_CFG_INITRD)
1.1 root 70:
71: /* FS = bootinfo_struct */
72: read_fw FW_CFG_INITRD_ADDR
73: shr $4, %eax
74: mov %ax, %fs
75:
76: /* ES = mmap_addr */
1.1.1.2 ! root 77: mov %fs:48, %eax
1.1 root 78: shr $4, %eax
79: mov %ax, %es
80:
81: /* Initialize multiboot mmap structs using int 0x15(e820) */
82: xor %ebx, %ebx
83: /* mmap start after first size */
84: movl $4, %edi
85:
86: mmap_loop:
87: /* entry size (mmap struct) & max buffer size (int15) */
88: movl $20, %ecx
89: /* store entry size */
1.1.1.2 ! root 90: /* old as(1) doesn't like this insn so emit the bytes instead:
1.1 root 91: movl %ecx, %es:-4(%edi)
1.1.1.2 ! root 92: */
! 93: .dc.b 0x26,0x67,0x66,0x89,0x4f,0xfc
1.1 root 94: /* e820 */
95: movl $0x0000e820, %eax
96: /* 'SMAP' magic */
97: movl $0x534d4150, %edx
98: int $0x15
99:
100: mmap_check_entry:
101: /* last entry? then we're done */
102: jb mmap_done
103: and %bx, %bx
104: jz mmap_done
105: /* valid entry, so let's loop on */
106:
107: mmap_store_entry:
108: /* %ax = entry_number * 24 */
109: mov $24, %ax
110: mul %bx
111: mov %ax, %di
112: movw %di, %fs:0x2c
113: /* %di = 4 + (entry_number * 24) */
114: add $4, %di
115: jmp mmap_loop
116:
117: mmap_done:
118: real_to_prot:
119: /* Load the GDT before going into protected mode */
120: lgdt:
1.1.1.2 ! root 121: data32 lgdt %gs:GS_GDT_DESC
1.1 root 122:
123: /* get us to protected mode now */
124: movl $1, %eax
125: movl %eax, %cr0
126:
127: /* the LJMP sets CS for us and gets us to 32-bit */
128: ljmp:
1.1.1.2 ! root 129: data32 ljmp *%gs:GS_PROT_JUMP
1.1 root 130:
131: prot_mode:
132: .code32
133:
134: /* initialize all other segments */
135: movl $0x10, %eax
136: movl %eax, %ss
137: movl %eax, %ds
138: movl %eax, %es
139: movl %eax, %fs
140: movl %eax, %gs
141:
1.1.1.2 ! root 142: /* Read the kernel and modules into RAM */
! 143: read_fw_blob(FW_CFG_KERNEL)
! 144:
1.1 root 145: /* Jump off to the kernel */
1.1.1.2 ! root 146: read_fw FW_CFG_KERNEL_ENTRY
1.1 root 147: mov %eax, %ecx
148:
149: /* EBX contains a pointer to the bootinfo struct */
150: read_fw FW_CFG_INITRD_ADDR
151: movl %eax, %ebx
152:
153: /* EAX has to contain the magic */
154: movl $MULTIBOOT_MAGIC, %eax
155: ljmp2:
156: jmp *%ecx
157:
158: /* Variables */
159: .align 4, 0
160: prot_jump: .long prot_mode
161: .short 8
162:
163: .align 4, 0
164: gdt:
165: /* 0x00 */
166: .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
167:
168: /* 0x08: code segment (base=0, limit=0xfffff, type=32bit code exec/read, DPL=0, 4k) */
169: .byte 0xff, 0xff, 0x00, 0x00, 0x00, 0x9a, 0xcf, 0x00
170:
171: /* 0x10: data segment (base=0, limit=0xfffff, type=32bit data read/write, DPL=0, 4k) */
172: .byte 0xff, 0xff, 0x00, 0x00, 0x00, 0x92, 0xcf, 0x00
173:
174: /* 0x18: code segment (base=0, limit=0x0ffff, type=16bit code exec/read/conf, DPL=0, 1b) */
175: .byte 0xff, 0xff, 0x00, 0x00, 0x00, 0x9e, 0x00, 0x00
176:
177: /* 0x20: data segment (base=0, limit=0x0ffff, type=16bit data read/write, DPL=0, 1b) */
178: .byte 0xff, 0xff, 0x00, 0x00, 0x00, 0x92, 0x00, 0x00
179:
180: gdt_desc:
181: .short (5 * 8) - 1
182: .long gdt
183:
1.1.1.2 ! root 184: BOOT_ROM_END
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.