diff --git a/build.rs b/build.rs index a59e0234..cc5bf99d 100644 --- a/build.rs +++ b/build.rs @@ -11,8 +11,6 @@ fn set_linker_script() { let cfg_feature = env::var("CARGO_CFG_FEATURE").unwrap(); let linker_script = match cfg_target_arch.as_str() { - "aarch64" if cfg_feature.contains("elf") => "link.ld", - "riscv64" if cfg_feature.contains("sbi") => "link.ld", "x86_64" if cfg_feature.contains("multiboot") => "platform/multiboot/link.ld", _ => return, }; diff --git a/src/arch/aarch64/entry.rs b/src/arch/aarch64/entry.rs index e7eb5e28..b429c02f 100644 --- a/src/arch/aarch64/entry.rs +++ b/src/arch/aarch64/entry.rs @@ -8,11 +8,14 @@ use aarch64_cpu::registers::{ use log::info; use tock_registers::fields::{FieldValue, TryFromValue}; +use crate::stack::STACK; + /// Number of virtual address bits for 4KB page const VA_BITS: u64 = 48; global_asm!( include_str!("entry.s"), + BOOT_STACK = sym STACK, start_rust = sym start_rust, ); diff --git a/src/arch/aarch64/entry.s b/src/arch/aarch64/entry.s index 9df42ba3..d27db610 100644 --- a/src/arch/aarch64/entry.s +++ b/src/arch/aarch64/entry.s @@ -16,8 +16,8 @@ _start: // This loads the physical address of the stack end. For details see // https://github.com/rust-embedded/rust-raspberrypi-OS-tutorials/blob/master/16_virtual_mem_part4_higher_half_kernel/src/bsp/raspberrypi/link.ld - adrp x4, __boot_core_stack_end_exclusive - add x4, x4, #:lo12:__boot_core_stack_end_exclusive + adrp x4, {BOOT_STACK} + add x4, x4, #:lo12:{BOOT_STACK} mov sp, x4 // Set correct Exception level! diff --git a/src/arch/aarch64/link.ld b/src/arch/aarch64/link.ld deleted file mode 100644 index aa033221..00000000 --- a/src/arch/aarch64/link.ld +++ /dev/null @@ -1,49 +0,0 @@ -/* Parts of this linker script are directly taken from Andre Richters Project: - * https://github.com/rust-embedded/rust-raspberrypi-OS-tutorials/blob/master/16_virtual_mem_part4_higher_half_kernel/src/bsp/raspberrypi/link.ld -*/ - -ENTRY(_start) -phys = 0x40400000; - -PHDRS -{ - segment_ro PT_LOAD FLAGS(4); /* 4 == RO */ - segment_rx PT_LOAD FLAGS(5); /* 5 == RX */ - segment_rw PT_LOAD FLAGS(6); /* 6 == RW */ -} - -SECTIONS -{ - . = phys; - __executable_start = .; - .text : { - *(.text) - *(.text.*) - } :segment_rx - .rodata : ALIGN(8) { - *(.rodata) - *(.rodata.*) - } :segment_ro - .got : ALIGN(8) { - /* Global offset table Todo */ - *(.got) - } :segment_ro - .data : ALIGN(8) { - *(.data) - *(.data.*) - } :segment_rw - .bss : ALIGN(8) { - *(.bss) - *(.bss.*) - } :segment_rw - . = ALIGN(4K); /* Align to page boundary */ - /*********************************************************************************************** - * Boot Core Stack - ***********************************************************************************************/ - __boot_core_stack_start = .; /* ^ */ - /* | stack */ - . += 16K; /* | growth */ - /* | direction */ - __boot_core_stack_end_exclusive = .; /* | */ - _end = .; -} diff --git a/src/arch/aarch64/mod.rs b/src/arch/aarch64/mod.rs index 98bb509e..f188d157 100644 --- a/src/arch/aarch64/mod.rs +++ b/src/arch/aarch64/mod.rs @@ -17,15 +17,13 @@ use hermit_entry::boot_info::{BootInfo, HardwareInfo, PlatformInfo, RawBootInfo, use hermit_entry::elf::LoadedKernel; use log::info; -use crate::BootInfoExt; use crate::arch::paging::*; use crate::fdt_ext::FdtExt; use crate::os::CONSOLE; +use crate::{BootInfoExt, stack}; /// start address of the RAM at Qemu's virt emulation const RAM_START: u64 = 0x40000000; -/// Default stack size of the kernel -const KERNEL_STACK_SIZE: usize = 32_768; /// Qemu assumes for ELF kernel that the fdt is located at /// start of RAM (0x4000_0000) /// see @@ -102,8 +100,7 @@ pub unsafe fn boot_kernel(kernel_info: LoadedKernel) -> ! { platform_info: PlatformInfo::LinuxBoot, }; - let stack = boot_info.load_info.kernel_image_addr_range.start as usize - KERNEL_STACK_SIZE; - let stack = ptr::with_exposed_provenance_mut(stack); + let stack = stack::get_stack_ptr(); let entry = ptr::with_exposed_provenance(entry_point.try_into().unwrap()); let raw_boot_info = boot_info.write(); diff --git a/src/arch/riscv64/link.ld b/src/arch/riscv64/link.ld deleted file mode 100644 index 8d3f17bc..00000000 --- a/src/arch/riscv64/link.ld +++ /dev/null @@ -1,11 +0,0 @@ -SECTIONS { - __executable_start = ADDR (.text.start); - - .text.start 0x80200000 : { *(.text._start) } - .text : { *(.text.*) } - .rodata : { *(.rodata.*) } - .data : { *(.data.*) } - .bss : { *(.bss.*) } - - _end = .; -} diff --git a/src/arch/riscv64/mod.rs b/src/arch/riscv64/mod.rs index 9eb61b78..0f9929cf 100644 --- a/src/arch/riscv64/mod.rs +++ b/src/arch/riscv64/mod.rs @@ -14,8 +14,8 @@ use hermit_entry::boot_info::{ use hermit_entry::elf::LoadedKernel; use log::info; -use crate::BootInfoExt; use crate::fdt_ext::FdtExt; +use crate::{BootInfoExt, stack}; pub fn find_kernel() -> &'static [u8] { let fdt = start::get_fdt(); @@ -92,7 +92,7 @@ pub unsafe fn boot_kernel(kernel_info: LoadedKernel) -> ! { platform_info: PlatformInfo::LinuxBoot, }; - let stack = start::get_stack_ptr(); + let stack = stack::get_stack_ptr(); let entry = ptr::with_exposed_provenance(entry_point.try_into().unwrap()); let hart_id = start::get_hart_id(); let raw_boot_info = boot_info.write(); diff --git a/src/arch/riscv64/start.rs b/src/arch/riscv64/start.rs index 98584fce..44148a7f 100644 --- a/src/arch/riscv64/start.rs +++ b/src/arch/riscv64/start.rs @@ -3,7 +3,8 @@ use core::sync::atomic::{AtomicPtr, AtomicUsize, Ordering}; use fdt::Fdt; -static mut STACK: Stack = Stack::new(); +use crate::stack::{STACK, Stack}; + static HART_ID: AtomicUsize = AtomicUsize::new(0); static FDT: AtomicPtr = AtomicPtr::new(ptr::null_mut()); @@ -20,29 +21,24 @@ pub fn get_fdt() -> Fdt<'static> { unsafe { Fdt::from_ptr(get_fdt_ptr()).unwrap() } } -pub fn get_stack_ptr() -> *mut u8 { - let stack_top = &raw mut STACK; - // SAFETY: Pointing directly past the object is allowed - let stack_bottom = unsafe { stack_top.add(1) }; - stack_bottom.cast::() -} - // TODO: Migrate to Constrained Naked Functions once stabilized // https://github.com/rust-lang/rust/issues/90957 // TODO: Migrate to asm_const for Stack::SIZE once stabilized // https://github.com/rust-lang/rust/issues/93332 #[no_mangle] #[naked_function::naked] +#[link_section = ".init"] pub unsafe extern "C" fn _start(hart_id: usize, fdt: *const u8) -> ! { asm!( // Initialize stack "la sp, {BOOT_STACK}", - "li t0, 0x8000", + "li t0, {STACK_SIZE}", "add sp, sp, t0", "j {start}", BOOT_STACK = sym STACK, + STACK_SIZE = const Stack::SIZE, start = sym start, ) } @@ -54,15 +50,3 @@ extern "C" fn start(hart_id: usize, fdt: *const u8) -> ! { unsafe { crate::os::loader_main() } } - -// Align to page size -#[repr(C, align(0x1000))] -pub struct Stack([u8; Self::SIZE]); - -impl Stack { - const SIZE: usize = 0x8000; - - pub const fn new() -> Self { - Self([0; Self::SIZE]) - } -} diff --git a/src/main.rs b/src/main.rs index 620209af..02ebf541 100644 --- a/src/main.rs +++ b/src/main.rs @@ -19,6 +19,8 @@ mod fdt; mod fdt_ext; mod log; mod os; +#[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))] +mod stack; #[cfg(any(target_os = "uefi", all(target_arch = "x86_64", target_os = "none")))] extern crate alloc; diff --git a/src/stack.rs b/src/stack.rs new file mode 100644 index 00000000..f991bc3d --- /dev/null +++ b/src/stack.rs @@ -0,0 +1,20 @@ +pub static mut STACK: Stack = Stack::new(); + +// Align to page size +#[repr(C, align(0x1000))] +pub struct Stack([u8; Self::SIZE]); + +impl Stack { + pub const SIZE: usize = 0x8000; + + pub const fn new() -> Self { + Self([0; Self::SIZE]) + } +} + +pub fn get_stack_ptr() -> *mut u8 { + let stack_top = &raw mut STACK; + // SAFETY: Pointing directly past the object is allowed + let stack_bottom = unsafe { stack_top.add(1) }; + stack_bottom.cast::() +} diff --git a/xtask/src/target.rs b/xtask/src/target.rs index 05942344..0cec9abe 100644 --- a/xtask/src/target.rs +++ b/xtask/src/target.rs @@ -75,6 +75,15 @@ impl Target { pub fn rustflags(&self) -> &'static [&'static str] { match self { + Self::Aarch64Elf | Self::Aarch64BeElf => &[ + "-Crelocation-model=static", + "-Clink-arg=--image-base=0x40400000", + ], + Self::Riscv64Sbi => &[ + "-Crelocation-model=static", + "-Clink-arg=--image-base=0x801ffe00", + "-Clink-arg=--section-start=.init=0x80200000", + ], Self::X86_64Linux | Self::X86_64Multiboot => &["-Crelocation-model=static"], _ => &[], }