source: mainline/kernel/arch/ia32/src/boot/boot.S@ 07b39338

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 07b39338 was f4fa6d9, checked in by Martin Sucha <sucha14@…>, 15 years ago

Remove CPUID check for PSE on ia32 as we no longer need that

  • Property mode set to 100644
File size: 12.3 KB
Line 
1/*
2 * Copyright (c) 2001 Jakub Jermar
3 * Copyright (c) 2005 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#include <arch/cpuid.h>
35
36#define START_STACK (BOOT_OFFSET - BOOT_STACK_SIZE)
37
38.section K_TEXT_START, "ax"
39
40.code32
41
42.macro pm_error msg
43 movl \msg, %esi
44 jmp pm_error_halt
45.endm
46
47.macro pm_status msg
48#ifdef CONFIG_EGA
49 pushl %esi
50 movl \msg, %esi
51 call pm_early_puts
52 popl %esi
53#endif
54.endm
55
56.macro pm2_status msg
57 pushl \msg
58 call early_puts
59.endm
60
61.align 4
62.global multiboot_image_start
63multiboot_header:
64 .long MULTIBOOT_HEADER_MAGIC
65 .long MULTIBOOT_HEADER_FLAGS
66 .long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS) /* checksum */
67 .long multiboot_header
68 .long unmapped_ktext_start
69 .long 0
70 .long 0
71 .long multiboot_image_start
72
73multiboot_image_start:
74 cld
75
76 /* Initialize stack pointer */
77 movl $START_STACK, %esp
78
79 /* Initialize Global Descriptor Table register */
80 lgdtl bootstrap_gdtr
81
82 /* Kernel data + stack */
83 movw $GDT_SELECTOR(KDATA_DES), %cx
84 movw %cx, %es
85 movw %cx, %fs
86 movw %cx, %gs
87 movw %cx, %ds
88 movw %cx, %ss
89
90 jmpl $GDT_SELECTOR(KTEXT_DES), $multiboot_meeting_point
91 multiboot_meeting_point:
92
93 /* Save GRUB arguments */
94 movl %eax, grub_eax
95 movl %ebx, grub_ebx
96
97 pm_status $status_prot
98
99#include "vesa_prot.inc"
100
101 /* Map kernel and turn paging on */
102 call map_kernel
103
104 /* Create the first stack frame */
105 pushl $0
106 movl %esp, %ebp
107
108 pm2_status $status_prot2
109
110 /* Call arch_pre_main(grub_eax, grub_ebx) */
111 pushl grub_ebx
112 pushl grub_eax
113 call arch_pre_main
114
115 pm2_status $status_main
116
117 /* Call main_bsp() */
118 call main_bsp
119
120 /* Not reached */
121 cli
122 hlt0:
123 hlt
124 jmp hlt0
125
126/** Calculate unmapped address of the end of the kernel. */
127calc_end_of_kernel:
128 movl $hardcoded_load_address, %edi
129 andl $0x7fffffff, %edi
130 movl (%edi), %esi
131 andl $0x7fffffff, %esi
132
133 movl $hardcoded_ktext_size, %edi
134 andl $0x7fffffff, %edi
135 addl (%edi), %esi
136 andl $0x7fffffff, %esi
137
138 movl $hardcoded_kdata_size, %edi
139 andl $0x7fffffff, %edi
140 addl (%edi), %esi
141 andl $0x7fffffff, %esi
142 movl %esi, end_of_kernel
143 ret
144
145/** Find free 2M (+4k for alignment) region where to store page tables */
146find_mem_for_pt:
147 /* Check if multiboot info is present */
148 cmpl $0x2BADB002, grub_eax
149 je check_multiboot_map
150 ret
151check_multiboot_map:
152 /* Copy address of the multiboot info to ebx */
153 movl grub_ebx, %ebx
154 /* Check if memory map flag is present */
155 movl (%ebx), %edx
156 andl $(1 << 6), %edx
157 jnz use_multiboot_map
158 ret
159use_multiboot_map:
160 /* Copy address of the memory map to edx */
161 movl 48(%ebx), %edx
162 movl %edx, %ecx
163 addl 44(%ebx), %ecx
164 /* Find a free region at least 2M in size */
165 check_memmap_loop:
166 /* Is this a free region? */
167 cmp $1, 20(%edx)
168 jnz next_region
169 /* Check size */
170 cmp $0, 16(%edx)
171 jnz next_region
172 cmpl $(2 * 1024 * 1024 + 4 * 1024), 12(%edx)
173 jbe next_region
174 cmp $0, 8(%edx)
175 jz found_region
176 next_region:
177 cmp %ecx, %edx
178 jbe next_region_do
179 ret
180 next_region_do:
181 addl (%edx), %edx
182 addl $4, %edx
183 jmp check_memmap_loop
184 found_region:
185 /* Use end of the found region */
186 mov 4(%edx), %ecx
187 add 12(%edx), %ecx
188 sub $(2 * 1024 * 1024), %ecx
189 mov %ecx, free_area
190 ret
191
192
193/** Setup mapping for the kernel.
194 *
195 * Setup mapping for both the unmapped and mapped sections
196 * of the kernel. For simplicity, we map the entire 4G space.
197 *
198 */
199.global map_kernel
200map_kernel:
201 /* Paging features */
202 movl %cr4, %ecx
203 andl $(~(1 << 5)), %ecx /* PAE off */
204 movl %ecx, %cr4
205
206 call calc_end_of_kernel
207 call find_mem_for_pt
208 mov end_of_kernel, %esi
209 mov free_area, %ecx
210 cmpl %esi, %ecx
211 jbe use_end_of_kernel
212 mov %ecx, %esi
213 /* Align address down to 4k */
214 andl $(~4095), %esi
215use_end_of_kernel:
216
217 /* Align address to 4k */
218 addl $4095, %esi
219 andl $(~4095), %esi
220
221 /* Allocate space for page tables*/
222 movl %esi, pt_loc
223 movl $ballocs, %edi
224 andl $0x7fffffff, %edi
225 movl %esi, (%edi)
226 addl $4, %edi
227 movl $(2*1024*1024), (%edi)
228
229 /* Fill page tables */
230 xorl %ecx, %ecx
231 xorl %ebx, %ebx
232
233 floop_pt:
234 movl $((1 << 1) | (1 << 0)), %eax
235 orl %ebx, %eax
236 movl %eax, (%esi, %ecx, 4)
237 addl $(4 * 1024), %ebx
238
239 incl %ecx
240 cmpl $(512 * 1024), %ecx
241 jl floop_pt
242
243 /* Fill page directory */
244 movl $(page_directory + 0), %esi
245 movl $(page_directory + 2048), %edi
246 xorl %ecx, %ecx
247 movl pt_loc, %ebx
248
249 floop:
250 movl $((1 << 1) | (1 << 0)), %eax
251 orl %ebx, %eax
252 /* Mapping 0x00000000 + %ecx * 4M => 0x00000000 + %ecx * 4M */
253 movl %eax, (%esi, %ecx, 4)
254 /* Mapping 0x80000000 + %ecx * 4M => 0x00000000 + %ecx * 4M */
255 movl %eax, (%edi, %ecx, 4)
256 addl $(4 * 1024), %ebx
257
258 incl %ecx
259 cmpl $512, %ecx
260 jl floop
261
262 movl %esi, %cr3
263
264 movl %cr0, %ebx
265 orl $(1 << 31), %ebx /* paging on */
266 movl %ebx, %cr0
267 ret
268
269/** Print string to EGA display (in light red) and halt.
270 *
271 * Should be executed from 32 bit protected mode with paging
272 * turned off. Stack is not required. This routine is used even
273 * if CONFIG_EGA is not enabled. Since we are going to halt the
274 * CPU anyway, it is always better to at least try to print
275 * some hints.
276 *
277 * @param %esi NULL-terminated string to print.
278 *
279 */
280pm_error_halt:
281 movl $0xb8000, %edi /* base of EGA text mode memory */
282 xorl %eax, %eax
283
284 /* Read bits 8 - 15 of the cursor address */
285 movw $0x3d4, %dx
286 movb $0xe, %al
287 outb %al, %dx
288
289 movw $0x3d5, %dx
290 inb %dx, %al
291 shl $8, %ax
292
293 /* Read bits 0 - 7 of the cursor address */
294 movw $0x3d4, %dx
295 movb $0xf, %al
296 outb %al, %dx
297
298 movw $0x3d5, %dx
299 inb %dx, %al
300
301 /* Sanity check for the cursor on screen */
302 cmp $2000, %ax
303 jb err_cursor_ok
304
305 movw $1998, %ax
306
307 err_cursor_ok:
308
309 movw %ax, %bx
310 shl $1, %eax
311 addl %eax, %edi
312
313 err_ploop:
314 lodsb
315
316 cmp $0, %al
317 je err_ploop_end
318
319 movb $0x0c, %ah /* black background, light red foreground */
320 stosw
321
322 /* Sanity check for the cursor on the last line */
323 inc %bx
324 cmp $2000, %bx
325 jb err_ploop
326
327 /* Scroll the screen (24 rows) */
328 movl %esi, %edx
329 movl $0xb80a0, %esi
330 movl $0xb8000, %edi
331 movl $960, %ecx
332 rep movsl
333
334 /* Clear the 24th row */
335 xorl %eax, %eax
336 movl $40, %ecx
337 rep stosl
338
339 /* Go to row 24 */
340 movl %edx, %esi
341 movl $0xb8f00, %edi
342 movw $1920, %bx
343
344 jmp err_ploop
345 err_ploop_end:
346
347 /* Write bits 8 - 15 of the cursor address */
348 movw $0x3d4, %dx
349 movb $0xe, %al
350 outb %al, %dx
351
352 movw $0x3d5, %dx
353 movb %bh, %al
354 outb %al, %dx
355
356 /* Write bits 0 - 7 of the cursor address */
357 movw $0x3d4, %dx
358 movb $0xf, %al
359 outb %al, %dx
360
361 movw $0x3d5, %dx
362 movb %bl, %al
363 outb %al, %dx
364
365 cli
366 hlt1:
367 hlt
368 jmp hlt1
369
370/** Print string to EGA display (in light green).
371 *
372 * Should be called from 32 bit protected mode with paging
373 * turned off. A stack space of at least 24 bytes is required,
374 * but the function does not establish a stack frame.
375 *
376 * Macros such as pm_status take care that this function
377 * is used only when CONFIG_EGA is enabled.
378 *
379 * @param %esi NULL-terminated string to print.
380 *
381 */
382pm_early_puts:
383 pushl %eax
384 pushl %ebx
385 pushl %ecx
386 pushl %edx
387 pushl %edi
388
389 movl $0xb8000, %edi /* base of EGA text mode memory */
390 xorl %eax, %eax
391
392 /* Read bits 8 - 15 of the cursor address */
393 movw $0x3d4, %dx
394 movb $0xe, %al
395 outb %al, %dx
396
397 movw $0x3d5, %dx
398 inb %dx, %al
399 shl $8, %ax
400
401 /* Read bits 0 - 7 of the cursor address */
402 movw $0x3d4, %dx
403 movb $0xf, %al
404 outb %al, %dx
405
406 movw $0x3d5, %dx
407 inb %dx, %al
408
409 /* Sanity check for the cursor on screen */
410 cmp $2000, %ax
411 jb pm_puts_cursor_ok
412
413 movw $1998, %ax
414
415 pm_puts_cursor_ok:
416
417 movw %ax, %bx
418 shl $1, %eax
419 addl %eax, %edi
420
421 pm_puts_ploop:
422 lodsb
423
424 cmp $0, %al
425 je pm_puts_ploop_end
426
427 movb $0x0a, %ah /* black background, light green foreground */
428 stosw
429
430 /* Sanity check for the cursor on the last line */
431 inc %bx
432 cmp $2000, %bx
433 jb pm_puts_ploop
434
435 /* Scroll the screen (24 rows) */
436 movl %esi, %edx
437 movl $0xb80a0, %esi
438 movl $0xb8000, %edi
439 movl $960, %ecx
440 rep movsl
441
442 /* Clear the 24th row */
443 xorl %eax, %eax
444 movl $40, %ecx
445 rep stosl
446
447 /* Go to row 24 */
448 movl %edx, %esi
449 movl $0xb8f00, %edi
450 movw $1920, %bx
451
452 jmp pm_puts_ploop
453 pm_puts_ploop_end:
454
455 /* Write bits 8 - 15 of the cursor address */
456 movw $0x3d4, %dx
457 movb $0xe, %al
458 outb %al, %dx
459
460 movw $0x3d5, %dx
461 movb %bh, %al
462 outb %al, %dx
463
464 /* Write bits 0 - 7 of the cursor address */
465 movw $0x3d4, %dx
466 movb $0xf, %al
467 outb %al, %dx
468
469 movw $0x3d5, %dx
470 movb %bl, %al
471 outb %al, %dx
472
473 popl %edi
474 popl %edx
475 popl %ecx
476 popl %ebx
477 popl %eax
478
479 ret
480
481/** Print string to EGA display.
482 *
483 * Should be called from 32 bit protected mode (with paging
484 * enabled and stack established). This function is ABI compliant.
485 *
486 * If CONFIG_EGA is undefined or CONFIG_FB is defined
487 * then this function does nothing.
488 *
489 * @param %ebp+0x08 NULL-terminated string to print.
490 *
491 */
492early_puts:
493
494#if ((defined(CONFIG_EGA)) && (!defined(CONFIG_FB)))
495
496 /* Prologue, save preserved registers */
497 pushl %ebp
498 movl %esp, %ebp
499 pushl %ebx
500 pushl %esi
501 pushl %edi
502
503 movl 0x08(%ebp), %esi
504 movl $(PA2KA(0xb8000)), %edi /* base of EGA text mode memory */
505 xorl %eax, %eax
506
507 /* Read bits 8 - 15 of the cursor address */
508 movw $0x3d4, %dx
509 movb $0xe, %al
510 outb %al, %dx
511
512 movw $0x3d5, %dx
513 inb %dx, %al
514 shl $8, %ax
515
516 /* Read bits 0 - 7 of the cursor address */
517 movw $0x3d4, %dx
518 movb $0xf, %al
519 outb %al, %dx
520
521 movw $0x3d5, %dx
522 inb %dx, %al
523
524 /* Sanity check for the cursor on screen */
525 cmp $2000, %ax
526 jb early_puts_cursor_ok
527
528 movw $1998, %ax
529
530 early_puts_cursor_ok:
531
532 movw %ax, %bx
533 shl $1, %eax
534 addl %eax, %edi
535
536 early_puts_ploop:
537 lodsb
538
539 cmp $0, %al
540 je early_puts_ploop_end
541
542 movb $0x0e, %ah /* black background, yellow foreground */
543 stosw
544
545 /* Sanity check for the cursor on the last line */
546 inc %bx
547 cmp $2000, %bx
548 jb early_puts_ploop
549
550 /* Scroll the screen (24 rows) */
551 movl %esi, %edx
552 movl $(PA2KA(0xb80a0)), %esi
553 movl $(PA2KA(0xb8000)), %edi
554 movl $960, %ecx
555 rep movsl
556
557 /* Clear the 24th row */
558 xorl %eax, %eax
559 movl $40, %ecx
560 rep stosl
561
562 /* Go to row 24 */
563 movl %edx, %esi
564 movl $(PA2KA(0xb8f00)), %edi
565 movw $1920, %bx
566
567 jmp early_puts_ploop
568 early_puts_ploop_end:
569
570 /* Write bits 8 - 15 of the cursor address */
571 movw $0x3d4, %dx
572 movb $0xe, %al
573 outb %al, %dx
574
575 movw $0x3d5, %dx
576 movb %bh, %al
577 outb %al, %dx
578
579 /* Write bits 0 - 7 of the cursor address */
580 movw $0x3d4, %dx
581 movb $0xf, %al
582 outb %al, %dx
583
584 movw $0x3d5, %dx
585 movb %bl, %al
586 outb %al, %dx
587
588 /* Epilogue, restore preserved registers */
589 popl %edi
590 popl %esi
591 popl %ebx
592 leave
593
594#endif
595
596 ret
597
598#include "vesa_real.inc"
599
600.section K_DATA_START, "aw", @progbits
601
602.align 4096
603page_directory:
604 .space 4096, 0
605
606bootstrap_gdtr:
607 .word GDT_SELECTOR(GDT_ITEMS)
608 .long KA2PA(gdt)
609
610grub_eax:
611 .long 0
612
613grub_ebx:
614 .long 0
615
616pt_loc:
617 .long 0
618end_of_kernel:
619 .long 0
620free_area:
621 .long 0
622
623err_pse:
624 .asciz "Page Size Extension not supported. System halted."
625
626status_prot:
627 .asciz "[prot] "
628status_vesa_copy:
629 .asciz "[vesa_copy] "
630status_grub_cmdline:
631 .asciz "[grub_cmdline] "
632status_vesa_real:
633 .asciz "[vesa_real] "
634status_prot2:
635 .asciz "[prot2] "
636status_main:
637 .asciz "[main] "
Note: See TracBrowser for help on using the repository browser.