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