From d5fb4b93e1a14d4d8c4fd6d234edd3f3b64df34e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kr=C3=B6ning?= Date: Wed, 3 Apr 2024 14:26:06 +0200 Subject: [PATCH] fix: put raw boot info into take-static MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Kröning --- Cargo.lock | 16 ++++++++ Cargo.toml | 1 + src/arch/aarch64/mod.rs | 34 ++++++++-------- src/arch/riscv64/mod.rs | 78 ++++++++++++++++++------------------- src/arch/x86_64/mod.rs | 86 +++++++++++++++++++++-------------------- 5 files changed, 117 insertions(+), 98 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b093b1c8..53271c19 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -113,6 +113,12 @@ version = "2.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +[[package]] +name = "call-once" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a57a50948117a233b27f9bf73ab74709ab90d245216c4707cc16eea067a50bb" + [[package]] name = "cfg-if" version = "1.0.0" @@ -301,6 +307,7 @@ dependencies = [ "sbi-rt", "spinning_top", "sptr", + "take-static", "uart_16550", "uefi", "uefi-services", @@ -588,6 +595,15 @@ dependencies = [ "windows", ] +[[package]] +name = "take-static" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf67eb0a80961fdb5df5e14b75c5b9fc93bdbf88b00d0260b7eec55041c4fe01" +dependencies = [ + "call-once", +] + [[package]] name = "time" version = "0.3.34" diff --git a/Cargo.toml b/Cargo.toml index 9248ab38..39a6199e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,7 @@ hermit-entry = { version = "0.9", features = ["loader"] } log = "0.4" one-shot-mutex = "0.1" sptr = "0.3" +take-static = "0.1" vm-fdt = { version = "0.3", default-features = false, features = ["alloc"] } [features] diff --git a/src/arch/aarch64/mod.rs b/src/arch/aarch64/mod.rs index 25911b50..800d4c1e 100644 --- a/src/arch/aarch64/mod.rs +++ b/src/arch/aarch64/mod.rs @@ -227,7 +227,12 @@ pub unsafe fn boot_kernel(kernel_info: LoadedKernel) -> ! { } let current_stack_address = load_info.kernel_image_addr_range.start - KERNEL_STACK_SIZE as u64; - pub static mut BOOT_INFO: Option = None; + + take_static::take_static! { + static RAW_BOOT_INFO: Option = None; + } + + let raw_boot_info = RAW_BOOT_INFO.take().unwrap(); let dtb = unsafe { Dtb::from_raw(sptr::from_exposed_addr(DEVICE_TREE as usize)) @@ -246,22 +251,19 @@ pub unsafe fn boot_kernel(kernel_info: LoadedKernel) -> ! { let ram_start = u64::from_be_bytes(start_slice.try_into().unwrap()); let ram_size = u64::from_be_bytes(size_slice.try_into().unwrap()); - let boot_info = { - let boot_info = BootInfo { - hardware_info: HardwareInfo { - phys_addr_range: ram_start..ram_start + ram_size, - serial_port_base: SerialPortBase::new(0x1000), - device_tree: core::num::NonZeroU64::new(DEVICE_TREE), - }, - load_info, - platform_info: PlatformInfo::LinuxBoot, - }; - RawBootInfo::from(boot_info) + let boot_info = BootInfo { + hardware_info: HardwareInfo { + phys_addr_range: ram_start..ram_start + ram_size, + serial_port_base: SerialPortBase::new(0x1000), + device_tree: core::num::NonZeroU64::new(DEVICE_TREE), + }, + load_info, + platform_info: PlatformInfo::LinuxBoot, }; - unsafe { - BOOT_INFO = Some(boot_info); - } + info!("boot_info = {boot_info:#?}"); + *raw_boot_info = Some(RawBootInfo::from(boot_info)); + info!("boot_info at {raw_boot_info:p}"); // Jump to the kernel entry point and provide the Multiboot information to it. info!( @@ -291,7 +293,7 @@ pub unsafe fn boot_kernel(kernel_info: LoadedKernel) -> ! { "br {entry}", stack_address = in(reg) current_stack_address, entry = in(reg) entry_point, - in("x0") BOOT_INFO.as_ref().unwrap(), + in("x0") raw_boot_info, in("x1") 0, options(noreturn) ) diff --git a/src/arch/riscv64/mod.rs b/src/arch/riscv64/mod.rs index 341de128..2a24aa68 100644 --- a/src/arch/riscv64/mod.rs +++ b/src/arch/riscv64/mod.rs @@ -100,47 +100,45 @@ pub unsafe fn boot_kernel(kernel_info: LoadedKernel) -> ! { info!("hart_id = {}", start::get_hart_id()); - static mut BOOT_INFO: Option = None; - - let boot_info = { - let phys_addr_range = { - let memory = fdt.memory(); - let mut regions = memory.regions(); - - let mem_region = regions.next().unwrap(); - assert!( - regions.next().is_none(), - "hermit-loader can only handle one memory region yet" - ); - - let mem_base = u64::try_from(mem_region.starting_address.addr()).unwrap(); - let mem_size = u64::try_from(mem_region.size.unwrap()).unwrap(); - mem_base..mem_base + mem_size - }; - - let device_tree = { - let fdt_addr = start::get_fdt_ptr().expose_addr(); - DeviceTreeAddress::new(fdt_addr.try_into().unwrap()) - }; - - let boot_info = BootInfo { - hardware_info: HardwareInfo { - phys_addr_range, - serial_port_base: None, - device_tree, - }, - load_info, - platform_info: PlatformInfo::LinuxBoot, - }; - - info!("boot_info = {boot_info:#?}"); - - RawBootInfo::from(boot_info) + take_static::take_static! { + static RAW_BOOT_INFO: Option = None; + } + + let raw_boot_info = RAW_BOOT_INFO.take().unwrap(); + + let phys_addr_range = { + let memory = fdt.memory(); + let mut regions = memory.regions(); + + let mem_region = regions.next().unwrap(); + assert!( + regions.next().is_none(), + "hermit-loader can only handle one memory region yet" + ); + + let mem_base = u64::try_from(mem_region.starting_address.addr()).unwrap(); + let mem_size = u64::try_from(mem_region.size.unwrap()).unwrap(); + mem_base..mem_base + mem_size }; - unsafe { - BOOT_INFO = Some(boot_info); - } + let device_tree = { + let fdt_addr = start::get_fdt_ptr().expose_addr(); + DeviceTreeAddress::new(fdt_addr.try_into().unwrap()) + }; + + let boot_info = BootInfo { + hardware_info: HardwareInfo { + phys_addr_range, + serial_port_base: None, + device_tree, + }, + load_info, + platform_info: PlatformInfo::LinuxBoot, + }; + + info!("boot_info = {boot_info:#?}"); + *raw_boot_info = Some(RawBootInfo::from(boot_info)); + info!("boot_info at {raw_boot_info:p}"); // Check expected signature of entry function let entry: Entry = { @@ -158,7 +156,7 @@ pub unsafe fn boot_kernel(kernel_info: LoadedKernel) -> ! { entry = in(reg) entry, stack = in(reg) start::get_stack_ptr(), in("a0") start::get_hart_id(), - in("a1") BOOT_INFO.as_ref().unwrap(), + in("a1") raw_boot_info, options(noreturn) ) } diff --git a/src/arch/x86_64/mod.rs b/src/arch/x86_64/mod.rs index 2d93ae34..37de072a 100644 --- a/src/arch/x86_64/mod.rs +++ b/src/arch/x86_64/mod.rs @@ -380,28 +380,29 @@ pub unsafe fn boot_kernel(kernel_info: LoadedKernel) -> ! { start_address, end_address ); - static mut BOOT_INFO: Option = None; - - let boot_info = { - let boot_info = BootInfo { - hardware_info: HardwareInfo { - phys_addr_range: start_address as u64..end_address as u64, - serial_port_base: SerialPortBase::new(SERIAL_IO_PORT), - device_tree: None, - }, - load_info, - platform_info: PlatformInfo::LinuxBootParams { - command_line, - boot_params_addr: (unsafe { boot_params } as u64).try_into().unwrap(), - }, - }; - RawBootInfo::from(boot_info) - }; - unsafe { - BOOT_INFO = Some(boot_info); - info!("BootInfo located at {:p}", &BOOT_INFO); + take_static::take_static! { + static RAW_BOOT_INFO: Option = None; + } + + let raw_boot_info = RAW_BOOT_INFO.take().unwrap(); + + let boot_info = BootInfo { + hardware_info: HardwareInfo { + phys_addr_range: start_address as u64..end_address as u64, + serial_port_base: SerialPortBase::new(SERIAL_IO_PORT), + device_tree: None, + }, + load_info, + platform_info: PlatformInfo::LinuxBootParams { + command_line, + boot_params_addr: (unsafe { boot_params } as u64).try_into().unwrap(), + }, }; + info!("boot_info = {boot_info:#?}"); + *raw_boot_info = Some(RawBootInfo::from(boot_info)); + info!("boot_info at {raw_boot_info:p}"); + // Jump to the kernel entry point and provide the Multiboot information to it. info!( "Jumping to HermitCore Application Entry Point at {:#x}", @@ -425,7 +426,7 @@ pub unsafe fn boot_kernel(kernel_info: LoadedKernel) -> ! { "jmp {entry}", stack_address = in(reg) current_stack_address, entry = in(reg) entry_point, - in("rdi") BOOT_INFO.as_ref().unwrap(), + in("rdi") raw_boot_info, in("rsi") 0, options(noreturn) ) @@ -483,28 +484,29 @@ pub unsafe fn boot_kernel(kernel_info: LoadedKernel) -> ! { let device_tree = DeviceTree::create().expect("Unable to create devicetree!"); - static mut BOOT_INFO: Option = None; - - let boot_info = { - let boot_info = BootInfo { - hardware_info: HardwareInfo { - phys_addr_range: 0..0, - serial_port_base: SerialPortBase::new(SERIAL_IO_PORT), - device_tree: DeviceTreeAddress::new(device_tree.as_ptr() as u64), - }, - load_info, - platform_info: PlatformInfo::Multiboot { - command_line, - multiboot_info_addr: (unsafe { mb_info } as u64).try_into().unwrap(), - }, - }; - RawBootInfo::from(boot_info) - }; - unsafe { - BOOT_INFO = Some(boot_info); - info!("BootInfo located at {:p}", &BOOT_INFO); + take_static::take_static! { + static RAW_BOOT_INFO: Option = None; } + let raw_boot_info = RAW_BOOT_INFO.take().unwrap(); + + let boot_info = BootInfo { + hardware_info: HardwareInfo { + phys_addr_range: 0..0, + serial_port_base: SerialPortBase::new(SERIAL_IO_PORT), + device_tree: DeviceTreeAddress::new(device_tree.as_ptr() as u64), + }, + load_info, + platform_info: PlatformInfo::Multiboot { + command_line, + multiboot_info_addr: (unsafe { mb_info } as u64).try_into().unwrap(), + }, + }; + + info!("boot_info = {boot_info:#?}"); + *raw_boot_info = Some(RawBootInfo::from(boot_info)); + info!("boot_info at {raw_boot_info:p}"); + // Jump to the kernel entry point and provide the Multiboot information to it. info!( "Jumping to HermitCore Application Entry Point at {:#x}", @@ -528,7 +530,7 @@ pub unsafe fn boot_kernel(kernel_info: LoadedKernel) -> ! { "jmp {entry}", stack_address = in(reg) current_stack_address, entry = in(reg) entry_point, - in("rdi") BOOT_INFO.as_ref().unwrap(), + in("rdi") raw_boot_info, in("rsi") 0, options(noreturn) )