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:
wilkie
2009-03-23 08:04:02 +08:00
committed by The XOmB Overlord
parent 93f112197d
commit 86a9ca243b
8 changed files with 324 additions and 509 deletions

View File

@@ -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

View File

@@ -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

View 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

View 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

View File

@@ -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

View 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

View File

@@ -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 */

View File

@@ -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 = .;
}