0,0 → 1,228 |
# |
# Copyright (c) 2001-2004 Jakub Jermar |
# Copyright (c) 2005-2006 Martin Decky |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - Redistributions in binary form must reproduce the above copyright |
# notice, this list of conditions and the following disclaimer in the |
# documentation and/or other materials provided with the distribution. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
|
#include <arch/boot/boot.h> |
#include <arch/boot/memmap.h> |
#include <arch/mm/page.h> |
#include <arch/pm.h> |
#include <arch/cpuid.h> |
|
#define START_STACK (BOOT_OFFSET - BOOT_STACK_SIZE) |
|
.section K_TEXT_START, "ax" |
|
.code32 |
.align 4 |
.global multiboot_image_start |
multiboot_header: |
.long MULTIBOOT_HEADER_MAGIC |
.long MULTIBOOT_HEADER_FLAGS |
.long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS) # checksum |
.long multiboot_header |
.long unmapped_ktext_start |
.long 0 |
.long 0 |
.long multiboot_image_start |
|
multiboot_image_start: |
cld |
movl $START_STACK, %esp # initialize stack pointer |
lgdt KA2PA(bootstrap_gdtr) # initialize Global Descriptor Table register |
|
movw $gdtselector(KDATA_DES), %cx |
movw %cx, %es |
movw %cx, %fs |
movw %cx, %gs |
movw %cx, %ds # kernel data + stack |
movw %cx, %ss |
|
jmpl $gdtselector(KTEXT_DES), $multiboot_meeting_point |
multiboot_meeting_point: |
|
movl %eax, grub_eax # save parameters from GRUB |
movl %ebx, grub_ebx |
|
movl $(INTEL_CPUID_LEVEL), %eax |
cpuid |
cmp $0x0, %eax # any function > 0? |
jbe pse_unsupported |
|
movl $(INTEL_CPUID_STANDARD), %eax |
cpuid |
bt $(INTEL_PSE), %edx |
jc pse_supported |
|
pse_unsupported: |
movl $pse_msg, %esi |
jmp error_halt |
|
pse_supported: |
|
bt $(INTEL_SEP), %edx |
jc sep_supported |
|
movl $sep_msg, %esi |
jmp error_halt |
|
sep_supported: |
|
#include "vesa_prot.inc" |
|
# map kernel and turn paging on |
call map_kernel |
|
# call arch_pre_main(grub_eax, grub_ebx) |
pushl grub_ebx |
pushl grub_eax |
call arch_pre_main |
|
call main_bsp |
|
# not reached |
cli |
hlt0: |
hlt |
jmp hlt0 |
|
.global map_kernel |
map_kernel: |
# |
# Here we setup mapping for both the unmapped and mapped sections of the kernel. |
# For simplicity, we map the entire 4G space. |
# |
movl %cr4, %ecx |
orl $(1 << 4), %ecx # turn PSE on |
andl $(~(1 << 5)), %ecx # turn PAE off |
movl %ecx, %cr4 |
|
movl $(page_directory + 0), %esi |
movl $(page_directory + 2048), %edi |
xorl %ecx, %ecx |
xorl %ebx, %ebx |
|
floop: |
movl $((1 << 7) | (1 << 1) | (1 << 0)), %eax |
orl %ebx, %eax |
movl %eax, (%esi, %ecx, 4) # mapping 0x00000000 + %ecx * 4M => 0x00000000 + %ecx * 4M |
movl %eax, (%edi, %ecx, 4) # mapping 0x80000000 + %ecx * 4M => 0x00000000 + %ecx * 4M |
addl $(4 * 1024 * 1024), %ebx |
|
incl %ecx |
cmpl $512, %ecx |
jl floop |
|
movl %esi, %cr3 |
|
movl %cr0, %ebx |
orl $(1 << 31), %ebx # turn paging on |
movl %ebx, %cr0 |
ret |
|
# Print string from %esi to EGA display (in red) and halt |
error_halt: |
movl $0xb8000, %edi # base of EGA text mode memory |
xorl %eax, %eax |
|
movw $0x3d4, %dx # read bits 8 - 15 of the cursor address |
movb $0xe, %al |
outb %al, %dx |
|
movw $0x3d5, %dx |
inb %dx, %al |
shl $8, %ax |
|
movw $0x3d4, %dx # read bits 0 - 7 of the cursor address |
movb $0xf, %al |
outb %al, %dx |
|
movw $0x3d5, %dx |
inb %dx, %al |
|
cmp $1920, %ax |
jbe cursor_ok |
|
movw $1920, %ax # sanity check for the cursor on the last line |
|
cursor_ok: |
|
movw %ax, %bx |
shl $1, %eax |
addl %eax, %edi |
|
movw $0x0c00, %ax # black background, light red foreground |
|
ploop: |
lodsb |
cmp $0, %al |
je ploop_end |
stosw |
inc %bx |
jmp ploop |
ploop_end: |
|
movw $0x3d4, %dx # write bits 8 - 15 of the cursor address |
movb $0xe, %al |
outb %al, %dx |
|
movw $0x3d5, %dx |
movb %bh, %al |
outb %al, %dx |
|
movw $0x3d4, %dx # write bits 0 - 7 of the cursor address |
movb $0xf, %al |
outb %al, %dx |
|
movw $0x3d5, %dx |
movb %bl, %al |
outb %al, %dx |
|
cli |
hlt1: |
hlt |
jmp hlt1 |
|
#include "vesa_real.inc" |
|
.section K_DATA_START, "aw", @progbits |
|
.align 4096 |
page_directory: |
.space 4096, 0 |
|
grub_eax: |
.long 0 |
|
grub_ebx: |
.long 0 |
|
pse_msg: |
.asciz "Page Size Extension not supported. System halted." |
|
sep_msg: |
.asciz "SYSENTER/SYSEXIT not supported. System halted." |