diff --git a/Cargo.lock b/Cargo.lock index d32e6b1e..2e8efebf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -101,15 +101,6 @@ version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" -[[package]] -name = "cc" -version = "1.0.84" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f8e7c90afad890484a21653d08b6e209ae34770fb5ee298f9c699fcc1e5c856" -dependencies = [ - "libc", -] - [[package]] name = "cfg-if" version = "1.0.0" @@ -284,7 +275,6 @@ dependencies = [ "aarch64-cpu", "align-address", "allocator-api2", - "cc", "exclusive_cell", "fdt", "goblin 0.8.0", @@ -293,7 +283,6 @@ dependencies = [ "log", "multiboot", "naked-function", - "nasm-rs", "qemu-exit", "riscv", "sbi", @@ -363,12 +352,6 @@ dependencies = [ "syn 2.0.38", ] -[[package]] -name = "nasm-rs" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe4d98d0065f4b1daf164b3eafb11974c94662e5e2396cf03f32d0bb5c17da51" - [[package]] name = "ntapi" version = "0.4.1" diff --git a/Cargo.toml b/Cargo.toml index 389b2989..202706d9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -45,10 +45,6 @@ riscv = "0.11" sbi = "0.2" sptr = "0.3" -[build-dependencies] -cc = "1.0" -nasm-rs = "0.2" - [profile.release] strip = "debuginfo" lto = true diff --git a/build.rs b/build.rs deleted file mode 100644 index dbf79f7f..00000000 --- a/build.rs +++ /dev/null @@ -1,29 +0,0 @@ -use std::env; - -fn main() -> Result<(), String> { - let target_arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap(); - let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap(); - let fc = env::var_os("CARGO_FEATURE_FC").is_some(); - - if target_arch == "x86_64" && target_os == "none" { - let mut nasm = nasm_rs::Build::new(); - - let entry = if fc { - "src/arch/x86_64/entry_fc.asm" - } else { - "src/arch/x86_64/entry.asm" - }; - nasm.file(entry); - let objects = nasm.compile_objects()?; - - let mut cc = cc::Build::new(); - for object in objects { - cc.object(object); - } - cc.compile("entry"); - - println!("cargo:rustc-link-lib=static=entry"); - } - - Ok(()) -} diff --git a/src/arch/x86_64/entry.asm b/src/arch/x86_64/entry.asm deleted file mode 100644 index fd036785..00000000 --- a/src/arch/x86_64/entry.asm +++ /dev/null @@ -1,223 +0,0 @@ -; This is the kernel's entry point. We could either call main here, -; or we can use this to setup the stack or other nice stuff, like -; perhaps setting up the GDT and segments. Please note that interrupts -; are disabled at this point: More on interrupts later! - -[BITS 32] - -%define BOOT_STACK_SIZE 4096 - -extern kernel_start ; defined in linker script -extern kernel_end - -; We use a special name to map this section at the begin of our kernel -; => Multiboot expects its magic number at the beginning of the kernel. -SECTION .mboot - -; This part MUST be 4 byte aligned, so we solve that issue using 'ALIGN 4'. -ALIGN 4 -mboot: - ; Multiboot macros to make a few lines more readable later - MULTIBOOT_PAGE_ALIGN equ (1 << 0) - MULTIBOOT_MEMORY_INFO equ (1 << 1) - MULTIBOOT_HEADER_MAGIC equ 0x1BADB002 - MULTIBOOT_HEADER_FLAGS equ MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO - MULTIBOOT_CHECKSUM equ -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS) - - ; This is the GRUB Multiboot header. A boot signature - dd MULTIBOOT_HEADER_MAGIC - dd MULTIBOOT_HEADER_FLAGS - dd MULTIBOOT_CHECKSUM - dd 0, 0, 0, 0, 0 ; address fields - -ALIGN 4 -; we need already a valid GDT to switch in the 64bit modus -GDT64: ; Global Descriptor Table (64-bit). - .Null: equ $ - GDT64 ; The null descriptor. - dw 0 ; Limit (low). - dw 0 ; Base (low). - db 0 ; Base (middle) - db 0 ; Access. - db 0 ; Granularity. - db 0 ; Base (high). - .Code: equ $ - GDT64 ; The code descriptor. - dw 0 ; Limit (low). - dw 0 ; Base (low). - db 0 ; Base (middle) - db 10011010b ; Access. - db 00100000b ; Granularity. - db 0 ; Base (high). - .Data: equ $ - GDT64 ; The data descriptor. - dw 0 ; Limit (low). - dw 0 ; Base (low). - db 0 ; Base (middle) - db 10010010b ; Access. - db 00000000b ; Granularity. - db 0 ; Base (high). - .Pointer: ; The GDT-pointer. - dw $ - GDT64 - 1 ; Limit. - dq GDT64 ; Base. - -SECTION .text -ALIGN 4 -global _start -_start: - cli ; avoid any interrupt - - ; Initialize stack pointer - mov esp, boot_stack - add esp, BOOT_STACK_SIZE - 16 - - ; Interpret multiboot information - mov DWORD [mb_info], ebx - -; This will set up the x86 control registers: -; Caching and the floating point unit are enabled -; Bootstrap page tables are loaded and page size -; extensions (huge pages) enabled. -cpu_init: - - ; initialize page tables - ; map kernel 1:1 - push edi - push ebx - push ecx - mov ecx, kernel_start - mov ebx, kernel_end - add ebx, 0x1000 -L0: cmp ecx, ebx - jae L1 - mov eax, ecx - and eax, 0xFFFFF000 ; page align lower half - mov edi, eax - shr edi, 9 ; (edi >> 12) * 8 (index for boot_pgt) - add edi, boot_pgt1 - or eax, 0x3 ; set present and writable bits - mov DWORD [edi], eax - add ecx, 0x1000 - jmp L0 -L1: - pop ecx - pop ebx - pop edi - - ; check for long mode - - ; do we have the instruction cpuid? - pushfd - pop eax - mov ecx, eax - xor eax, 1 << 21 - push eax - popfd - pushfd - pop eax - push ecx - popfd - xor eax, ecx - jz Linvalid - - ; cpuid > 0x80000000? - mov eax, 0x80000000 - cpuid - cmp eax, 0x80000001 - jb Linvalid ; It is less, there is no long mode. - - ; do we have a long mode? - mov eax, 0x80000001 - cpuid - test edx, 1 << 29 ; Test if the LM-bit, which is bit 29, is set in the D-register. - jz Linvalid ; They aren't, there is no long mode. - - ; Set CR3 - mov eax, boot_pml4 - ;or eax, (1 << 0) ; set present bit - mov cr3, eax - - ; we need to enable PAE modus - mov eax, cr4 - or eax, 1 << 5 - mov cr4, eax - - ; switch to the compatibility mode (which is part of long mode) - mov ecx, 0xC0000080 - rdmsr - or eax, 1 << 8 - wrmsr - - ; Set CR4 - mov eax, cr4 - and eax, 0xfffbf9ff ; disable SSE - ;or eax, (1 << 7) ; enable PGE - mov cr4, eax - - ; Set CR0 (PM-bit is already set) - mov eax, cr0 - and eax, ~(1 << 2) ; disable FPU emulation - or eax, (1 << 1) ; enable FPU montitoring - and eax, ~(1 << 30) ; enable caching - and eax, ~(1 << 29) ; disable write through caching - and eax, ~(1 << 16) ; allow kernel write access to read-only pages - or eax, (1 << 31) ; enable paging - mov cr0, eax - - lgdt [GDT64.Pointer] ; Load the 64-bit global descriptor table. - jmp GDT64.Code:start64 ; Set the code segment and enter 64-bit long mode. - -; there is no long mode -Linvalid: - jmp $ - - -[BITS 64] -start64: - ; initialize segment registers - mov ax, GDT64.Data - mov ds, ax - mov es, ax - mov ss, ax - xor ax, ax - mov fs, ax - mov gs, ax - cld - ; set default stack pointer - mov rsp, boot_stack - add rsp, BOOT_STACK_SIZE-16 - - ; jump to the boot processors's C code - extern loader_main - jmp loader_main - jmp $ - -SECTION .data - -global mb_info: -ALIGN 8 -mb_info: - DQ 0 - -ALIGN 4096 -global boot_stack -boot_stack: - TIMES (BOOT_STACK_SIZE) DB 0xcd - -; Bootstrap page tables are used during the initialization. -ALIGN 4096 -boot_pml4: - DQ boot_pdpt + 0x3 ; PG_PRESENT | PG_RW - times 510 DQ 0 ; PAGE_MAP_ENTRIES - 2 - DQ boot_pml4 + 0x3 ; PG_PRESENT | PG_RW -boot_pdpt: - DQ boot_pgd + 0x3 ; PG_PRESENT | PG_RW - times 511 DQ 0 ; PAGE_MAP_ENTRIES - 1 -boot_pgd: - DQ boot_pgt1 + 0x3 ; PG_PRESENT | PG_RW - DQ boot_pgt2 + 0x3 ; PG_PRESENT | PG_RW - times 510 DQ 0 ; PAGE_MAP_ENTRIES - 1 -boot_pgt1: - times 512 DQ 0 -boot_pgt2: - times 512 DQ 0 - -; add some hints to the ELF file -SECTION .note.GNU-stack noalloc noexec nowrite progbits diff --git a/src/arch/x86_64/entry.s b/src/arch/x86_64/entry.s new file mode 100644 index 00000000..bf25dbf2 --- /dev/null +++ b/src/arch/x86_64/entry.s @@ -0,0 +1,224 @@ +# This is the kernel's entry point. We could either call main here, +# or we can use this to setup the stack or other nice stuff, like +# perhaps setting up the GDT and segments. Please note that interrupts +# are disabled at this point: More on interrupts later! + +.code32 + +.set BOOT_STACK_SIZE, 4096 + +.extern kernel_start # defined in linker script +.extern kernel_end + +# We use a special name to map this section at the begin of our kernel +# => Multiboot expects its magic number at the beginning of the kernel. +.section .mboot, "a" + +# This part MUST be 4 byte aligned, so we solve that issue using '.align 4'. +.align 4 +.global mboot +mboot: + # Multiboot macros to make a few lines more readable later + .set MULTIBOOT_PAGE_ALIGN , (1 << 0) + .set MULTIBOOT_MEMORY_INFO , (1 << 1) + .set MULTIBOOT_HEADER_MAGIC , 0x1BADB002 + .set MULTIBOOT_HEADER_FLAGS , MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO + .set MULTIBOOT_CHECKSUM , -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS) + + # This is the GRUB Multiboot header. A boot signature + .4byte MULTIBOOT_HEADER_MAGIC + .4byte MULTIBOOT_HEADER_FLAGS + .4byte MULTIBOOT_CHECKSUM + .4byte 0, 0, 0, 0, 0 # address fields + +.align 4 +# we need already a valid GDT to switch in the 64bit modus +GDT64: # Global Descriptor Table (64-bit). +.set GDT64.Null, . - GDT64 # The null descriptor. + .2byte 0 # Limit (low). + .2byte 0 # Base (low). + .byte 0 # Base (middle) + .byte 0 # Access. + .byte 0 # Granularity. + .byte 0 # Base (high). +.set GDT64.Code, . - GDT64 # The code descriptor. + .2byte 0 # Limit (low). + .2byte 0 # Base (low). + .byte 0 # Base (middle) + .byte 0b10011010 # Access. + .byte 0b00100000 # Granularity. + .byte 0 # Base (high). +.set GDT64.Data, . - GDT64 # The data descriptor. + .2byte 0 # Limit (low). + .2byte 0 # Base (low). + .byte 0 # Base (middle) + .byte 0b10010010 # Access. + .byte 0b00000000 # Granularity. + .byte 0 # Base (high). + GDT64.Pointer: # The GDT-pointer. + .2byte . - GDT64 - 1 # Limit. + .8byte GDT64 # Base. + +.section .text +.align 4 +.global _start +_start: + cli # avoid any interrupt + + # Initialize stack pointer + mov esp, OFFSET boot_stack + add esp, BOOT_STACK_SIZE - 16 + + # Interpret multiboot information + mov [mb_info], ebx + +# This will set up the x86 control registers: +# Caching and the floating point unit are enabled +# Bootstrap page tables are loaded and page size +# extensions (huge pages) enabled. +cpu_init: + + # initialize page tables + # map kernel 1:1 + push edi + push ebx + push ecx + mov ecx, OFFSET kernel_start + mov ebx, OFFSET kernel_end + add ebx, 0x1000 +L0: cmp ecx, ebx + jae L1 + mov eax, ecx + and eax, 0xFFFFF000 # page align lower half + mov edi, eax + shr edi, 9 # (edi >> 12) * 8 (index for boot_pgt) + add edi, OFFSET boot_pgt1 + or eax, 0x3 # set present and writable bits + mov [edi], eax + add ecx, 0x1000 + jmp L0 +L1: + pop ecx + pop ebx + pop edi + + # check for long mode + + # do we have the instruction cpuid? + pushfd + pop eax + mov ecx, eax + xor eax, 1 << 21 + push eax + popfd + pushfd + pop eax + push ecx + popfd + xor eax, ecx + jz Linvalid + + # cpuid > 0x80000000? + mov eax, 0x80000000 + cpuid + cmp eax, 0x80000001 + jb Linvalid # It is less, there is no long mode. + + # do we have a long mode? + mov eax, 0x80000001 + cpuid + test edx, 1 << 29 # Test if the LM-bit, which is bit 29, is set in the D-register. + jz Linvalid # They aren't, there is no long mode. + + # Set CR3 + mov eax, OFFSET boot_pml4 + # or eax, (1 << 0) # set present bit + mov cr3, eax + + # we need to enable PAE modus + mov eax, cr4 + or eax, 1 << 5 + mov cr4, eax + + # switch to the compatibility mode (which is part of long mode) + mov ecx, 0xC0000080 + rdmsr + or eax, 1 << 8 + wrmsr + + # Set CR4 + mov eax, cr4 + and eax, 0xfffbf9ff # disable SSE + # or eax, (1 << 7) # enable PGE + mov cr4, eax + + # Set CR0 (PM-bit is already set) + mov eax, cr0 + and eax, ~(1 << 2) # disable FPU emulation + or eax, (1 << 1) # enable FPU montitoring + and eax, ~(1 << 30) # enable caching + and eax, ~(1 << 29) # disable write through caching + and eax, ~(1 << 16) # allow kernel write access to read-only pages + or eax, (1 << 31) # enable paging + mov cr0, eax + + lgdt [GDT64.Pointer] # Load the 64-bit global descriptor table. + # https://github.com/llvm/llvm-project/issues/46048 + .att_syntax prefix + # Set the code segment and enter 64-bit long mode. + ljmp $GDT64.Code, $start64 + .intel_syntax noprefix + +# there is no long mode +Linvalid: + jmp Linvalid + +.code64 +start64: + # initialize segment registers + mov ax, OFFSET GDT64.Data + mov ds, eax + mov es, eax + mov ss, eax + xor ax, ax + mov fs, eax + mov gs, eax + cld + # set default stack pointer + movabs rsp, OFFSET boot_stack + add rsp, BOOT_STACK_SIZE-16 + + # jump to the boot processors's C code + .extern loader_main + jmp loader_main + jmp start64+0x28 + +.section .data + +.global mb_info +.align 8 +mb_info: + .8byte 0 + +.align 4096 +.global boot_stack +boot_stack: + .fill BOOT_STACK_SIZE, 1, 0xcd + +# Bootstrap page tables are used during the initialization. +.align 4096 +boot_pml4: + .8byte boot_pdpt + 0x3 # PG_PRESENT | PG_RW + .fill 510, 8, 0 # PAGE_MAP_ENTRIES - 2 + .8byte boot_pml4 + 0x3 # PG_PRESENT | PG_RW +boot_pdpt: + .8byte boot_pgd + 0x3 # PG_PRESENT | PG_RW + .fill 511, 8, 0 # PAGE_MAP_ENTRIES - 1 +boot_pgd: + .8byte boot_pgt1 + 0x3 # PG_PRESENT | PG_RW + .8byte boot_pgt2 + 0x3 # PG_PRESENT | PG_RW + .fill 510, 8, 0 # PAGE_MAP_ENTRIES - 1 +boot_pgt1: + .fill 512, 8, 0 +boot_pgt2: + .fill 512, 8, 0 diff --git a/src/arch/x86_64/entry_fc.asm b/src/arch/x86_64/entry_fc.asm deleted file mode 100644 index 25c7548c..00000000 --- a/src/arch/x86_64/entry_fc.asm +++ /dev/null @@ -1,164 +0,0 @@ -; This is the kernel's entry point, if Hermit is running with -; FireCracker. FireCracker assumes a 64 bit Linux kernel. - -[BITS 64] - -%define BOOT_STACK_SIZE 4096 - -extern kernel_start ; defined in linker script -extern kernel_end - -; Move entry point at the beginning of the elf file -SECTION .mboot -ALIGN 8 -global _start -_start: - cli ; avoid any interrupt - - ; Initialize stack pointer - mov rsp, boot_stack - add rsp, BOOT_STACK_SIZE - 16 - - mov QWORD [boot_params], rsi - - ; initialize page tables - ; map kernel 1:1 - push rdi - push rbx - push rcx - mov rcx, kernel_start - mov rbx, kernel_end - add rbx, 0x1000 - L0: cmp rcx, rbx - jae L1 - mov rax, rcx - and eax, 0xFFFFF000 ; page align lower half - mov rdi, rax - shr rdi, 9 ; (edi >> 12) * 8 (index for boot_pgt) - add rdi, boot_pgt1 - or rax, 0x3 ; set present and writable bits - mov QWORD [rdi], rax - add rcx, 0x1000 - jmp L0 - L1: - pop rcx - pop rbx - pop rdi - - ; Set CR3 - mov eax, boot_pml4 - ;or eax, (1 << 0) ; set present bit - mov cr3, rax - - ; we need to enable PAE modus - mov rax, cr4 - or eax, 1 << 5 - mov cr4, rax - - ; switch to the compatibility mode (which is part of long mode) - mov ecx, 0xC0000080 - rdmsr - or eax, 1 << 8 - wrmsr - - - ; Set CR4 - mov rax, cr4 - and eax, 0x00000000fffbf9ff ; disable SSE - ;or eax, (1 << 7) ; enable PGE - mov cr4, rax - - ; Set CR0 (PM-bit is already set) - mov rax, cr0 - and rax, ~(1 << 2) ; disable FPU emulation - or eax, (1 << 1) ; enable FPU montitoring - and rax, ~(1 << 30) ; enable caching - and rax, ~(1 << 29) ; disable write through caching - and rax, ~(1 << 16) ; allow kernel write access to read-only pages - or eax, (1 << 31) ; enable paging - mov cr0, rax - - - lgdt [GDT64.Pointer] ; Load the 64-bit global descriptor table. - jmp start64 ; Set the code segment and enter 64-bit long mode. - -SECTION .text -ALIGN 8 -start64: - ; initialize segment registers - mov ax, GDT64.Data - mov ds, ax - mov es, ax - mov ss, ax - xor ax, ax - mov fs, ax - mov gs, ax - cld - ; set default stack pointer - mov rsp, boot_stack - add rsp, BOOT_STACK_SIZE-16 - - ; jump to the boot processors's C code - extern loader_main - jmp loader_main - jmp $ - -SECTION .data -ALIGN 4 -; we need already a valid GDT to switch in the 64bit modus -GDT64: ; Global Descriptor Table (64-bit). - .Null: equ $ - GDT64 ; The null descriptor. - dw 0 ; Limit (low). - dw 0 ; Base (low). - db 0 ; Base (middle) - db 0 ; Access. - db 0 ; Granularity. - db 0 ; Base (high). - .Code: equ $ - GDT64 ; The code descriptor. - dw 0 ; Limit (low). - dw 0 ; Base (low). - db 0 ; Base (middle) - db 10011010b ; Access. - db 00100000b ; Granularity. - db 0 ; Base (high). - .Data: equ $ - GDT64 ; The data descriptor. - dw 0 ; Limit (low). - dw 0 ; Base (low). - db 0 ; Base (middle) - db 10010010b ; Access. - db 00000000b ; Granularity. - db 0 ; Base (high). - .Pointer: ; The GDT-pointer. - dw $ - GDT64 - 1 ; Limit. - dq GDT64 ; Base. - -global boot_params: -ALIGN 8 -boot_params: - DQ 0 - -ALIGN 4096 -global boot_stack -boot_stack: - TIMES (BOOT_STACK_SIZE) DB 0xcd - -; Bootstrap page tables are used during the initialization. -ALIGN 4096 -boot_pml4: - DQ boot_pdpt + 0x3 ; PG_PRESENT | PG_RW - times 510 DQ 0 ; PAGE_MAP_ENTRIES - 2 - DQ boot_pml4 + 0x3 ; PG_PRESENT | PG_RW -boot_pdpt: - DQ boot_pgd + 0x3 ; PG_PRESENT | PG_RW - times 511 DQ 0 ; PAGE_MAP_ENTRIES - 1 -boot_pgd: - DQ boot_pgt1 + 0x3 ; PG_PRESENT | PG_RW - DQ boot_pgt2 + 0x3 ; PG_PRESENT | PG_RW - times 510 DQ 0 ; PAGE_MAP_ENTRIES - 1 -boot_pgt1: - times 512 DQ 0 -boot_pgt2: - times 512 DQ 0 - -; add some hints to the ELF file -SECTION .note.GNU-stack noalloc noexec nowrite progbits \ No newline at end of file diff --git a/src/arch/x86_64/entry_fc.s b/src/arch/x86_64/entry_fc.s new file mode 100644 index 00000000..c46c37c2 --- /dev/null +++ b/src/arch/x86_64/entry_fc.s @@ -0,0 +1,162 @@ +# This is the kernel's entry point, if Hermit is running with +# FireCracker. FireCracker assumes a 64 bit Linux kernel. + +.code64 + +.set BOOT_STACK_SIZE, 4096 + +.extern kernel_start # defined in linker script +.extern kernel_end + +# Move entry point at the beginning of the elf file +.section .mboot, "a" +.align 8 +.global _start +_start: + cli # avoid any interrupt + + # Initialize stack pointer + movabs rsp, OFFSET boot_stack + add rsp, BOOT_STACK_SIZE - 16 + + mov [boot_params], rsi + + # initialize page tables + # map kernel 1:1 + push rdi + push rbx + push rcx + movabs rcx, OFFSET kernel_start + movabs rbx, OFFSET kernel_end + add rbx, 0x1000 + L0: cmp rcx, rbx + jae L1 + mov rax, rcx + and eax, 0xFFFFF000 # page align lower half + mov rdi, rax + shr rdi, 9 # (edi >> 12) * 8 (index for boot_pgt) + add rdi, OFFSET boot_pgt1 + or rax, 0x3 # set present and writable bits + mov [rdi], rax + add rcx, 0x1000 + jmp L0 + L1: + pop rcx + pop rbx + pop rdi + + # Set CR3 + mov eax, OFFSET boot_pml4 + ;or eax, (1 << 0) # set present bit + mov cr3, rax + + # we need to enable PAE modus + mov rax, cr4 + or eax, 1 << 5 + mov cr4, rax + + # switch to the compatibility mode (which is part of long mode) + mov ecx, 0xC0000080 + rdmsr + or eax, 1 << 8 + wrmsr + + + # Set CR4 + mov rax, cr4 + and eax, 0x00000000fffbf9ff # disable SSE + ;or eax, (1 << 7) # enable PGE + mov cr4, rax + + # Set CR0 (PM-bit is already set) + mov rax, cr0 + and rax, ~(1 << 2) # disable FPU emulation + or eax, (1 << 1) # enable FPU montitoring + and rax, ~(1 << 30) # enable caching + and rax, ~(1 << 29) # disable write through caching + and rax, ~(1 << 16) # allow kernel write access to read-only pages + or eax, (1 << 31) # enable paging + mov cr0, rax + + + lgdt [GDT64.Pointer] # Load the 64-bit global descriptor table. + jmp start64 # Set the code segment and enter 64-bit long mode. + +.section .text +.align 8 +start64: + # initialize segment registers + mov ax, OFFSET GDT64.Data + mov ds, ax + mov es, ax + mov ss, ax + xor ax, ax + mov fs, ax + mov gs, ax + cld + # set default stack pointer + movabs rsp, OFFSET boot_stack + add rsp, BOOT_STACK_SIZE-16 + + # jump to the boot processors's C code + .extern loader_main + jmp loader_main +invalid: + jmp invalid + +.section .data +.align 4 +# we need already a valid GDT to switch in the 64bit modus +GDT64: # Global Descriptor Table (64-bit). +.set GDT64.Null, . - GDT64 # The null descriptor. + .2byte 0 # Limit (low). + .2byte 0 # Base (low). + .byte 0 # Base (middle) + .byte 0 # Access. + .byte 0 # Granularity. + .byte 0 # Base (high). +.set GDT64.Code, . - GDT64 # The code descriptor. + .2byte 0 # Limit (low). + .2byte 0 # Base (low). + .byte 0 # Base (middle) + .byte 0b10011010 # Access. + .byte 0b00100000 # Granularity. + .byte 0 # Base (high). +.set GDT64.Data, . - GDT64 # The data descriptor. + .2byte 0 # Limit (low). + .2byte 0 # Base (low). + .byte 0 # Base (middle) + .byte 0b10010010 # Access. + .byte 0b00000000 # Granularity. + .byte 0 # Base (high). + GDT64.Pointer: # The GDT-pointer. + .2byte . - GDT64 - 1 # Limit. + .8byte GDT64 # Base. + +.global boot_params +.align 8 +boot_params: + .8byte 0 + +.align 4096 +.global boot_stack +boot_stack: + .fill BOOT_STACK_SIZE, 1, 0xcd + +# Bootstrap page tables are used during the initialization. +.align 4096 +boot_pml4: + .8byte boot_pdpt + 0x3 # PG_PRESENT | PG_RW + .fill 510, 8, 0 # PAGE_MAP_ENTRIES - 2 + .8byte boot_pml4 + 0x3 # PG_PRESENT | PG_RW +boot_pdpt: + .8byte boot_pgd + 0x3 # PG_PRESENT | PG_RW + .fill 511, 8, 0 # PAGE_MAP_ENTRIES - 1 +boot_pgd: + .8byte boot_pgt1 + 0x3 # PG_PRESENT | PG_RW + .8byte boot_pgt2 + 0x3 # PG_PRESENT | PG_RW + .fill 510, 8, 0 # PAGE_MAP_ENTRIES - 1 +boot_pgt1: + .fill 512, 8, 0 +boot_pgt2: + .fill 512, 8, 0 diff --git a/src/arch/x86_64/mod.rs b/src/arch/x86_64/mod.rs index ebad4280..d33a4f13 100644 --- a/src/arch/x86_64/mod.rs +++ b/src/arch/x86_64/mod.rs @@ -69,6 +69,15 @@ impl MemoryManagement for Mem { } } +#[cfg_attr(not(feature = "fc"), allow(bad_asm_style))] +mod entry { + #[cfg(not(feature = "fc"))] + core::arch::global_asm!(include_str!("entry.s")); + + #[cfg(feature = "fc")] + core::arch::global_asm!(include_str!("entry_fc.s")); +} + // FUNCTIONS pub fn message_output_init() { unsafe { COM1.init() };