source: mainline/kernel/arch/ia32/src/boot/boot.S@ 20f1597

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 20f1597 was bf25efb, checked in by Jiri Svoboda <jirik.svoboda@…>, 17 years ago

Rewrite rest of multiboot info parsing to C.

  • Property mode set to 100644
File size: 8.9 KB
Line 
1#
2# Copyright (c) 2001-2004 Jakub Jermar
3# Copyright (c) 2005-2006 Martin Decky
4# All rights reserved.
5#
6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions
8# are met:
9#
10# - Redistributions of source code must retain the above copyright
11# notice, this list of conditions and the following disclaimer.
12# - Redistributions in binary form must reproduce the above copyright
13# notice, this list of conditions and the following disclaimer in the
14# documentation and/or other materials provided with the distribution.
15# - The name of the author may not be used to endorse or promote products
16# derived from this software without specific prior written permission.
17#
18# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28#
29
30#include <arch/boot/boot.h>
31#include <arch/boot/memmap.h>
32#include <arch/mm/page.h>
33#include <arch/pm.h>
34
35#define START_STACK (BOOT_OFFSET - BOOT_STACK_SIZE)
36
37.section K_TEXT_START, "ax"
38
39.code32
40.align 4
41.global multiboot_image_start
42multiboot_header:
43 .long MULTIBOOT_HEADER_MAGIC
44 .long MULTIBOOT_HEADER_FLAGS
45 .long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS) # checksum
46 .long multiboot_header
47 .long unmapped_ktext_start
48 .long 0
49 .long 0
50 .long multiboot_image_start
51
52multiboot_image_start:
53 cld
54 movl $START_STACK, %esp # initialize stack pointer
55 lgdt KA2PA(bootstrap_gdtr) # initialize Global Descriptor Table register
56
57 movw $selector(KDATA_DES), %cx
58 movw %cx, %es
59 movw %cx, %fs
60 movw %cx, %gs
61 movw %cx, %ds # kernel data + stack
62 movw %cx, %ss
63
64 jmpl $selector(KTEXT_DES), $multiboot_meeting_point
65 multiboot_meeting_point:
66
67 movl %eax, grub_eax # save parameters from GRUB
68 movl %ebx, grub_ebx
69
70 xorl %eax, %eax
71 cpuid
72 cmp $0x0, %eax # any function > 0?
73 jbe pse_unsupported
74 movl $0x1, %eax # Basic function code 1
75 cpuid
76 bt $3, %edx # Test if PSE is supported
77 jc pse_supported
78
79 pse_unsupported:
80 movl $pse_msg, %esi
81 jmp error_halt
82
83 pse_supported:
84
85#ifdef CONFIG_FB
86 mov $vesa_init, %esi
87 mov $VESA_INIT_SEGMENT << 4, %edi
88 mov $e_vesa_init - vesa_init, %ecx
89 rep movsb
90
91 mov $VESA_INIT_SEGMENT << 4, %edi
92 jmpl *%edi
93
94 vesa_meeting_point:
95
96 mov %esi, KA2PA(vesa_ph_addr)
97 mov %di, KA2PA(vesa_height)
98 shr $16, %edi
99 mov %di, KA2PA(vesa_width)
100 mov %bx, KA2PA(vesa_scanline)
101 shr $16, %ebx
102 mov %bx, KA2PA(vesa_bpp)
103#endif
104
105 call map_kernel # map kernel and turn paging on
106
107 # ia32_cboot(grub_eax, grub_ebx)
108 pushl grub_ebx
109 pushl grub_eax
110 call ia32_cboot # Does not return.
111
112 # Not reached.
113
114 cli
115 hlt
116
117.global map_kernel
118map_kernel:
119 #
120 # Here we setup mapping for both the unmapped and mapped sections of the kernel.
121 # For simplicity, we map the entire 4G space.
122 #
123 movl %cr4, %ecx
124 orl $(1 << 4), %ecx # turn PSE on
125 andl $(~(1 << 5)), %ecx # turn PAE off
126 movl %ecx, %cr4
127
128 movl $(page_directory + 0), %esi
129 movl $(page_directory + 2048), %edi
130 xorl %ecx, %ecx
131 xorl %ebx, %ebx
1320:
133 movl $((1 << 7) | (1 << 1) | (1 << 0)), %eax
134 orl %ebx, %eax
135 movl %eax, (%esi, %ecx, 4) # mapping 0x00000000 + %ecx * 4M => 0x00000000 + %ecx * 4M
136 movl %eax, (%edi, %ecx, 4) # mapping 0x80000000 + %ecx * 4M => 0x00000000 + %ecx * 4M
137 addl $(4 * 1024 * 1024), %ebx
138
139 incl %ecx
140 cmpl $512, %ecx
141 jl 0b
142
143 movl %esi, %cr3
144
145 movl %cr0, %ebx
146 orl $(1 << 31), %ebx # turn paging on
147 movl %ebx, %cr0
148 ret
149
150# Print string from %esi to EGA display (in red) and halt
151error_halt:
152 movl $0xb8000, %edi # base of EGA text mode memory
153 xorl %eax, %eax
154
155 movw $0x3d4, %dx # read bits 8 - 15 of the cursor address
156 movb $0xe, %al
157 outb %al, %dx
158
159 movw $0x3d5, %dx
160 inb %dx, %al
161 shl $8, %ax
162
163 movw $0x3d4, %dx # read bits 0 - 7 of the cursor address
164 movb $0xf, %al
165 outb %al, %dx
166
167 movw $0x3d5, %dx
168 inb %dx, %al
169
170 cmp $1920, %ax
171 jbe cursor_ok
172 movw $1920, %ax # sanity check for the cursor on the last line
173 cursor_ok:
174
175 movw %ax, %bx
176 shl $1, %eax
177 addl %eax, %edi
178
179 movw $0x0c00, %ax # black background, light red foreground
180
181 ploop:
182 lodsb
183 cmp $0, %al
184 je ploop_end
185 stosw
186 inc %bx
187 jmp ploop
188 ploop_end:
189
190 movw $0x3d4, %dx # write bits 8 - 15 of the cursor address
191 movb $0xe, %al
192 outb %al, %dx
193
194 movw $0x3d5, %dx
195 movb %bh, %al
196 outb %al, %dx
197
198 movw $0x3d4, %dx # write bits 0 - 7 of the cursor address
199 movb $0xf, %al
200 outb %al, %dx
201
202 movw $0x3d5, %dx
203 movb %bl, %al
204 outb %al, %dx
205
206 cli
207 hlt
208
209#ifdef CONFIG_FB
210vesa_init:
211 jmp $selector(VESA_INIT_DES), $vesa_init_real - vesa_init
212
213.code16
214vesa_init_real:
215
216 mov %cr0, %eax
217 and $~1, %eax
218 mov %eax, %cr0
219
220 jmp $VESA_INIT_SEGMENT, $vesa_init_real2 - vesa_init
221
222vesa_init_real2:
223
224 mov $VESA_INIT_SEGMENT, %bx
225
226 mov %bx, %es
227 mov %bx, %fs
228 mov %bx, %gs
229 mov %bx, %ds
230 mov %bx, %ss
231
232 movl %esp, %eax
233 movl $0x0000fffc, %esp
234 movl $0x0000fffc, %ebp
235 pushl %eax
236
237#define VESA_INFO_SIZE 1024
238
239#define VESA_MODE_ATTRIBUTES_OFFSET 0
240#define VESA_MODE_LIST_PTR_OFFSET 14
241#define VESA_MODE_SCANLINE_OFFSET 16
242#define VESA_MODE_WIDTH_OFFSET 18
243#define VESA_MODE_HEIGHT_OFFSET 20
244#define VESA_MODE_BPP_OFFSET 25
245#define VESA_MODE_PHADDR_OFFSET 40
246
247#define VESA_END_OF_MODES 0xffff
248
249#define VESA_OK 0x4f
250
251#define VESA_GET_INFO 0x4f00
252#define VESA_GET_MODE_INFO 0x4f01
253#define VESA_SET_MODE 0x4f02
254#define VESA_SET_PALETTE 0x4f09
255
256#if CONFIG_VESA_BPP == 24
257#define CONFIG_VESA_BPP_VARIANT 32
258#endif
259
260 mov $VESA_GET_INFO, %ax
261 mov $e_vesa_init - vesa_init, %di
262 push %di
263 int $0x10
264
265 pop %di
266 cmp $VESA_OK, %al
267 jnz 0f
268
269 mov 2 + VESA_MODE_LIST_PTR_OFFSET(%di), %si
270 mov %si, %gs
271 mov VESA_MODE_LIST_PTR_OFFSET(%di), %si
272
273 add $VESA_INFO_SIZE, %di
274
2751:# Try next mode
276 mov %gs:(%si), %cx
277 cmp $VESA_END_OF_MODES, %cx
278 jz 0f
279
280 inc %si
281 inc %si
282 push %cx
283 push %di
284 push %si
285 mov $VESA_GET_MODE_INFO, %ax
286 int $0x10
287
288 pop %si
289 pop %di
290 pop %cx
291 cmp $VESA_OK, %al
292 jnz 0f
293
294 mov $CONFIG_VESA_WIDTH, %ax
295 cmp VESA_MODE_WIDTH_OFFSET(%di), %ax
296 jnz 1b
297
298 mov $CONFIG_VESA_HEIGHT, %ax
299 cmp VESA_MODE_HEIGHT_OFFSET(%di), %ax
300 jnz 1b
301
302 mov $CONFIG_VESA_BPP, %al
303 cmp VESA_MODE_BPP_OFFSET(%di), %al
304
305#ifdef CONFIG_VESA_BPP_VARIANT
306 jz 2f
307
308 mov $CONFIG_VESA_BPP_VARIANT, %al
309 cmp VESA_MODE_BPP_OFFSET(%di), %al
310#endif
311 jnz 1b
312
3132:
314
315 mov %cx, %bx
316 or $0xc000, %bx
317 push %di
318 mov $VESA_SET_MODE, %ax
319 int $0x10
320
321 pop %di
322 cmp $VESA_OK, %al
323 jnz 0f
324
325#if CONFIG_VESA_BPP == 8
326
327 # Set 3:2:3 VGA palette
328
329 mov VESA_MODE_ATTRIBUTES_OFFSET(%di), %ax
330 push %di
331 mov $vga323 - vesa_init, %di
332 mov $0x100, %ecx
333
334 bt $5, %ax # Test if VGA compatible registers are present
335 jnc vga_compat
336
337 # Try VESA routine to set palette
338
339 mov $VESA_SET_PALETTE, %ax
340 xor %bl, %bl
341 xor %dx, %dx
342 int $0x10
343
344 cmp $0x00, %ah
345 je vga_not_compat
346
347 vga_compat:
348
349 # Try VGA registers to set palette
350
351 movw $0x3c6, %dx # Set palette mask
352 movb $0xff, %al
353 outb %al, %dx
354
355 movw $0x3c8, %dx # First index to set
356 xor %al, %al
357 outb %al, %dx
358
359 movw $0x3c9, %dx # Data port
360 vga_loop:
361 movb %es:2(%di), %al
362 outb %al, %dx
363
364 movb %es:1(%di), %al
365 outb %al, %dx
366
367 movb %es:(%di), %al
368 outb %al, %dx
369
370 addw $4, %di
371 loop vga_loop
372
373 vga_not_compat:
374
375 pop %di
376
377#endif
378
379 mov VESA_MODE_PHADDR_OFFSET(%di), %esi
380 mov VESA_MODE_WIDTH_OFFSET(%di), %ax
381 shl $16, %eax
382 mov VESA_MODE_HEIGHT_OFFSET(%di), %ax
383 mov VESA_MODE_BPP_OFFSET(%di), %bl
384 xor %bh, %bh
385 shl $16, %ebx
386 mov VESA_MODE_SCANLINE_OFFSET(%di), %bx
387 mov %eax, %edi
388
3898:
390
391 mov %cr0, %eax
392 or $1, %eax
393 mov %eax, %cr0
394
395 jmp 9f
3969:
397
398 ljmpl $selector(KTEXT_DES), $(vesa_init_protect - vesa_init + VESA_INIT_SEGMENT << 4)
399
4000:# No prefered mode found
401 mov $0x111, %cx
402 push %di
403 push %cx
404 mov $VESA_GET_MODE_INFO, %ax
405 int $0x10
406
407 pop %cx
408 pop %di
409 cmp $VESA_OK, %al
410 jnz 1f
411 jz 2b # Force relative jump
412
4131:
414 mov $0x0003, %ax
415 int $0x10
416 mov $0xffffffff, %edi # EGA text mode used, because of problems with VESA
417 xor %ax, %ax
418 jz 8b # Force relative jump
419
420vga323:
421#include "vga323.pal"
422
423.code32
424vesa_init_protect:
425 movw $selector(KDATA_DES), %cx
426 movw %cx, %es
427 movw %cx, %fs
428 movw %cx, %gs
429 movw %cx, %ds # kernel data + stack
430 movw %cx, %ss
431
432 movl $START_STACK, %esp # initialize stack pointer
433
434 jmpl $selector(KTEXT_DES), $vesa_meeting_point
435
436.align 4
437e_vesa_init:
438#endif
439
440.section K_DATA_START, "aw", @progbits
441
442.align 4096
443page_directory:
444 .space 4096, 0
445
446grub_eax:
447 .long 0
448
449grub_ebx:
450 .long 0
451
452pse_msg:
453 .asciz "Page Size Extension not supported. System halted."
Note: See TracBrowser for help on using the repository browser.