/kernel/trunk/arch/amd64/src/mm/memory_init.c |
---|
31,9 → 31,8 |
#include <arch/mm/page.h> |
#include <print.h> |
__u8 e820counter = 0xff; |
struct e820memmap_ e820table[MEMMAP_E820_MAX_RECORDS]; |
__u32 e801memorysize; |
__u8 e820counter __attribute__ ((section ("BOOT_DATA"))) = 0xff; |
struct e820memmap_ e820table[MEMMAP_E820_MAX_RECORDS] __attribute__ ((section ("BOOT_DATA"))) ; |
size_t get_memory_size(void) |
{ |
/kernel/trunk/arch/amd64/src/boot/boot.S |
---|
33,45 → 33,55 |
#include <arch/cpuid.h> |
#include <arch/boot/boot.h> |
#define START_STACK (BOOT_OFFSET - BOOT_STACK_SIZE) |
#define START_STACK_64 0xffffffff80007c00 |
# |
# This is where we require any SPARTAN-kernel-compatible boot loader |
# to pass control in real mode. |
# |
# Protected mode tables are statically initialised during compile |
# time. So we can just load the respective table registers and |
# switch to protected mode. |
# |
#define START_STACK (BOOTSTRAP_OFFSET-0x400) |
.section K_TEXT_START, "ax" |
# .code16 |
# .global kernel_image_start |
# .global multiboot_image_start |
# kernel_image_start: |
# cli |
# xorw %ax,%ax |
# movw %ax,%ds |
# movw %ax,%es |
# movw %ax,%ss # initialize stack segment register |
# movl $(START_STACK), %esp # initialize stack pointer |
# |
# call memmap_arch_init |
# |
# movl $0x80000000, %eax |
# cpuid |
# cmp $0x80000000, %eax # any function > 80000000h? |
# jbe no_long_mode |
# movl $(AMD_CPUID_EXTENDED), %eax # Extended function code 80000001 |
# cpuid |
# bt $29, %edx # Test if long mode is supported. |
# jnc no_long_mode |
# |
# # Load gdtr, idtr |
# lgdt real_bootstrap_gdtr_boot |
# |
# movl %cr0,%eax |
# orl $0x1,%eax |
# movl %eax,%cr0 # switch to protected mode |
# |
# jmpl $gdtselector(KTEXT32_DES), $now_in_prot |
# |
# no_long_mode: |
# 1: |
# jmp 1b |
# |
.code16 |
.global kernel_image_start |
.global multiboot_image_start |
kernel_image_start: |
cli |
xorw %ax,%ax |
movw %ax,%ds |
movw %ax,%es |
movw %ax,%ss # initialize stack segment register |
movl $(START_STACK), %esp # initialize stack pointer |
call memmap_arch_init |
movl $0x80000000, %eax |
cpuid |
cmp $0x80000000, %eax # any function > 80000000h? |
jbe no_long_mode |
movl $(AMD_CPUID_EXTENDED), %eax # Extended function code 80000001 |
cpuid |
bt $29, %edx # Test if long mode is supported. |
jnc no_long_mode |
# Load gdtr, idtr |
lgdt real_bootstrap_gdtr_boot |
movl %cr0,%eax |
orl $0x1,%eax |
movl %eax,%cr0 # switch to protected mode |
jmpl $gdtselector(KTEXT32_DES), $now_in_prot |
no_long_mode: |
1: |
jmp 1b |
.code32 |
.align 4 |
multiboot_header: |
78,11 → 88,11 |
.long MULTIBOOT_HEADER_MAGIC |
.long MULTIBOOT_HEADER_FLAGS |
.long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS) # checksum |
.long multiboot_header |
.long unmapped_ktext_start |
.long multiboot_header + BOOT_OFFSET |
.long unmapped_ktext_start + BOOT_OFFSET |
.long 0 |
.long 0 |
.long multiboot_image_start |
.long multiboot_image_start + BOOT_OFFSET |
multiboot_image_start: |
movl $START_STACK, %esp # initialize stack pointer |
99,39 → 109,44 |
jmpl $gdtselector(KTEXT_DES), $multiboot_meeting_point + BOOT_OFFSET |
multiboot_meeting_point: |
# Protected 32-bit. We want to reuse the code-seg descriptor, |
# the Default operand size must not be 1 when entering long mode |
hlt |
# Protected 32-bit. We want to reuse the code-seg descriptor, |
# the Default operand size must not be 1 when entering long mode |
now_in_prot: |
# Set up stack & data descriptors |
movw $gdtselector(KDATA_DES), %ax |
movw %ax, %ds |
movw %ax, %ss |
movb $0xd1, %al # enable A20 using the keyboard controller |
outb %al, $0x64 |
movb $0xdf, %al |
outb %al, $0x60 |
pushl %ebx # save parameters from GRUB |
pushl %eax |
# Enable 64-bit page transaltion entries - CR4.PAE = 1. |
# Paging is not enabled until after long mode is enabled |
movl %cr4, %eax |
btsl $5, %eax |
movl %eax, %cr4 |
# Set up paging tables |
leal ptl_0, %eax |
movl %eax, %cr3 |
# Enable long mode |
movl $EFER_MSR_NUM, %ecx # EFER MSR number |
rdmsr # Read EFER |
btsl $AMD_LME_FLAG, %eax # Set LME=1 |
wrmsr # Write EFER |
movl $EFER_MSR_NUM, %ecx # EFER MSR number |
rdmsr # Read EFER |
btsl $AMD_LME_FLAG, %eax # Set LME=1 |
wrmsr # Write EFER |
# Enable paging to activate long mode (set CR0.PG=1) |
movl %cr0, %eax |
btsl $31, %eax |
movl %eax, %cr0 |
# At this point we are in compatibility mode |
jmpl $gdtselector(KTEXT_DES), $start64 |
.code64 |
138,10 → 153,16 |
start64: |
movq $(PA2KA(START_STACK)), %rsp |
# Copy kernel to higher physical memory |
movq $BOOTSTRAP_OFFSET, %rsi |
movq $BOOTSTRAP_OFFSET + BOOT_OFFSET, %rdi |
movq $_hardcoded_kernel_size, %rcx |
cld |
rep movsb |
call main_bsp # never returns |
cli |
hlt |
1: |
jmp 1b |
.section K_DATA_START, "aw", @progbits |
.align 4096 |
197,6 → 218,11 |
.fill 510,8,0 |
.quad ptl_1 + (PTL_WRITABLE | PTL_PRESENT) |
.global real_bootstrap_gdtr_boot |
real_bootstrap_gdtr_boot: |
.word gdtselector(GDT_ITEMS) |
.long KA2PA(gdt)-BOOT_OFFSET |
.global protected_bootstrap_gdtr |
protected_bootstrap_gdtr: |
.word gdtselector(GDT_ITEMS) |
/kernel/trunk/arch/amd64/src/boot/memmap.S |
---|
0,0 → 1,115 |
/* |
* Copyright (C) 2005 Josef Cejka |
* 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/memmap.h> |
E820_SMAP = 0x534d4150 |
.global memmap_arch_init |
.global e801memorysize |
.code16 |
.section K_TEXT_START_2, "ax" |
memmap_arch_init: |
e820begin: |
xorl %ebx,%ebx # during first call, ebx must be 0 |
movw $e820table_boot,%di |
movb $MEMMAP_E820_MAX_RECORDS,e820counter_boot |
e820loop: |
movl $E820_SMAP,%edx # control sequence "SMAP" |
movl $0x0000e820,%eax # service |
movl $MEMMAP_E820_RECORD_SIZE,%ecx |
int $0x15 |
jc e820err |
cmpl $E820_SMAP,%eax # verifying BIOS |
jne e820err |
cmpl $MEMMAP_E820_RECORD_SIZE,%ecx |
jne e820err # bad record size - bug in bios |
movw %di,%ax # next record |
addw $MEMMAP_E820_RECORD_SIZE,%ax |
movw %ax,%di |
decb e820counter_boot # buffer is full |
jz e820end |
testl %ebx,%ebx |
jnz e820loop |
e820end: |
movb $MEMMAP_E820_MAX_RECORDS,%al |
subb e820counter_boot,%al |
movb %al,e820counter_boot # store # of valid entries in e820counter |
jmp e801begin |
e820err: |
movb $0,e820counter_boot |
# method e801 - get size of memory |
e801begin: |
xorw %dx,%dx |
xorw %cx,%cx |
xorw %bx,%bx |
movw $0xe801,%ax |
stc |
int $0x15 |
jc e801end |
# fix problem with some BIOSes which use ax:bx rather than cx:dx |
testw %cx,%cx |
jnz e801cxdx |
testw %dx,%dx |
jnz e801cxdx |
movw %ax,%cx |
movw %bx,%dx |
e801cxdx: |
andl $0xffff,%edx |
shll $6,%edx |
andl $0xffff,%ecx |
addl %ecx,%edx |
addl $0x0400,%edx # add lower 1 MB - it's not included by e801 method |
movl %edx,e801memorysize |
e801end: |
ret |
.section K_DATA_START, "aw", @progbits |
#memory size in 1 kb chunks |
e801memorysize: |
.long 0 |
/kernel/trunk/arch/amd64/include/boot/memmapasm.h |
---|
0,0 → 1,0 |
link ../../../ia32/include/boot/memmapasm.h |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/kernel/trunk/arch/amd64/include/boot/boot.h |
---|
29,9 → 29,8 |
#ifndef __amd64_BOOT_H__ |
#define __amd64_BOOT_H__ |
#define BOOT_OFFSET 0x108000 |
#define AP_BOOT_OFFSET 0x8000 |
#define BOOT_STACK_SIZE 0x400 |
#define BOOTSTRAP_OFFSET 0x8000 |
#define BOOT_OFFSET 0x100000 |
#define MULTIBOOT_HEADER_MAGIC 0x1BADB002 |
#define MULTIBOOT_HEADER_FLAGS 0x00010003 |
/kernel/trunk/arch/amd64/Makefile.inc |
---|
77,6 → 77,7 |
arch/$(ARCH)/src/dummy.s \ |
arch/$(ARCH)/src/fpu_context.c \ |
arch/$(ARCH)/src/boot/boot.S \ |
arch/$(ARCH)/src/boot/memmap.S \ |
arch/$(ARCH)/src/pm.c \ |
arch/$(ARCH)/src/context.S \ |
arch/$(ARCH)/src/drivers/ega.c \ |
/kernel/trunk/arch/amd64/_link.ld.in |
---|
12,10 → 12,13 |
#include <arch/boot/boot.h> |
#include <arch/mm/page.h> |
ENTRY(kernel_image_start) |
SECTIONS { |
.unmapped BOOT_OFFSET: AT (0) { |
.unmapped BOOTSTRAP_OFFSET: AT (BOOTSTRAP_OFFSET) { |
unmapped_ktext_start = .; |
*(K_TEXT_START); |
*(K_TEXT_START_2); |
unmapped_ktext_end = .; |
unmapped_kdata_start = .; |
23,8 → 26,9 |
unmapped_kdata_end = .; |
} |
.mapped (PA2KA(BOOT_OFFSET)+SIZEOF(.unmapped)) : AT (SIZEOF(.unmapped)) { |
.mapped (PA2KA(BOOT_OFFSET+BOOTSTRAP_OFFSET)+SIZEOF(.unmapped)) : AT (BOOTSTRAP_OFFSET+SIZEOF(.unmapped)) { |
ktext_start = .; |
*(BOOT_DATA); |
*(.text); |
ktext_end = .; |
32,7 → 36,7 |
*(.data); /* initialized data */ |
*(.rodata*); /* string literals */ |
hardcoded_load_address = .; |
QUAD(PA2KA(BOOT_OFFSET)); |
QUAD(PA2KA(BOOT_OFFSET+BOOTSTRAP_OFFSET)); |
hardcoded_ktext_size = .; |
QUAD(ktext_end - ktext_start + (unmapped_ktext_end - unmapped_ktext_start)); |
hardcoded_kdata_size = .; |
52,4 → 56,18 |
kdata_end = .; |
} |
_hardcoded_kernel_size = (ktext_end - ktext_start) + (unmapped_ktext_end - unmapped_ktext_start) + (kdata_end - kdata_start) + (unmapped_kdata_end - unmapped_kdata_start); |
/* Symbols that need to be accessed both from real mode & long mode */ |
/* e820*_boot is real mode (pre-above-1MB-move), e820* is */ |
/* kernel mapped above-1MB-physical copied symbol */ |
e820table_boot = KA2PA(e820table) - BOOT_OFFSET; |
e820counter_boot = KA2PA(e820counter) - BOOT_OFFSET; |
/* real_bootstrap_gdtr is mapped real_bootstrap_gdtr_boot */ |
/* It is physically outside of kernel area, we have to access */ |
/* it after modification from long mode for booting */ |
/* SMP slave processors */ |
real_bootstrap_gdtr = PA2KA(real_bootstrap_gdtr_boot); |
} |
/kernel/trunk/arch/amd64/boot/Makefile |
---|
0,0 → 1,17 |
.PHONY: build clean |
build: boot.bin |
dd if=boot.bin of=../../../image.bin bs=512 conv=sync |
-cat ../../../kernel.bin >> ../../../image.bin |
dd if=/dev/zero of=../../../image.bin bs=1 seek=1474559 count=1 |
boot.bin: boot.o |
$(LD) -T boot.ld -entry _start_0x7c00 --oformat binary boot.o -o $@ |
boot.o: boot.S |
$(CC) -E -DKERNEL_SIZE=$(KERNEL_SIZE) boot.S > boot.s |
$(AS) boot.s -o $@ |
rm boot.s |
clean: |
-rm -f boot.o boot.bin ../../../image.bin |
/kernel/trunk/arch/amd64/boot/boot.ld |
---|
0,0 → 1,4 |
OUTPUT_FORMAT(binary) |
SECTIONS { |
.text 0x7c00 : AT (0x0) { *(.text) } |
} |
/kernel/trunk/arch/amd64/boot/boot.S |
---|
0,0 → 1,151 |
# |
# Copyright (C) 2001-2004 Jakub Jermar |
# 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. |
# |
# This is a very primitive boot.s |
# It assumes that the first sector of the kernel image is found |
# on head 0, track 0, sector 2 of the first floppy drive (1440K). |
# Next kernel sectors follow on disk sector 3, 4, ... |
# |
# KERNEL_SIZE is passed from the outside to the preprocessor |
#if (KERNEL_SIZE%512>0) |
#define TAIL 1 |
#else |
#define TAIL 0 |
#endif |
#define SECTORS (KERNEL_SIZE/512+TAIL) |
.text |
.global _start_0x7c00 |
.code16 |
_start_0x7c00: |
xorw %ax,%ax # reset, %al will be used below |
movw %ax,%dx # fd0, %dh and %dl will be used below |
movw %dx,%ds |
movw %dx,%ss # initialize stack |
movw $stack,%sp |
int $0x13 # reset floppy |
jc stop_trying |
movw %dx,%ds |
movw %dx,%ss |
movw $0x7c00,%sp |
movw $0xffe0,%si # after next increment, %si will become 0x0000 |
movw %si,%es |
movw $0x8000,%bx # at %es:%bx |
movl $(SECTORS),%edi |
read_next: |
test %edi,%edi |
jnz read_sectors |
movb $12,%al |
movw $0x3f2,%dx |
outb %al,%dx |
movb $('$'),%al |
call echo_mark |
jmpl $0,$0x8000 |
read_sectors: |
movb $('.'),%al |
call echo_mark |
decl %edi |
incw logical_sector |
movw %es,%si |
addw $0x20,%si |
movw %si,%es |
movw logical_sector,%ax |
divb sectors |
movb %ah,%cl |
incb %cl # sector |
movb %al,%ch |
shrb $1,%ch # track |
movb %al,%dh |
andb $1,%dh # head |
movw $0x0201,%ax |
int $0x13 |
jnc read_next |
movb $('R'),%al |
call echo_mark |
xorw %ax,%ax # try to reset |
movw %ax,%dx # fd0 |
int $0x13 |
jnc read_next |
stop_trying: |
movb $('F'),%al |
call echo_mark |
cli |
hlt |
CH=4 |
echo_mark: |
push %bp |
movw %sp,%bp |
pusha |
movb $0xe,%ah |
movb $7,%bl |
int $0x10 |
popa |
pop %bp |
ret |
# current logical sector from the beginning of the disk |
logical_sector: |
.word 0 |
# number of sectors per track on 1440 floppy |
sectors: |
.byte 18 |
# boot floppy signature |
.org 0x1fe |
boot_floppy_signature: |
.byte 0x55 |
.byte 0xaa |
stack: |