root / pc-bios / optionrom / multiboot.S @ 076d2471
History | View | Annotate | Download (4 kB)
1 | f16408df | Alexander Graf | /* |
---|---|---|---|
2 | f16408df | Alexander Graf | * Multiboot Option ROM |
3 | f16408df | Alexander Graf | * |
4 | f16408df | Alexander Graf | * This program is free software; you can redistribute it and/or modify |
5 | f16408df | Alexander Graf | * it under the terms of the GNU General Public License as published by |
6 | f16408df | Alexander Graf | * the Free Software Foundation; either version 2 of the License, or |
7 | f16408df | Alexander Graf | * (at your option) any later version. |
8 | f16408df | Alexander Graf | * |
9 | f16408df | Alexander Graf | * This program is distributed in the hope that it will be useful, |
10 | f16408df | Alexander Graf | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | f16408df | Alexander Graf | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | f16408df | Alexander Graf | * GNU General Public License for more details. |
13 | f16408df | Alexander Graf | * |
14 | f16408df | Alexander Graf | * You should have received a copy of the GNU General Public License |
15 | 8167ee88 | Blue Swirl | * along with this program; if not, see <http://www.gnu.org/licenses/>. |
16 | f16408df | Alexander Graf | * |
17 | f16408df | Alexander Graf | * Copyright Novell Inc, 2009 |
18 | f16408df | Alexander Graf | * Authors: Alexander Graf <agraf@suse.de> |
19 | f16408df | Alexander Graf | */ |
20 | f16408df | Alexander Graf | |
21 | dd4b2659 | Alexander Graf | #include "optionrom.h" |
22 | f16408df | Alexander Graf | |
23 | f16408df | Alexander Graf | #define MULTIBOOT_MAGIC 0x2badb002 |
24 | f16408df | Alexander Graf | |
25 | 77873196 | Alexander Graf | #define GS_PROT_JUMP 0 |
26 | 77873196 | Alexander Graf | #define GS_GDT_DESC 6 |
27 | 77873196 | Alexander Graf | |
28 | f16408df | Alexander Graf | |
29 | dd4b2659 | Alexander Graf | BOOT_ROM_START |
30 | f16408df | Alexander Graf | |
31 | f16408df | Alexander Graf | run_multiboot: |
32 | f16408df | Alexander Graf | |
33 | f16408df | Alexander Graf | cli |
34 | f16408df | Alexander Graf | cld |
35 | f16408df | Alexander Graf | |
36 | f16408df | Alexander Graf | mov %cs, %eax |
37 | f16408df | Alexander Graf | shl $0x4, %eax |
38 | f16408df | Alexander Graf | |
39 | 77873196 | Alexander Graf | /* set up a long jump descriptor that is PC relative */ |
40 | f16408df | Alexander Graf | |
41 | 77873196 | Alexander Graf | /* move stack memory to %gs */ |
42 | 77873196 | Alexander Graf | mov %ss, %ecx |
43 | 77873196 | Alexander Graf | shl $0x4, %ecx |
44 | 77873196 | Alexander Graf | mov %esp, %ebx |
45 | 77873196 | Alexander Graf | add %ebx, %ecx |
46 | 77873196 | Alexander Graf | sub $0x20, %ecx |
47 | 77873196 | Alexander Graf | sub $0x30, %esp |
48 | 77873196 | Alexander Graf | shr $0x4, %ecx |
49 | 77873196 | Alexander Graf | mov %cx, %gs |
50 | 77873196 | Alexander Graf | |
51 | 77873196 | Alexander Graf | /* now push the indirect jump decriptor there */ |
52 | f16408df | Alexander Graf | mov (prot_jump), %ebx |
53 | f16408df | Alexander Graf | add %eax, %ebx |
54 | 77873196 | Alexander Graf | movl %ebx, %gs:GS_PROT_JUMP |
55 | 77873196 | Alexander Graf | mov $8, %bx |
56 | 77873196 | Alexander Graf | movw %bx, %gs:GS_PROT_JUMP + 4 |
57 | 77873196 | Alexander Graf | |
58 | 77873196 | Alexander Graf | /* fix the gdt descriptor to be PC relative */ |
59 | 77873196 | Alexander Graf | movw (gdt_desc), %bx |
60 | 77873196 | Alexander Graf | movw %bx, %gs:GS_GDT_DESC |
61 | 77873196 | Alexander Graf | movl (gdt_desc+2), %ebx |
62 | 77873196 | Alexander Graf | add %eax, %ebx |
63 | 77873196 | Alexander Graf | movl %ebx, %gs:GS_GDT_DESC + 2 |
64 | 77873196 | Alexander Graf | |
65 | 53ea95de | Adam Lackorzynski | xor %eax, %eax |
66 | 53ea95de | Adam Lackorzynski | mov %eax, %es |
67 | 53ea95de | Adam Lackorzynski | |
68 | 77873196 | Alexander Graf | /* Read the bootinfo struct into RAM */ |
69 | 77873196 | Alexander Graf | read_fw_blob(FW_CFG_INITRD) |
70 | f16408df | Alexander Graf | |
71 | f16408df | Alexander Graf | /* FS = bootinfo_struct */ |
72 | f16408df | Alexander Graf | read_fw FW_CFG_INITRD_ADDR |
73 | f16408df | Alexander Graf | shr $4, %eax |
74 | f16408df | Alexander Graf | mov %ax, %fs |
75 | f16408df | Alexander Graf | |
76 | f16408df | Alexander Graf | /* ES = mmap_addr */ |
77 | 53ea95de | Adam Lackorzynski | mov %fs:48, %eax |
78 | f16408df | Alexander Graf | shr $4, %eax |
79 | f16408df | Alexander Graf | mov %ax, %es |
80 | f16408df | Alexander Graf | |
81 | f16408df | Alexander Graf | /* Initialize multiboot mmap structs using int 0x15(e820) */ |
82 | f16408df | Alexander Graf | xor %ebx, %ebx |
83 | f16408df | Alexander Graf | /* mmap start after first size */ |
84 | f16408df | Alexander Graf | movl $4, %edi |
85 | f16408df | Alexander Graf | |
86 | f16408df | Alexander Graf | mmap_loop: |
87 | f16408df | Alexander Graf | /* entry size (mmap struct) & max buffer size (int15) */ |
88 | f16408df | Alexander Graf | movl $20, %ecx |
89 | f16408df | Alexander Graf | /* store entry size */ |
90 | ff56954b | Juergen Lock | /* old as(1) doesn't like this insn so emit the bytes instead: |
91 | f16408df | Alexander Graf | movl %ecx, %es:-4(%edi) |
92 | ff56954b | Juergen Lock | */ |
93 | ff56954b | Juergen Lock | .dc.b 0x26,0x67,0x66,0x89,0x4f,0xfc |
94 | f16408df | Alexander Graf | /* e820 */ |
95 | f16408df | Alexander Graf | movl $0x0000e820, %eax |
96 | f16408df | Alexander Graf | /* 'SMAP' magic */ |
97 | f16408df | Alexander Graf | movl $0x534d4150, %edx |
98 | f16408df | Alexander Graf | int $0x15 |
99 | f16408df | Alexander Graf | |
100 | f16408df | Alexander Graf | mmap_check_entry: |
101 | f16408df | Alexander Graf | /* last entry? then we're done */ |
102 | f16408df | Alexander Graf | jb mmap_done |
103 | f16408df | Alexander Graf | and %bx, %bx |
104 | f16408df | Alexander Graf | jz mmap_done |
105 | f16408df | Alexander Graf | /* valid entry, so let's loop on */ |
106 | f16408df | Alexander Graf | |
107 | f16408df | Alexander Graf | mmap_store_entry: |
108 | f16408df | Alexander Graf | /* %ax = entry_number * 24 */ |
109 | f16408df | Alexander Graf | mov $24, %ax |
110 | f16408df | Alexander Graf | mul %bx |
111 | f16408df | Alexander Graf | mov %ax, %di |
112 | f16408df | Alexander Graf | movw %di, %fs:0x2c |
113 | f16408df | Alexander Graf | /* %di = 4 + (entry_number * 24) */ |
114 | f16408df | Alexander Graf | add $4, %di |
115 | f16408df | Alexander Graf | jmp mmap_loop |
116 | f16408df | Alexander Graf | |
117 | f16408df | Alexander Graf | mmap_done: |
118 | f16408df | Alexander Graf | real_to_prot: |
119 | f16408df | Alexander Graf | /* Load the GDT before going into protected mode */ |
120 | f16408df | Alexander Graf | lgdt: |
121 | 77873196 | Alexander Graf | data32 lgdt %gs:GS_GDT_DESC |
122 | f16408df | Alexander Graf | |
123 | f16408df | Alexander Graf | /* get us to protected mode now */ |
124 | f16408df | Alexander Graf | movl $1, %eax |
125 | f16408df | Alexander Graf | movl %eax, %cr0 |
126 | f16408df | Alexander Graf | |
127 | f16408df | Alexander Graf | /* the LJMP sets CS for us and gets us to 32-bit */ |
128 | f16408df | Alexander Graf | ljmp: |
129 | 77873196 | Alexander Graf | data32 ljmp *%gs:GS_PROT_JUMP |
130 | f16408df | Alexander Graf | |
131 | f16408df | Alexander Graf | prot_mode: |
132 | f16408df | Alexander Graf | .code32 |
133 | f16408df | Alexander Graf | |
134 | f16408df | Alexander Graf | /* initialize all other segments */ |
135 | f16408df | Alexander Graf | movl $0x10, %eax |
136 | f16408df | Alexander Graf | movl %eax, %ss |
137 | f16408df | Alexander Graf | movl %eax, %ds |
138 | f16408df | Alexander Graf | movl %eax, %es |
139 | f16408df | Alexander Graf | movl %eax, %fs |
140 | f16408df | Alexander Graf | movl %eax, %gs |
141 | f16408df | Alexander Graf | |
142 | 77873196 | Alexander Graf | /* Read the kernel and modules into RAM */ |
143 | 77873196 | Alexander Graf | read_fw_blob(FW_CFG_KERNEL) |
144 | 77873196 | Alexander Graf | |
145 | f16408df | Alexander Graf | /* Jump off to the kernel */ |
146 | 77873196 | Alexander Graf | read_fw FW_CFG_KERNEL_ENTRY |
147 | f16408df | Alexander Graf | mov %eax, %ecx |
148 | f16408df | Alexander Graf | |
149 | f16408df | Alexander Graf | /* EBX contains a pointer to the bootinfo struct */ |
150 | f16408df | Alexander Graf | read_fw FW_CFG_INITRD_ADDR |
151 | f16408df | Alexander Graf | movl %eax, %ebx |
152 | f16408df | Alexander Graf | |
153 | f16408df | Alexander Graf | /* EAX has to contain the magic */ |
154 | f16408df | Alexander Graf | movl $MULTIBOOT_MAGIC, %eax |
155 | f16408df | Alexander Graf | ljmp2: |
156 | f16408df | Alexander Graf | jmp *%ecx |
157 | f16408df | Alexander Graf | |
158 | f16408df | Alexander Graf | /* Variables */ |
159 | f16408df | Alexander Graf | .align 4, 0 |
160 | f16408df | Alexander Graf | prot_jump: .long prot_mode |
161 | f16408df | Alexander Graf | .short 8 |
162 | f16408df | Alexander Graf | |
163 | f16408df | Alexander Graf | .align 4, 0 |
164 | f16408df | Alexander Graf | gdt: |
165 | f16408df | Alexander Graf | /* 0x00 */ |
166 | f16408df | Alexander Graf | .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 |
167 | f16408df | Alexander Graf | |
168 | f16408df | Alexander Graf | /* 0x08: code segment (base=0, limit=0xfffff, type=32bit code exec/read, DPL=0, 4k) */ |
169 | f16408df | Alexander Graf | .byte 0xff, 0xff, 0x00, 0x00, 0x00, 0x9a, 0xcf, 0x00 |
170 | f16408df | Alexander Graf | |
171 | f16408df | Alexander Graf | /* 0x10: data segment (base=0, limit=0xfffff, type=32bit data read/write, DPL=0, 4k) */ |
172 | f16408df | Alexander Graf | .byte 0xff, 0xff, 0x00, 0x00, 0x00, 0x92, 0xcf, 0x00 |
173 | f16408df | Alexander Graf | |
174 | f16408df | Alexander Graf | /* 0x18: code segment (base=0, limit=0x0ffff, type=16bit code exec/read/conf, DPL=0, 1b) */ |
175 | f16408df | Alexander Graf | .byte 0xff, 0xff, 0x00, 0x00, 0x00, 0x9e, 0x00, 0x00 |
176 | f16408df | Alexander Graf | |
177 | f16408df | Alexander Graf | /* 0x20: data segment (base=0, limit=0x0ffff, type=16bit data read/write, DPL=0, 1b) */ |
178 | f16408df | Alexander Graf | .byte 0xff, 0xff, 0x00, 0x00, 0x00, 0x92, 0x00, 0x00 |
179 | f16408df | Alexander Graf | |
180 | f16408df | Alexander Graf | gdt_desc: |
181 | f16408df | Alexander Graf | .short (5 * 8) - 1 |
182 | f16408df | Alexander Graf | .long gdt |
183 | f16408df | Alexander Graf | |
184 | dd4b2659 | Alexander Graf | BOOT_ROM_END |