mirror of
https://github.com/xomboverlord/xomb-bare-bones.git
synced 2026-01-11 18:33:15 +01:00
I have added new assembly files that will compile under YASM or NASM assemblers. Note: They are now in Intel syntax for great good. They will match the Intel syntax used by LDC.
Signed-off-by: The XOmB Overlord <overlord@xomb.net>
This commit is contained in:
committed by
The XOmB Overlord
parent
93f112197d
commit
86a9ca243b
@@ -17,28 +17,26 @@ prebuild= \
|
||||
\
|
||||
echo ; \
|
||||
echo Compiling Assembly for target: x86_64 ;\
|
||||
echo '--> boot.S';\
|
||||
gcc -nostdlib -nodefaultlibs -g -DUSE_ASSERT -mcmodel=kernel -c ../kernel/arch/x86_64/boot/boot.S -o dsss_objs/G/kernel.arch.x86_64.boot.boot.o ; \
|
||||
echo '--> load.S';\
|
||||
gcc -nostdlib -nodefaultlibs -g -DUSE_ASSERT -mcmodel=kernel -c ../kernel/arch/x86_64/boot/load.S -o dsss_objs/G/kernel.arch.x86_64.boot.load.o ; \
|
||||
#echo '--> trampoline.S';\
|
||||
#x86_64-pc-elf-gcc -nostdlib -nodefaultlibs -g -DUSE_ASSERT -mcmodel=kernel -c ../kernel/arch/x86_64/boot/trampoline.S -o dsss_objs/G/kernel.arch.x86_64.boot.trampoline.o ;\
|
||||
echo '--> boot.s';\
|
||||
yasm -o dsss_objs/G/kernel.arch.x86_64.boot.boot.o ../kernel/arch/x86_64/boot/boot.s -felf64;\
|
||||
echo '--> load.s';\
|
||||
yasm -o dsss_objs/G/kernel.arch.x86_64.load.load.o ../kernel/arch/x86_64/boot/load.s -felf64;\
|
||||
\
|
||||
\
|
||||
echo ; \
|
||||
echo Compiling Kernel Runtime ; \
|
||||
echo '--> kernel/runtime/object.d';\
|
||||
ldc -nodefaultlib -I.. -I../kernel/runtime/. -c ../kernel/runtime/object.d -ofdsss_objs/G/kernel.runtime.object.o; \
|
||||
ldc -nodefaultlib -I.. -I../kernel/runtime/. -code-model=kernel -c ../kernel/runtime/object.d -ofdsss_objs/G/kernel.runtime.object.o; \
|
||||
echo '--> kernel/runtime/invariant.d';\
|
||||
ldc -nodefaultlib -g -I.. -I../kernel/runtime/. -c ../kernel/runtime/invariant.d -ofdsss_objs/G/kernel.runtime.invariant.o; \
|
||||
ldc -nodefaultlib -g -I.. -I../kernel/runtime/. -code-model=kernel -c ../kernel/runtime/invariant.d -ofdsss_objs/G/kernel.runtime.invariant.o; \
|
||||
echo '--> kernel/runtime/std/typeinfo/*';\
|
||||
ldc -nodefaultlib -g -I.. -I../kernel/runtime/. -c `ls ../kernel/runtime/std/typeinfo/*.d` -oddsss_objs/G/. ;\
|
||||
ldc -nodefaultlib -g -I.. -I../kernel/runtime/. -code-model=kernel -c `ls ../kernel/runtime/std/typeinfo/*.d` -oddsss_objs/G/. ;\
|
||||
echo '--> kernel/runtime/dstubs.d';\
|
||||
ldc -nodefaultlib -g -I.. -I../kernel/runtime/. -c ../kernel/runtime/dstubs.d -ofdsss_objs/G/kernel.runtime.dstubs.o ;\
|
||||
ldc -nodefaultlib -g -I.. -I../kernel/runtime/. -code-model=kernel -c ../kernel/runtime/dstubs.d -ofdsss_objs/G/kernel.runtime.dstubs.o ;\
|
||||
echo '--> kernel/runtime/util.d';\
|
||||
ldc -nodefaultlib -g -I.. -I../kernel/runtime/. -c ../kernel/runtime/util.d -ofdsss_objs/G/kernel.runtime.util.o ;\
|
||||
ldc -nodefaultlib -g -I.. -I../kernel/runtime/. -code-model=kernel -c ../kernel/runtime/util.d -ofdsss_objs/G/kernel.runtime.util.o ;\
|
||||
echo '--> kernel/runtime/std/moduleinit.d';\
|
||||
ldc -nodefaultlib -g -I.. -I../kernel/runtime/. -c ../kernel/runtime/std/moduleinit.d -ofdsss_objs/G/kernel.runtime.std.moduleinit.o ;\
|
||||
ldc -nodefaultlib -g -I.. -I../kernel/runtime/. -code-model=kernel -c ../kernel/runtime/std/moduleinit.d -ofdsss_objs/G/kernel.runtime.std.moduleinit.o ;\
|
||||
\
|
||||
echo ; \
|
||||
echo Compiling Kernel Proper ;
|
||||
@@ -56,7 +54,7 @@ echo Creating Kernel Executable; \
|
||||
echo '--> xomb';\
|
||||
#llvm-ld -native -Xlinker=-nostdlib -Xlinker=-Tlinker.ld -Xlinker="-b elf64-x86-64" `ls dsss_objs/G/*.o` -o iso/boot/xomb ; \
|
||||
#llvm-ld -nodefaultlib -g -I.. -I../kernel/runtime/. `ls dsss_objs/G/*.o` ;\
|
||||
ld -nostdlib -nodefaultlibs -b elf64-x86-64 -T linker.ld -o iso/boot/xomb `ls dsss_objs/G/*.o`;\
|
||||
ld -nostdlib -nodefaultlibs -b elf64-x86-64 -T ../kernel/arch/x86_64/linker.ld -o iso/boot/xomb `ls dsss_objs/G/*.o`;\
|
||||
\
|
||||
echo ;\
|
||||
echo Creating Kernel Dump; \
|
||||
@@ -65,4 +63,4 @@ rm -f xomb.dump && x86_64-pc-elf-objdump -d -S -r iso/boot/xomb > xomb.dump;\
|
||||
\
|
||||
echo ;\
|
||||
echo Compiling ISO; \
|
||||
mkisofs -R -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 16 -boot-info-table -o xomb.iso ./iso
|
||||
mkisofs -R -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 16 -boot-info-table -input-charset UTF-8 -o xomb.iso ./iso
|
||||
|
||||
@@ -1,275 +0,0 @@
|
||||
/*
|
||||
|
||||
boot.S - bootstrap the kernel
|
||||
|
||||
The 32 bit bootstrap code that serves these functions:
|
||||
|
||||
- contains multiboot header
|
||||
- contains 32 bit GDT
|
||||
- contains 32 bit IDT (for debugging, can be removed later)
|
||||
- contains page tables
|
||||
- lower 40MB are mapped 1-1
|
||||
- higher 40MB (from 0xffffffff80000000) are mapped from 0x0 on
|
||||
- after code in load.S runs, the lower half map should not be needed
|
||||
|
||||
- transitions into long mode:
|
||||
- enables PAE (physical-address-extensions)
|
||||
- setting PML4 (page-map-level-4)
|
||||
- setting EFER flags for LMA (long-mode-active) and SYSCALL-SYSRET
|
||||
- enables paging by setting the PG bit in CR0 (Control Register 0)
|
||||
- long jumps to code within load.S
|
||||
|
||||
- note: some addresses located within the higher half need to be converted
|
||||
to linear addresses: the stack, _edata, _end
|
||||
- this is because: the multiboot header expects linear addresses,
|
||||
the CPU expects stack at linear address, as it would for GDT, IDT, etc
|
||||
|
||||
*/
|
||||
|
||||
#define EXE_COMPAT_HACK
|
||||
|
||||
#define ASM 1
|
||||
#include "multiboot.h"
|
||||
|
||||
#include "boot.h"
|
||||
|
||||
.globl start, _start
|
||||
|
||||
.text
|
||||
|
||||
start:
|
||||
_start:
|
||||
.code32
|
||||
|
||||
/* Stash values for multiboot we won't touch until 64 bit mode */
|
||||
movl %ebx, %esi
|
||||
movl %eax, %edi
|
||||
|
||||
/* jump to the 32 bit common start */
|
||||
jmp (start32)
|
||||
|
||||
/* Align 32 bits boundary. */
|
||||
.align 4
|
||||
|
||||
/* Multiboot header. */
|
||||
|
||||
multiboot_header:
|
||||
/* magic */
|
||||
.long MULTIBOOT_HEADER_MAGIC
|
||||
/* flags */
|
||||
.long MULTIBOOT_HEADER_FLAGS
|
||||
/* checksum */
|
||||
.long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
|
||||
|
||||
#ifdef EXE_COMPAT_HACK
|
||||
|
||||
/* header_addr */
|
||||
.long (multiboot_header)
|
||||
/* load_addr */
|
||||
.long (_start)
|
||||
/* load_end_addr */
|
||||
.long (_edata-KERNEL_VMA_BASE)
|
||||
/* bss_end_addr */
|
||||
.long (_end-KERNEL_VMA_BASE)
|
||||
/* entry_addr */
|
||||
.long (start)
|
||||
#endif
|
||||
|
||||
.global start32, _start32
|
||||
|
||||
_start32:
|
||||
start32:
|
||||
|
||||
/* disable interrupts (CLear Interrupt flag) */
|
||||
cli
|
||||
|
||||
/* enable 64-bit page-translation-table entries by
|
||||
setting CR4.PAE=1. Paging not enabled until after
|
||||
long mode enabled */
|
||||
movl %cr4, %eax
|
||||
bts $5, %eax
|
||||
movl %eax, %cr4
|
||||
|
||||
/* Create long mode page table and init CR3 to point to
|
||||
the base of the PML4 page table. */
|
||||
movl $(pml4_base), %eax
|
||||
movl %eax, %cr3
|
||||
|
||||
/* Enable Long mode and SYSCALL/SYSRET instructions */
|
||||
movl $0xc0000080, %ecx
|
||||
rdmsr
|
||||
bts $8, %eax
|
||||
bts $0, %eax
|
||||
wrmsr
|
||||
|
||||
/* Load the 32 bit GDT */
|
||||
lgdt (pGDT32)
|
||||
|
||||
/* Load the 32 bit IDT */
|
||||
lidt (pIDT32)
|
||||
|
||||
/* establish a stack for 32 bit code */
|
||||
mov $((stack-KERNEL_VMA_BASE) + STACK_SIZE), %esp
|
||||
|
||||
/* enable paging to activate long mode */
|
||||
movl %cr0, %eax
|
||||
bts $31, %eax
|
||||
movl %eax, %cr0
|
||||
|
||||
// make the jump to long mode!
|
||||
ljmp $CS_KERNEL, $(start64-KERNEL_VMA_BASE)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// The following are a series of kernel structures used by the cpu
|
||||
// These are temporary and will be replaced by permanent ones when the
|
||||
// kernel is executed proper.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// 32 BIT GDT
|
||||
|
||||
.align 4096
|
||||
.globl pGDT32
|
||||
pGDT32:
|
||||
.word GDT_END - GDT_TABLE - 1
|
||||
.quad GDT_TABLE - KERNEL_VMA_BASE
|
||||
|
||||
.align 4096
|
||||
GDT_TABLE:
|
||||
.quad 0x0000000000000000 /* NULL descriptor */
|
||||
.quad 0x00cf9a000000ffff /* __KERNEL32_CS */
|
||||
.quad 0x00af9a000000ffff /* __KERNEL_CS */
|
||||
.quad 0x0000000000000000 /* upper half of CS */
|
||||
.quad 0x00af93000000ffff /* __KERNEL_DS */
|
||||
.quad 0x0000000000000000 /* upper half of DS */
|
||||
.quad 0x00affa000000ffff /* __USER_CS */
|
||||
.quad 0x0000000000000000 /* upper half of CS */
|
||||
.quad 0x00aff3000000ffff /* __USER_DS */
|
||||
.quad 0x0000000000000000 /* upper half of DS */
|
||||
.quad 0,0 /* TSS */
|
||||
.quad 0,0 /* TSS */
|
||||
.quad 0,0 /* LDT */
|
||||
.quad 0,0 /* LDT */
|
||||
|
||||
// wtf?
|
||||
.quad 0,0,0 /* three TLS descriptors */
|
||||
.quad 0x0000f40000000000 /* node/CPU stored in limit */
|
||||
GDT_END:
|
||||
|
||||
|
||||
// 32 BIT IDT
|
||||
|
||||
.align 4096
|
||||
|
||||
|
||||
.globl pIDT32
|
||||
pIDT32:
|
||||
|
||||
|
||||
.word IDT_END - IDT_TABLE - 1
|
||||
.quad IDT_TABLE - KERNEL_VMA_BASE
|
||||
|
||||
#define IDT_LOCATION 0x106000
|
||||
|
||||
.align 4096
|
||||
IDT_TABLE:
|
||||
i = 0
|
||||
.rept 32
|
||||
.long 0x100000 | ((IDT_LOCATION + i) & 0xFFFF)
|
||||
.long ((IDT_LOCATION + i) & 0xFFFF0000) | 0x8E00
|
||||
i = i + 8
|
||||
.endr
|
||||
IDT_END:
|
||||
|
||||
.align 4096
|
||||
|
||||
int_handler_32:
|
||||
|
||||
i = 0
|
||||
.rept 32
|
||||
mov i, %eax
|
||||
iret
|
||||
i = i + 1
|
||||
.endr
|
||||
|
||||
int_handler_32_end:
|
||||
|
||||
.align 4096 // the others may not be needed, but this one MUST BE THERE
|
||||
.globl pml4_base
|
||||
|
||||
// PML4
|
||||
pml4_base:
|
||||
.quad (level3_ident_pgt + 0x0000000000000007)
|
||||
.fill 510,8,0
|
||||
.quad (level3_ident_pgt + 0x0000000000000007)
|
||||
|
||||
|
||||
// --- THIS SHOULD BE ALIGNED AT 4K --- //
|
||||
|
||||
.align 4096
|
||||
.globl level3_ident_pgt
|
||||
// PDP
|
||||
// PML3
|
||||
level3_ident_pgt:
|
||||
.quad (level2_ident_pgt + 0x07)
|
||||
.quad 0 //(level2_ident_pgt + 0x07)
|
||||
.quad (level2_ident_pgt + 0x07)
|
||||
|
||||
.rept (507)
|
||||
.quad 0
|
||||
.endr
|
||||
|
||||
.quad (level2_ident_pgt + 0x07)
|
||||
.quad 0 // (level2_ident_pgt + 0x07)
|
||||
|
||||
|
||||
|
||||
// --- THIS SHOULD BE ALIGNED AT 4K --- //
|
||||
|
||||
|
||||
.align 4096
|
||||
.globl level2_ident_pgt
|
||||
// flags 0x00087
|
||||
// PDE
|
||||
// PML2
|
||||
level2_ident_pgt:
|
||||
i = 0
|
||||
|
||||
// 15 TABLE ENTRIES
|
||||
.rept 15
|
||||
.quad (level1_ident_pgt + i + 0x0000000000000007)
|
||||
i = i + 4096
|
||||
.endr
|
||||
|
||||
.fill 497,8,0
|
||||
|
||||
|
||||
// --- THIS SHOULD BE ALIGNED AT 4K --- //
|
||||
|
||||
|
||||
// PTE
|
||||
// PML1
|
||||
.align 4096
|
||||
.globl level1_ident_pgt
|
||||
level1_ident_pgt:
|
||||
// UM
|
||||
// 40MB for bootup.
|
||||
i = 0
|
||||
|
||||
// 15 TABLES
|
||||
.rept (512 * 15)
|
||||
.quad i << 12 | 0x087
|
||||
i = i + 1
|
||||
.endr
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
163
kernel/arch/x86_64/boot/boot.s
Normal file
163
kernel/arch/x86_64/boot/boot.s
Normal file
@@ -0,0 +1,163 @@
|
||||
; boot.s
|
||||
|
||||
; entry is from bootloader
|
||||
|
||||
section .text
|
||||
bits 32
|
||||
|
||||
%include "defines.mac"
|
||||
|
||||
; externs given by the linker script
|
||||
extern _edata
|
||||
extern _end
|
||||
|
||||
; extern to the load.s
|
||||
extern start64
|
||||
extern stack
|
||||
|
||||
; define the starting point for this module
|
||||
global start
|
||||
global _start
|
||||
start:
|
||||
_start:
|
||||
|
||||
; Stash values for multiboot we won't touch until 64 bit mode
|
||||
mov esi, ebx
|
||||
mov edi, eax
|
||||
|
||||
jmp start32
|
||||
|
||||
; the multiboot header needs to be aligned at
|
||||
; a 32 bit boundary
|
||||
align 4
|
||||
|
||||
multiboot_header:
|
||||
|
||||
dd MULTIBOOT_HEADER_MAGIC
|
||||
dd MULTIBOOT_HEADER_FLAGS
|
||||
dd -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
|
||||
dd multiboot_header
|
||||
dd _start
|
||||
dd (_edata-KERNEL_VMA_BASE)
|
||||
dd (_end-KERNEL_VMA_BASE)
|
||||
dd _start
|
||||
|
||||
; the 32 bit entry
|
||||
global start32
|
||||
start32:
|
||||
|
||||
; disable interrupts
|
||||
cli
|
||||
|
||||
; enable 64-bit page translation table entries
|
||||
; by setting CR4.PAE = 1.
|
||||
;
|
||||
; Paging is not enabled until long mode.
|
||||
mov eax, cr4
|
||||
bts eax, 5
|
||||
mov cr4, eax
|
||||
|
||||
; Create long mode page table and init CR3 to
|
||||
; point to the base of the PML4 page table
|
||||
mov eax, pml4_base
|
||||
mov cr3, eax
|
||||
|
||||
; Enable Long mode and SYSCALL / SYSRET instructions
|
||||
mov ecx, 0xC0000080
|
||||
rdmsr
|
||||
bts eax, 8
|
||||
bts eax, 0
|
||||
wrmsr
|
||||
|
||||
; Load the 32 bit GDT
|
||||
lgdt [pGDT32]
|
||||
|
||||
; Load the 32 bit IDT
|
||||
; lidt [pIDT32]
|
||||
|
||||
; establish a stack for 32 bit code
|
||||
mov esp, (stack-KERNEL_VMA_BASE) + STACK_SIZE
|
||||
|
||||
; enable paging to activate long mode
|
||||
mov eax, cr0
|
||||
bts eax, 31
|
||||
mov cr0, eax
|
||||
|
||||
jmp CS_KERNEL:(start64-KERNEL_VMA_BASE)
|
||||
|
||||
bits 64
|
||||
code64Jump:
|
||||
jmp (start64-KERNEL_VMA_BASE)
|
||||
|
||||
|
||||
|
||||
|
||||
; Data Structures Follow
|
||||
bits 32
|
||||
|
||||
; 32 bit gdt
|
||||
|
||||
align 4096
|
||||
|
||||
pGDT32:
|
||||
dw GDT_END - GDT_TABLE - 1
|
||||
dq GDT_TABLE - KERNEL_VMA_BASE
|
||||
|
||||
GDT_TABLE:
|
||||
|
||||
dq 0x0000000000000000 ; Null Descriptor
|
||||
dq 0x00cf9a000000ffff ; CS_KERNEL32
|
||||
dq 0x00af9a000000ffff,0 ; CS_KERNEL
|
||||
dq 0x00af93000000ffff,0 ; DS_KERNEL
|
||||
dq 0x00affa000000ffff,0 ; CS_USER
|
||||
dq 0x00aff3000000ffff,0 ; DS_USER
|
||||
dq 0,0 ;
|
||||
dq 0,0 ;
|
||||
dq 0,0 ;
|
||||
dq 0,0 ;
|
||||
|
||||
dq 0,0,0 ; Three TLS descriptors
|
||||
dq 0x0000f40000000000 ;
|
||||
|
||||
GDT_END:
|
||||
|
||||
|
||||
|
||||
|
||||
; Temporary page tables
|
||||
|
||||
; These assume linking to 0xFFFF800000000000
|
||||
align 4096
|
||||
pml4_base:
|
||||
dq (pml3_base + 0x7)
|
||||
times 255 dq 0
|
||||
dq (pml3_base + 0x7)
|
||||
times 255 dq 0
|
||||
|
||||
align 4096
|
||||
pml3_base:
|
||||
dq (pml2_base + 0x7)
|
||||
times 511 dq 0
|
||||
|
||||
align 4096
|
||||
pml2_base:
|
||||
%assign i 0
|
||||
%rep 25
|
||||
dq (pml1_base + i + 0x7)
|
||||
%assign i i+4096
|
||||
%endrep
|
||||
|
||||
times (512-25) dq 0
|
||||
|
||||
align 4096
|
||||
; 15 tables are described here
|
||||
; this maps 40 MB from address 0x0
|
||||
; to an identity mapping
|
||||
pml1_base:
|
||||
%assign i 0
|
||||
%rep 512*25
|
||||
dq (i << 12) | 0x087
|
||||
%assign i i+1
|
||||
%endrep
|
||||
|
||||
|
||||
17
kernel/arch/x86_64/boot/defines.mac
Normal file
17
kernel/arch/x86_64/boot/defines.mac
Normal file
@@ -0,0 +1,17 @@
|
||||
; multiboot definitions
|
||||
%define MULTIBOOT_HEADER_MAGIC 0x1BADB002
|
||||
%define MULTIBOOT_HEADER_FLAGS 0x00010003
|
||||
|
||||
; where is the kernel?
|
||||
%define KERNEL_VMA_BASE 0xFFFF800000000000
|
||||
%define KERNEL_LMA_BASE 0x100000
|
||||
|
||||
; the gdt entry to use for the kernel
|
||||
%define CS_KERNEL 0x10
|
||||
%define CS_KERNEL32 0x08
|
||||
|
||||
; other definitions
|
||||
|
||||
%define STACK_SIZE 0x4000
|
||||
|
||||
|
||||
@@ -1,94 +0,0 @@
|
||||
/*
|
||||
|
||||
load.S
|
||||
|
||||
The 64 bit code that serves these functions:
|
||||
|
||||
- sets up stack
|
||||
- transfers %rip to higher half
|
||||
- clears cpu flags
|
||||
- calls kmain with multiboot information
|
||||
|
||||
*/
|
||||
|
||||
#define ASM 1
|
||||
|
||||
#include "multiboot.h"
|
||||
#include "boot.h"
|
||||
|
||||
|
||||
.text
|
||||
.code64
|
||||
|
||||
.globl start64, _start64
|
||||
|
||||
start64:
|
||||
_start64:
|
||||
|
||||
|
||||
/* Initialize the 64 bit stack pointer. */
|
||||
movq $((stack - KERNEL_VMA_BASE) + STACK_SIZE), %rsp
|
||||
|
||||
/* set up the stack for the return */
|
||||
pushq $CS_KERNEL
|
||||
pushq $long_entry
|
||||
|
||||
/* Go into canonical higher half */
|
||||
/* This trick is borrowed from the linux kernel,
|
||||
/arch/x86_64/kernel/head.S */
|
||||
|
||||
lretq
|
||||
|
||||
long_entry:
|
||||
|
||||
/* From here on out, we are running instructions
|
||||
Within the higher half (0xffffffff80000000 ... )
|
||||
|
||||
We can safely unmap the lower half, we do not
|
||||
need an identity mapping of the lower half. */
|
||||
|
||||
movq $(stack + STACK_SIZE), %rsp
|
||||
|
||||
/* Set cpu flags */
|
||||
pushq $0
|
||||
lss (%rsp), %eax
|
||||
popf
|
||||
|
||||
/* Sets the Input/Output Permission Level to 3, so
|
||||
that it will not check the IO permissions bitmap when access is requested. */
|
||||
|
||||
pushf
|
||||
popq %rax
|
||||
or $0x3000, %rax
|
||||
pushq %rax
|
||||
popf
|
||||
|
||||
addq $(KERNEL_VMA_BASE), %rsi
|
||||
|
||||
/* Push the pointer to the Multiboot information structure. */
|
||||
pushq %rsi
|
||||
/* Push the magic value. */
|
||||
pushq %rdi
|
||||
|
||||
/* Now enter the kmain function... */
|
||||
call EXT_C(kmain)
|
||||
|
||||
|
||||
|
||||
/* We should not get here */
|
||||
|
||||
loop:
|
||||
|
||||
hlt
|
||||
jmp loop
|
||||
|
||||
// --- STACK --- //
|
||||
.globl stack
|
||||
.align 4096
|
||||
|
||||
// Our stack area.
|
||||
stack:
|
||||
.rept STACK_SIZE
|
||||
.long 0
|
||||
.endr
|
||||
|
||||
101
kernel/arch/x86_64/boot/load.s
Normal file
101
kernel/arch/x86_64/boot/load.s
Normal file
@@ -0,0 +1,101 @@
|
||||
; load.s
|
||||
|
||||
; entry is from boot.s
|
||||
|
||||
bits 64
|
||||
|
||||
; Everywhere you see some weird addition logic
|
||||
; This is to fit the addresses into 32 bit sizes
|
||||
; Note, they will sign extend!
|
||||
|
||||
section .text
|
||||
|
||||
; include useful definitions
|
||||
%include "defines.mac"
|
||||
|
||||
; extern to kmain.d
|
||||
extern kmain
|
||||
|
||||
global start64
|
||||
|
||||
start64:
|
||||
|
||||
; Initialize the 64 bit stack pointer.
|
||||
mov rsp, ((stack - KERNEL_VMA_BASE) + STACK_SIZE)
|
||||
|
||||
; Set up the stack for the return.
|
||||
push CS_KERNEL
|
||||
|
||||
; RAX - the address to return to
|
||||
mov rax, KERNEL_VMA_BASE >> 32
|
||||
shl rax, 32
|
||||
or rax, long_entry - (KERNEL_VMA_BASE & 0xffffffff00000000)
|
||||
push rax
|
||||
|
||||
; Go into canonical higher half
|
||||
; It uses a trick to update the program counter
|
||||
; across a 64 bit address space
|
||||
ret
|
||||
|
||||
long_entry:
|
||||
|
||||
; From here on out, we are running instructions
|
||||
; within the higher half (0xffffffff80000000 ... )
|
||||
|
||||
; We can safely upmap the lower half, we do not
|
||||
; need an identity mapping of this region
|
||||
|
||||
; set up a 64 bit virtual stack
|
||||
mov rax, KERNEL_VMA_BASE >> 32
|
||||
shl rax, 32
|
||||
or rax, stack - (KERNEL_VMA_BASE & 0xffffffff00000000)
|
||||
mov rsp, rax
|
||||
|
||||
; set cpu flags
|
||||
push 0
|
||||
lss eax, [rsp]
|
||||
popf
|
||||
|
||||
; set the input/output permission level to 3
|
||||
; it will allow all access
|
||||
|
||||
pushf
|
||||
pop rax
|
||||
or rax, 0x3000
|
||||
push rax
|
||||
popf
|
||||
|
||||
; update the multiboot struct to point to a
|
||||
; virtual address
|
||||
add rsi, (KERNEL_VMA_BASE & 0xffffffff)
|
||||
|
||||
; push the parameters (just in case)
|
||||
push rsi
|
||||
push rdi
|
||||
|
||||
; call kmain
|
||||
call kmain
|
||||
|
||||
|
||||
|
||||
; we should not get here
|
||||
|
||||
haltloop:
|
||||
|
||||
hlt
|
||||
jmp haltloop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
|
||||
|
||||
|
||||
; stack space
|
||||
global stack
|
||||
align 4096
|
||||
|
||||
stack:
|
||||
%rep STACK_SIZE
|
||||
dd 0
|
||||
%endrep
|
||||
|
||||
@@ -1,104 +0,0 @@
|
||||
/* multiboot.h - the header for Multiboot */
|
||||
|
||||
/* Macros. */
|
||||
|
||||
/* The magic number for the Multiboot header. */
|
||||
#define MULTIBOOT_HEADER_MAGIC 0x1BADB002
|
||||
|
||||
/* The flags for the Multiboot header. */
|
||||
//#ifdef __ELF__
|
||||
//# define MULTIBOOT_HEADER_FLAGS 0x00000003
|
||||
//#else
|
||||
# define MULTIBOOT_HEADER_FLAGS 0x00010003
|
||||
//#endif
|
||||
|
||||
/* The magic number passed by a Multiboot-compliant boot loader. */
|
||||
#define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002
|
||||
|
||||
/* The size of our stack (16KB). */
|
||||
#define STACK_SIZE 0x4000
|
||||
|
||||
/* C symbol format. HAVE_ASM_USCORE is defined by configure. */
|
||||
#ifdef HAVE_ASM_USCORE
|
||||
# define EXT_C(sym) _ ## sym
|
||||
#else
|
||||
# define EXT_C(sym) sym
|
||||
#endif
|
||||
|
||||
#ifndef ASM
|
||||
/* Do not include here in boot.S. */
|
||||
|
||||
/* Types. */
|
||||
|
||||
/* The Multiboot header. */
|
||||
typedef struct multiboot_header
|
||||
{
|
||||
unsigned long magic;
|
||||
unsigned long flags;
|
||||
unsigned long checksum;
|
||||
unsigned long header_addr;
|
||||
unsigned long load_addr;
|
||||
unsigned long load_end_addr;
|
||||
unsigned long bss_end_addr;
|
||||
unsigned long entry_addr;
|
||||
} multiboot_header_t;
|
||||
|
||||
/* The symbol table for a.out. */
|
||||
typedef struct aout_symbol_table
|
||||
{
|
||||
unsigned long tabsize;
|
||||
unsigned long strsize;
|
||||
unsigned long addr;
|
||||
unsigned long reserved;
|
||||
} aout_symbol_table_t;
|
||||
|
||||
/* The section header table for ELF. */
|
||||
typedef struct elf_section_header_table
|
||||
{
|
||||
unsigned long num;
|
||||
unsigned long size;
|
||||
unsigned long addr;
|
||||
unsigned long shndx;
|
||||
} elf_section_header_table_t;
|
||||
|
||||
/* The Multiboot information. */
|
||||
typedef struct multiboot_info
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned long mem_lower;
|
||||
unsigned long mem_upper;
|
||||
unsigned long boot_device;
|
||||
unsigned long cmdline;
|
||||
unsigned long mods_count;
|
||||
unsigned long mods_addr;
|
||||
union
|
||||
{
|
||||
aout_symbol_table_t aout_sym;
|
||||
elf_section_header_table_t elf_sec;
|
||||
} u;
|
||||
unsigned long mmap_length;
|
||||
unsigned long mmap_addr;
|
||||
} multiboot_info_t;
|
||||
|
||||
/* The module structure. */
|
||||
typedef struct module
|
||||
{
|
||||
unsigned long mod_start;
|
||||
unsigned long mod_end;
|
||||
unsigned long string;
|
||||
unsigned long reserved;
|
||||
} module_t;
|
||||
|
||||
/* The memory map. Be careful that the offset 0 is base_addr_low
|
||||
but no size. */
|
||||
typedef struct memory_map
|
||||
{
|
||||
unsigned long size;
|
||||
unsigned long base_addr_low;
|
||||
unsigned long base_addr_high;
|
||||
unsigned long length_low;
|
||||
unsigned long length_high;
|
||||
unsigned long type;
|
||||
} memory_map_t;
|
||||
|
||||
#endif /* ! ASM */
|
||||
@@ -1,23 +1,23 @@
|
||||
/*
|
||||
linker.ld
|
||||
|
||||
* This script is given as the only script to the linker
|
||||
* Will map boot.S to LMA, and then everything else
|
||||
will be linked to the VMA and mapped at the LMA
|
||||
* _etext, _edata, _end are defined here
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/* KERNEL LINK LOCATIONS
|
||||
|
||||
these are the locations to map to
|
||||
they need to be set within boot.h
|
||||
as well
|
||||
|
||||
* linker.ld
|
||||
*
|
||||
* This script is given as the only script to the linker
|
||||
* Will map boot.S to LMA, and then everything else
|
||||
* will be linked to the VMA and mapped at the LMA
|
||||
* _etext, _edata, _end are defined here
|
||||
*
|
||||
*/
|
||||
|
||||
kernel_VMA = 0xffffffff80000000;
|
||||
/*
|
||||
* KERNEL LINK LOCATIONS
|
||||
*
|
||||
* these are the locations to map to
|
||||
* they need to be set within boot.h
|
||||
* as well
|
||||
*
|
||||
*/
|
||||
|
||||
kernel_VMA = 0xffff800000000000;
|
||||
kernel_LMA = 0x100000;
|
||||
|
||||
/* start from the entry point */
|
||||
@@ -29,6 +29,8 @@ SECTIONS
|
||||
|
||||
_boot = .;
|
||||
|
||||
_kernelLMA = .;
|
||||
|
||||
/* boot.S is ran in linear addresses */
|
||||
.text_boot :
|
||||
{
|
||||
@@ -55,8 +57,8 @@ SECTIONS
|
||||
|
||||
_text = .;
|
||||
|
||||
PROVIDE(_kernel = .);
|
||||
PROVIDE(_kernelBase = kernel_VMA);
|
||||
_kernel = .;
|
||||
_kernelVMA = kernel_VMA;
|
||||
|
||||
/* the rest of the code links to higher memory */
|
||||
.text : AT(ADDR(.text) - kernel_VMA + kernel_LMA)
|
||||
@@ -72,10 +74,10 @@ SECTIONS
|
||||
. = ALIGN(4096);
|
||||
}
|
||||
|
||||
PROVIDE(_ekernel = .);
|
||||
/*PROVIDE(_ekernel = .);*/
|
||||
|
||||
/* _etext defined */
|
||||
PROVIDE (_etext = .);
|
||||
_etext = .; PROVIDE(etext = .);
|
||||
|
||||
_data = .;
|
||||
|
||||
@@ -102,6 +104,8 @@ SECTIONS
|
||||
/* _edata defined */
|
||||
_edata = .; PROVIDE (edata = .);
|
||||
|
||||
_bss = .;
|
||||
|
||||
/* static code */
|
||||
.bss : AT(ADDR(.bss) - kernel_VMA + kernel_LMA)
|
||||
{
|
||||
@@ -109,6 +113,8 @@ SECTIONS
|
||||
. = ALIGN(4096);
|
||||
}
|
||||
|
||||
_ebss = .;
|
||||
|
||||
/* */
|
||||
.ehframe : AT(ADDR(.ehframe) - kernel_VMA + kernel_LMA)
|
||||
{
|
||||
@@ -117,9 +123,12 @@ SECTIONS
|
||||
. = ALIGN(4096);
|
||||
}
|
||||
|
||||
/* _end defined */
|
||||
|
||||
/* _end defined (for posterity and tradition) */
|
||||
_end = .; PROVIDE (end = .);
|
||||
|
||||
_ekernel = .;
|
||||
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user