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

Last change on this file was 8be3230, checked in by Jiri Svoboda <jiri@…>, 7 years ago

Revert "Remove realmode VESA code" - needs more work

This reverts commit 8781e9d05ac3f6aeaa3ad709c5af9efa3209b87a.

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