source: mainline/kernel/arch/ia32/src/boot/multiboot.S@ dc41772

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since dc41772 was dc41772, checked in by Jiri Svoboda <jiri@…>, 7 years ago

Revert "Remove dead code" - needs more work

This reverts commit 9a791eb9411b32c4c733f382971ad899794149b1.

  • Property mode set to 100644
File size: 14.5 KB
RevLine 
[873c681]1/*
2 * Copyright (c) 2001 Jakub Jermar
3 * Copyright (c) 2005 Martin Decky
[6d8c4654]4 * Copyright (c) 2011 Martin Sucha
[873c681]5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * - Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * - Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * - The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
[f761f1eb]30
[8844e70]31#include <abi/asmtool.h>
[f9447155]32#include <arch/boot/boot.h>
[7ba16eb]33#include <arch/boot/memmap.h>
[8f2153b]34#include <arch/mm/page.h>
35#include <arch/pm.h>
[1f5c9c96]36#include <genarch/multiboot/multiboot.h>
[c18e666]37#include <arch/cpuid.h>
[57c2a87]38#include <arch/cpu.h>
[f9447155]39
[8781e9d]40// TODO: most of this file can be rewritten in C
41
[17aa6d1]42// TODO: FB state should be checked dynamically from provided multiboot info.
43// Currently we only enable EGA statically, which forces us to rebuild
44// the image to get very early debug output.
45
[873c681]46#define START_STACK (BOOT_OFFSET - BOOT_STACK_SIZE)
[66def8d]47
[874e312a]48.section K_TEXT_START, "ax"
[f761f1eb]49
[b0bf501]50.code32
[873c681]51
[dc41772]52.macro pm_error msg
53 movl \msg, %esi
54 jmp pm_error_halt
55.endm
56
[873c681]57.macro pm_status msg
[8781e9d]58#if defined(CONFIG_EGA) && !defined(CONFIG_FB)
[873c681]59 pushl %esi
60 movl \msg, %esi
61 call pm_early_puts
62 popl %esi
63#endif
64.endm
65
66.macro pm2_status msg
67 pushl \msg
68 call early_puts
69.endm
70
[f9447155]71.align 4
72multiboot_header:
73 .long MULTIBOOT_HEADER_MAGIC
[8781e9d]74#ifdef CONFIG_FB
[f9447155]75 .long MULTIBOOT_HEADER_FLAGS
[873c681]76 .long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS) /* checksum */
[8781e9d]77#else
78 .long MULTIBOOT_HEADER_FLAGS_NOFB
79 .long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS_NOFB) /* checksum */
80#endif
[66def8d]81 .long multiboot_header
[bae43dc]82 .long unmapped_start
[f9447155]83 .long 0
84 .long 0
[66def8d]85 .long multiboot_image_start
[8781e9d]86#ifdef CONFIG_FB
87 .long 0
88 .long CONFIG_BFB_WIDTH
89 .long CONFIG_BFB_HEIGHT
90 .long CONFIG_BFB_BPP
91#endif
[421c833]92
[8844e70]93SYMBOL(multiboot_image_start)
[f66c203d]94 cli
[e13daa5d]95 cld
[a35b458]96
[873c681]97 /* Initialize stack pointer */
98 movl $START_STACK, %esp
[a35b458]99
[f66c203d]100 /*
101 * Initialize Global Descriptor Table and
102 * Interrupt Descriptor Table registers
103 */
[1d3d2cf]104 lgdtl bootstrap_gdtr
[f66c203d]105 lidtl bootstrap_idtr
[a35b458]106
[873c681]107 /* Kernel data + stack */
[1d3d2cf]108 movw $GDT_SELECTOR(KDATA_DES), %cx
[5eb1379]109 movw %cx, %es
110 movw %cx, %fs
[ff133e2]111 movw %cx, %gs
[873c681]112 movw %cx, %ds
[5eb1379]113 movw %cx, %ss
[a35b458]114
[1d3d2cf]115 jmpl $GDT_SELECTOR(KTEXT_DES), $multiboot_meeting_point
[4533601]116 multiboot_meeting_point:
[a35b458]117
[1f5c9c96]118 /* Save multiboot arguments */
119 movl %eax, multiboot_eax
120 movl %ebx, multiboot_ebx
[a35b458]121
[873c681]122 pm_status $status_prot
[a35b458]123
[e3e4a2c]124#ifndef PROCESSOR_i486
[a35b458]125
[e3e4a2c]126 pm_status $status_prot2
[a35b458]127
[e3e4a2c]128 movl $(INTEL_CPUID_LEVEL), %eax
129 cpuid
130 cmp $0x0, %eax /* any function > 0? */
131 jbe pse_unsupported
[a35b458]132
[e3e4a2c]133 movl $(INTEL_CPUID_STANDARD), %eax
134 cpuid
135 bt $(INTEL_PSE), %edx
136 jnc pse_unsupported
[a35b458]137
[e3e4a2c]138 /* Map kernel and turn paging on */
139 pm_status $status_pse
140 call map_kernel_pse
141 jmp stack_init
[a35b458]142
[e3e4a2c]143#endif /* PROCESSOR_i486 */
[a35b458]144
[e3e4a2c]145 pse_unsupported:
[a35b458]146
[e3e4a2c]147 /* Map kernel and turn paging on */
148 pm_status $status_non_pse
[fb45c7b]149 call map_kernel_non_pse
[a35b458]150
[e3e4a2c]151 stack_init:
[a35b458]152
[873c681]153 /* Create the first stack frame */
154 pushl $0
155 movl %esp, %ebp
[a35b458]156
[e3e4a2c]157 pm2_status $status_prot3
[a35b458]158
[36df4109]159 /* Call ia32_pre_main(multiboot_eax, multiboot_ebx) */
[1f5c9c96]160 pushl multiboot_ebx
161 pushl multiboot_eax
[36df4109]162 call ia32_pre_main
[a35b458]163
[873c681]164 pm2_status $status_main
[a35b458]165
[873c681]166 /* Call main_bsp() */
[deca67b]167 call main_bsp
[a35b458]168
[873c681]169 /* Not reached */
[d47f0e1]170 cli
[421c833]171 hlt0:
172 hlt
173 jmp hlt0
[d47f0e1]174
[e3e4a2c]175/** Setup mapping for the kernel (PSE variant)
[873c681]176 *
177 * Setup mapping for both the unmapped and mapped sections
178 * of the kernel. For simplicity, we map the entire 4G space.
179 *
180 */
[8844e70]181FUNCTION_BEGIN(map_kernel_pse)
[b112055]182 /* Paging features */
[dcbc8be]183 movl %cr4, %ecx
[57c2a87]184 orl $CR4_PSE, %ecx /* PSE on */
185 andl $~CR4_PAE, %ecx /* PAE off */
[eaf6cd6]186 movl %ecx, %cr4
[a35b458]187
[eaf6cd6]188 movl $(page_directory + 0), %esi
189 movl $(page_directory + 2048), %edi
[cf27a6cb]190 xorl %ecx, %ecx
[e3e4a2c]191 xorl %ebx, %ebx
[a35b458]192
[e3e4a2c]193 floop_pse:
[a0d9abcd]194 movl $(PDE_4M | PDE_RW | PDE_P), %eax
[421c833]195 orl %ebx, %eax
[873c681]196 /* Mapping 0x00000000 + %ecx * 4M => 0x00000000 + %ecx * 4M */
197 movl %eax, (%esi, %ecx, 4)
198 /* Mapping 0x80000000 + %ecx * 4M => 0x00000000 + %ecx * 4M */
199 movl %eax, (%edi, %ecx, 4)
[e3e4a2c]200 addl $(4 * 1024 * 1024), %ebx
[a35b458]201
[421c833]202 incl %ecx
203 cmpl $512, %ecx
[e3e4a2c]204 jl floop_pse
[a35b458]205
[cf27a6cb]206 movl %esi, %cr3
[a35b458]207
[dcbc8be]208 movl %cr0, %ebx
[57c2a87]209 orl $CR0_PG, %ebx /* paging on */
[dcbc8be]210 movl %ebx, %cr0
[d47f0e1]211 ret
[8844e70]212FUNCTION_END(map_kernel_pse)
[dcbc8be]213
[e3e4a2c]214/** Setup mapping for the kernel (non-PSE variant).
215 *
216 * Setup mapping for both the unmapped and mapped sections
217 * of the kernel. For simplicity, we map the entire 4G space.
218 *
219 */
[8844e70]220FUNCTION_BEGIN(map_kernel_non_pse)
[e3e4a2c]221 /* Paging features */
222 movl %cr4, %ecx
[57c2a87]223 andl $~CR4_PAE, %ecx /* PAE off */
[e3e4a2c]224 movl %ecx, %cr4
[a35b458]225
[e3e4a2c]226 call calc_kernel_end
227 call find_mem_for_pt
[a35b458]228
[e3e4a2c]229 mov kernel_end, %esi
230 mov free_area, %ecx
[a35b458]231
[e3e4a2c]232 cmpl %esi, %ecx
233 jbe use_kernel_end
[a35b458]234
[e3e4a2c]235 mov %ecx, %esi
[a35b458]236
[e3e4a2c]237 /* Align address down to 4k */
[0637ddb]238 andl $(~(PAGE_SIZE - 1)), %esi
[a35b458]239
[e3e4a2c]240 use_kernel_end:
[a35b458]241
[e3e4a2c]242 /* Align address to 4k */
[0637ddb]243 addl $(PAGE_SIZE - 1), %esi
244 andl $(~(PAGE_SIZE - 1)), %esi
[a35b458]245
[e3e4a2c]246 /* Allocate space for page tables */
247 movl %esi, pt_loc
[0637ddb]248 movl $KA2PA(ballocs), %edi
[a35b458]249
[e3e4a2c]250 movl %esi, (%edi)
251 addl $4, %edi
252 movl $(2 * 1024 * 1024), (%edi)
[a35b458]253
[e3e4a2c]254 /* Fill page tables */
255 xorl %ecx, %ecx
256 xorl %ebx, %ebx
[a35b458]257
[e3e4a2c]258 floop_pt:
[a0d9abcd]259 movl $(PTE_RW | PTE_P), %eax
[e3e4a2c]260 orl %ebx, %eax
261 movl %eax, (%esi, %ecx, 4)
[0637ddb]262 addl $PAGE_SIZE, %ebx
[a35b458]263
[e3e4a2c]264 incl %ecx
265 cmpl $(512 * 1024), %ecx
[a35b458]266
[e3e4a2c]267 jl floop_pt
[a35b458]268
[e3e4a2c]269 /* Fill page directory */
270 movl $(page_directory + 0), %esi
271 movl $(page_directory + 2048), %edi
272 xorl %ecx, %ecx
273 movl pt_loc, %ebx
[a35b458]274
[e3e4a2c]275 floop:
[a0d9abcd]276 movl $(PDE_RW | PDE_P), %eax
[e3e4a2c]277 orl %ebx, %eax
[a35b458]278
[e3e4a2c]279 /* Mapping 0x00000000 + %ecx * 4M => 0x00000000 + %ecx * 4M */
280 movl %eax, (%esi, %ecx, 4)
[a35b458]281
[e3e4a2c]282 /* Mapping 0x80000000 + %ecx * 4M => 0x00000000 + %ecx * 4M */
283 movl %eax, (%edi, %ecx, 4)
[0637ddb]284 addl $PAGE_SIZE, %ebx
[a35b458]285
[e3e4a2c]286 incl %ecx
287 cmpl $512, %ecx
[a35b458]288
[e3e4a2c]289 jl floop
[a35b458]290
[e3e4a2c]291 movl %esi, %cr3
[a35b458]292
[e3e4a2c]293 movl %cr0, %ebx
[57c2a87]294 orl $CR0_PG, %ebx /* paging on */
[e3e4a2c]295 movl %ebx, %cr0
[a35b458]296
[e3e4a2c]297 ret
[8844e70]298FUNCTION_END(map_kernel_non_pse)
[e3e4a2c]299
300/** Calculate unmapped address of the end of the kernel. */
301calc_kernel_end:
[8a1afd2]302 movl $KA2PA(kdata_end), %edi
303 movl %edi, kernel_end
[e3e4a2c]304 ret
305
306/** Find free 2M (+4k for alignment) region where to store page tables */
307find_mem_for_pt:
308 /* Check if multiboot info is present */
[1f5c9c96]309 cmpl $MULTIBOOT_LOADER_MAGIC, multiboot_eax
[e3e4a2c]310 je check_multiboot_map
[a35b458]311
[e3e4a2c]312 ret
[a35b458]313
[e3e4a2c]314 check_multiboot_map:
[a35b458]315
[e3e4a2c]316 /* Copy address of the multiboot info to ebx */
[1f5c9c96]317 movl multiboot_ebx, %ebx
[a35b458]318
[e3e4a2c]319 /* Check if memory map flag is present */
320 movl (%ebx), %edx
[7ba16eb]321 andl $MULTIBOOT_INFO_FLAGS_MMAP, %edx
[e3e4a2c]322 jnz use_multiboot_map
[a35b458]323
[e3e4a2c]324 ret
[a35b458]325
[e3e4a2c]326 use_multiboot_map:
[a35b458]327
[e3e4a2c]328 /* Copy address of the memory map to edx */
[7ba16eb]329 movl MULTIBOOT_INFO_OFFSET_MMAP_ADDR(%ebx), %edx
[e3e4a2c]330 movl %edx, %ecx
[a35b458]331
[7ba16eb]332 addl MULTIBOOT_INFO_OFFSET_MMAP_LENGTH(%ebx), %ecx
[a35b458]333
[e3e4a2c]334 /* Find a free region at least 2M in size */
335 check_memmap_loop:
[a35b458]336
[e3e4a2c]337 /* Is this a free region? */
[7ba16eb]338 cmpl $MEMMAP_MEMORY_AVAILABLE, MULTIBOOT_MEMMAP_OFFSET_MM_INFO + E820MEMMAP_OFFSET_TYPE(%edx)
[e3e4a2c]339 jnz next_region
[a35b458]340
[e3e4a2c]341 /* Check size */
[7ba16eb]342 cmpl $0, MULTIBOOT_MEMMAP_OFFSET_MM_INFO + E820MEMMAP_OFFSET_SIZE + 4(%edx)
[e3e4a2c]343 jnz next_region
[7ba16eb]344 cmpl $(2 * 1024 * 1024 + PAGE_SIZE), MULTIBOOT_MEMMAP_OFFSET_MM_INFO + E820MEMMAP_OFFSET_SIZE(%edx)
[e3e4a2c]345 jbe next_region
[a35b458]346
[7ba16eb]347 cmpl $0, MULTIBOOT_MEMMAP_OFFSET_MM_INFO + E820MEMMAP_OFFSET_BASE_ADDRESS + 4(%edx)
[e3e4a2c]348 jz found_region
[a35b458]349
[e3e4a2c]350 next_region:
[a35b458]351
[e3e4a2c]352 cmp %ecx, %edx
353 jbe next_region_do
[a35b458]354
[e3e4a2c]355 ret
[a35b458]356
[e3e4a2c]357 next_region_do:
[a35b458]358
[7ba16eb]359 addl MULTIBOOT_MEMMAP_OFFSET_SIZE(%edx), %edx
360 addl $MULTIBOOT_MEMMAP_SIZE_SIZE, %edx
[e3e4a2c]361 jmp check_memmap_loop
[a35b458]362
[e3e4a2c]363 found_region:
[a35b458]364
[e3e4a2c]365 /* Use end of the found region */
[7ba16eb]366 mov MULTIBOOT_MEMMAP_OFFSET_MM_INFO + E820MEMMAP_OFFSET_BASE_ADDRESS(%edx), %ecx
367 add MULTIBOOT_MEMMAP_OFFSET_MM_INFO + E820MEMMAP_OFFSET_SIZE(%edx), %ecx
[e3e4a2c]368 sub $(2 * 1024 * 1024), %ecx
369 mov %ecx, free_area
[a35b458]370
[e3e4a2c]371 ret
372
[dc41772]373/** Print string to EGA display (in light red) and halt.
374 *
375 * Should be executed from 32 bit protected mode with paging
376 * turned off. Stack is not required. This routine is used even
377 * if CONFIG_EGA is not enabled. Since we are going to halt the
378 * CPU anyway, it is always better to at least try to print
379 * some hints.
380 *
381 * @param %esi NULL-terminated string to print.
382 *
383 */
384pm_error_halt:
385 movl $0xb8000, %edi /* base of EGA text mode memory */
386 xorl %eax, %eax
387
388 /* Read bits 8 - 15 of the cursor address */
389 movw $0x3d4, %dx
390 movb $0xe, %al
391 outb %al, %dx
392
393 movw $0x3d5, %dx
394 inb %dx, %al
395 shl $8, %ax
396
397 /* Read bits 0 - 7 of the cursor address */
398 movw $0x3d4, %dx
399 movb $0xf, %al
400 outb %al, %dx
401
402 movw $0x3d5, %dx
403 inb %dx, %al
404
405 /* Sanity check for the cursor on screen */
406 cmp $2000, %ax
407 jb err_cursor_ok
408
409 movw $1998, %ax
410
411 err_cursor_ok:
412
413 movw %ax, %bx
414 shl $1, %eax
415 addl %eax, %edi
416
417 err_ploop:
418 lodsb
419
420 cmp $0, %al
421 je err_ploop_end
422
423 movb $0x0c, %ah /* black background, light red foreground */
424 stosw
425
426 /* Sanity check for the cursor on the last line */
427 inc %bx
428 cmp $2000, %bx
429 jb err_ploop
430
431 /* Scroll the screen (24 rows) */
432 movl %esi, %edx
433 movl $0xb80a0, %esi
434 movl $0xb8000, %edi
435 movl $960, %ecx
436 rep movsl
437
438 /* Clear the 24th row */
439 xorl %eax, %eax
440 movl $40, %ecx
441 rep stosl
442
443 /* Go to row 24 */
444 movl %edx, %esi
445 movl $0xb8f00, %edi
446 movw $1920, %bx
447
448 jmp err_ploop
449 err_ploop_end:
450
451 /* Write bits 8 - 15 of the cursor address */
452 movw $0x3d4, %dx
453 movb $0xe, %al
454 outb %al, %dx
455
456 movw $0x3d5, %dx
457 movb %bh, %al
458 outb %al, %dx
459
460 /* Write bits 0 - 7 of the cursor address */
461 movw $0x3d4, %dx
462 movb $0xf, %al
463 outb %al, %dx
464
465 movw $0x3d5, %dx
466 movb %bl, %al
467 outb %al, %dx
468
469 cli
470 hlt1:
471 hlt
472 jmp hlt1
473
[873c681]474/** Print string to EGA display (in light green).
475 *
476 * Should be called from 32 bit protected mode with paging
477 * turned off. A stack space of at least 24 bytes is required,
478 * but the function does not establish a stack frame.
479 *
480 * Macros such as pm_status take care that this function
481 * is used only when CONFIG_EGA is enabled.
482 *
483 * @param %esi NULL-terminated string to print.
484 *
485 */
486pm_early_puts:
487 pushl %eax
488 pushl %ebx
489 pushl %ecx
490 pushl %edx
491 pushl %edi
[a35b458]492
[873c681]493 movl $0xb8000, %edi /* base of EGA text mode memory */
494 xorl %eax, %eax
[a35b458]495
[873c681]496 /* Read bits 8 - 15 of the cursor address */
497 movw $0x3d4, %dx
498 movb $0xe, %al
499 outb %al, %dx
[a35b458]500
[873c681]501 movw $0x3d5, %dx
502 inb %dx, %al
503 shl $8, %ax
[a35b458]504
[873c681]505 /* Read bits 0 - 7 of the cursor address */
506 movw $0x3d4, %dx
507 movb $0xf, %al
508 outb %al, %dx
[a35b458]509
[873c681]510 movw $0x3d5, %dx
511 inb %dx, %al
[a35b458]512
[873c681]513 /* Sanity check for the cursor on screen */
514 cmp $2000, %ax
515 jb pm_puts_cursor_ok
[a35b458]516
[873c681]517 movw $1998, %ax
[a35b458]518
[873c681]519 pm_puts_cursor_ok:
[a35b458]520
[873c681]521 movw %ax, %bx
522 shl $1, %eax
523 addl %eax, %edi
[a35b458]524
[873c681]525 pm_puts_ploop:
526 lodsb
[a35b458]527
[873c681]528 cmp $0, %al
529 je pm_puts_ploop_end
[a35b458]530
[873c681]531 movb $0x0a, %ah /* black background, light green foreground */
532 stosw
[a35b458]533
[873c681]534 /* Sanity check for the cursor on the last line */
535 inc %bx
536 cmp $2000, %bx
537 jb pm_puts_ploop
[a35b458]538
[873c681]539 /* Scroll the screen (24 rows) */
540 movl %esi, %edx
541 movl $0xb80a0, %esi
542 movl $0xb8000, %edi
[22c3444]543 movl $960, %ecx
544 rep movsl
[a35b458]545
[873c681]546 /* Clear the 24th row */
547 xorl %eax, %eax
[22c3444]548 movl $40, %ecx
549 rep stosl
[a35b458]550
[873c681]551 /* Go to row 24 */
552 movl %edx, %esi
553 movl $0xb8f00, %edi
554 movw $1920, %bx
[a35b458]555
[873c681]556 jmp pm_puts_ploop
557 pm_puts_ploop_end:
[a35b458]558
[873c681]559 /* Write bits 8 - 15 of the cursor address */
560 movw $0x3d4, %dx
561 movb $0xe, %al
562 outb %al, %dx
[a35b458]563
[873c681]564 movw $0x3d5, %dx
565 movb %bh, %al
566 outb %al, %dx
[a35b458]567
[873c681]568 /* Write bits 0 - 7 of the cursor address */
569 movw $0x3d4, %dx
570 movb $0xf, %al
571 outb %al, %dx
[a35b458]572
[873c681]573 movw $0x3d5, %dx
574 movb %bl, %al
575 outb %al, %dx
[a35b458]576
[873c681]577 popl %edi
578 popl %edx
579 popl %ecx
580 popl %ebx
581 popl %eax
[a35b458]582
[873c681]583 ret
584
585/** Print string to EGA display.
586 *
587 * Should be called from 32 bit protected mode (with paging
588 * enabled and stack established). This function is ABI compliant.
589 *
590 * If CONFIG_EGA is undefined or CONFIG_FB is defined
591 * then this function does nothing.
592 *
593 * @param %ebp+0x08 NULL-terminated string to print.
594 *
595 */
596early_puts:
[a35b458]597
[873c681]598#if ((defined(CONFIG_EGA)) && (!defined(CONFIG_FB)))
[a35b458]599
[873c681]600 /* Prologue, save preserved registers */
601 pushl %ebp
602 movl %esp, %ebp
603 pushl %ebx
604 pushl %esi
605 pushl %edi
[a35b458]606
[873c681]607 movl 0x08(%ebp), %esi
608 movl $(PA2KA(0xb8000)), %edi /* base of EGA text mode memory */
609 xorl %eax, %eax
[a35b458]610
[873c681]611 /* Read bits 8 - 15 of the cursor address */
612 movw $0x3d4, %dx
613 movb $0xe, %al
614 outb %al, %dx
[a35b458]615
[873c681]616 movw $0x3d5, %dx
617 inb %dx, %al
618 shl $8, %ax
[a35b458]619
[873c681]620 /* Read bits 0 - 7 of the cursor address */
621 movw $0x3d4, %dx
622 movb $0xf, %al
623 outb %al, %dx
[a35b458]624
[873c681]625 movw $0x3d5, %dx
626 inb %dx, %al
[a35b458]627
[873c681]628 /* Sanity check for the cursor on screen */
629 cmp $2000, %ax
630 jb early_puts_cursor_ok
[a35b458]631
[873c681]632 movw $1998, %ax
[a35b458]633
[873c681]634 early_puts_cursor_ok:
[a35b458]635
[873c681]636 movw %ax, %bx
637 shl $1, %eax
638 addl %eax, %edi
[a35b458]639
[873c681]640 early_puts_ploop:
641 lodsb
[a35b458]642
[873c681]643 cmp $0, %al
644 je early_puts_ploop_end
[a35b458]645
[873c681]646 movb $0x0e, %ah /* black background, yellow foreground */
647 stosw
[a35b458]648
[873c681]649 /* Sanity check for the cursor on the last line */
650 inc %bx
651 cmp $2000, %bx
652 jb early_puts_ploop
[a35b458]653
[873c681]654 /* Scroll the screen (24 rows) */
655 movl %esi, %edx
656 movl $(PA2KA(0xb80a0)), %esi
657 movl $(PA2KA(0xb8000)), %edi
[22c3444]658 movl $960, %ecx
659 rep movsl
[a35b458]660
[873c681]661 /* Clear the 24th row */
662 xorl %eax, %eax
[22c3444]663 movl $40, %ecx
664 rep stosl
[a35b458]665
[873c681]666 /* Go to row 24 */
667 movl %edx, %esi
668 movl $(PA2KA(0xb8f00)), %edi
669 movw $1920, %bx
[a35b458]670
[873c681]671 jmp early_puts_ploop
672 early_puts_ploop_end:
[a35b458]673
[873c681]674 /* Write bits 8 - 15 of the cursor address */
675 movw $0x3d4, %dx
676 movb $0xe, %al
677 outb %al, %dx
[a35b458]678
[873c681]679 movw $0x3d5, %dx
680 movb %bh, %al
681 outb %al, %dx
[a35b458]682
[873c681]683 /* Write bits 0 - 7 of the cursor address */
684 movw $0x3d4, %dx
685 movb $0xf, %al
686 outb %al, %dx
[a35b458]687
[873c681]688 movw $0x3d5, %dx
689 movb %bl, %al
690 outb %al, %dx
[a35b458]691
[873c681]692 /* Epilogue, restore preserved registers */
693 popl %edi
694 popl %esi
695 popl %ebx
696 leave
[a35b458]697
[873c681]698#endif
[a35b458]699
[873c681]700 ret
701
[874e312a]702.section K_DATA_START, "aw", @progbits
[dcbc8be]703
704.align 4096
705page_directory:
706 .space 4096, 0
[eaf6cd6]707
[8844e70]708SYMBOL(bootstrap_idtr)
[f66c203d]709 .word 0
710 .long 0
711
[8844e70]712SYMBOL(bootstrap_gdtr)
[1d3d2cf]713 .word GDT_SELECTOR(GDT_ITEMS)
714 .long KA2PA(gdt)
715
[8844e70]716SYMBOL(multiboot_eax)
[7cb567cd]717 .long 0
[1f5c9c96]718
[8844e70]719SYMBOL(multiboot_ebx)
[7cb567cd]720 .long 0
721
[b112055]722pt_loc:
723 .long 0
[e3e4a2c]724kernel_end:
[b112055]725 .long 0
726free_area:
727 .long 0
728
[873c681]729status_prot:
730 .asciz "[prot] "
[e3e4a2c]731status_pse:
732 .asciz "[pse] "
733status_non_pse:
734 .asciz "[non_pse] "
[1f5c9c96]735status_multiboot_cmdline:
736 .asciz "[multiboot_cmdline] "
[873c681]737status_prot2:
738 .asciz "[prot2] "
[e3e4a2c]739status_prot3:
740 .asciz "[prot3] "
[873c681]741status_main:
742 .asciz "[main] "
Note: See TracBrowser for help on using the repository browser.