From e7358e3e5b4ba2158a5f5f4edaa27c3e9f424857 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 20 Sep 2025 19:10:01 +0200 Subject: [PATCH] Deduplicate a bunch of things that use KernelArgs between archs --- src/arch/aarch64/start.rs | 70 +++-------------------------------- src/arch/riscv64/start.rs | 62 ++++--------------------------- src/arch/x86_shared/start.rs | 59 ++++-------------------------- src/startup/memory.rs | 41 +++++++++++++++++++-- src/startup/mod.rs | 71 ++++++++++++++++++++++++++++++++---- 5 files changed, 120 insertions(+), 183 deletions(-) diff --git a/src/arch/aarch64/start.rs b/src/arch/aarch64/start.rs index f0689c5d40..eec13f801a 100644 --- a/src/arch/aarch64/start.rs +++ b/src/arch/aarch64/start.rs @@ -10,17 +10,7 @@ use core::{ use fdt::Fdt; use crate::{ - allocator, - arch::interrupt, - device, - devices::graphical_debug, - dtb, - dtb::register_dev_memory_ranges, - paging, - startup::{ - memory::{register_bootloader_areas, register_memory_region, BootloaderMemoryKind}, - KernelArgs, - }, + allocator, arch::interrupt, device, devices::graphical_debug, dtb, paging, startup::KernelArgs, }; /// Test of zero values in BSS. @@ -44,14 +34,8 @@ pub unsafe extern "C" fn kstart(args_ptr: *const KernelArgs) -> ! { assert_eq!(DATA_TEST_NONZERO, 0xFFFF_FFFF_FFFF_FFFF); } - // Convert env to slice - let env = slice::from_raw_parts( - (crate::PHYS_OFFSET + args.env_base as usize) as *const u8, - args.env_size as usize, - ); - // Set up graphical debug - graphical_debug::init(env); + graphical_debug::init(args.env()); // Get hardware descriptor data //TODO: use env {DTB,RSDT}_{BASE,SIZE}? @@ -70,14 +54,6 @@ pub unsafe extern "C" fn kstart(args_ptr: *const KernelArgs) -> ! { .ok_or(fdt::FdtError::BadPtr) .and_then(|data| Fdt::new(data)); - let rsdp_opt = hwdesc_data.and_then(|data| { - if data.starts_with(b"RSD PTR ") { - Some(data.as_ptr()) - } else { - None - } - }); - // Try to find serial port prior to logging if let Ok(dtb) = &dtb_res { device::serial::init_early(dtb); @@ -89,37 +65,7 @@ pub unsafe extern "C" fn kstart(args_ptr: *const KernelArgs) -> ! { interrupt::init(); // Initialize RMM - register_bootloader_areas(args.areas_base as usize, args.areas_size as usize); - if let Ok(dtb) = &dtb_res { - register_dev_memory_ranges(dtb); - } - - register_memory_region( - args.kernel_base as usize, - args.kernel_size as usize, - BootloaderMemoryKind::Kernel, - ); - register_memory_region( - args.stack_base as usize, - args.stack_size as usize, - BootloaderMemoryKind::IdentityMap, - ); - register_memory_region( - args.env_base as usize, - args.env_size as usize, - BootloaderMemoryKind::IdentityMap, - ); - register_memory_region( - args.hwdesc_base as usize, - args.hwdesc_size as usize, - BootloaderMemoryKind::IdentityMap, - ); - register_memory_region( - args.bootstrap_base as usize, - args.bootstrap_size as usize, - BootloaderMemoryKind::IdentityMap, - ); - crate::startup::memory::init(None, None); + crate::startup::memory::init(&args, None, None); // Initialize paging paging::init(); @@ -148,20 +94,14 @@ pub unsafe extern "C" fn kstart(args_ptr: *const KernelArgs) -> ! { #[cfg(feature = "acpi")] { - crate::acpi::init(rsdp_opt); + crate::acpi::init(args.acpi_rsdp()); } } } BSP_READY.store(true, Ordering::SeqCst); - crate::Bootstrap { - base: crate::memory::Frame::containing(crate::paging::PhysicalAddress::new( - args.bootstrap_base as usize, - )), - page_count: (args.bootstrap_size as usize) / crate::memory::PAGE_SIZE, - env, - } + args.bootstrap() }; crate::kmain(bootstrap); diff --git a/src/arch/riscv64/start.rs b/src/arch/riscv64/start.rs index 313ecc28b9..2ef6e2b035 100644 --- a/src/arch/riscv64/start.rs +++ b/src/arch/riscv64/start.rs @@ -15,11 +15,7 @@ use crate::{ arch::{device::serial::init_early, interrupt, paging}, device, devices::graphical_debug, - dtb::register_dev_memory_ranges, - startup::{ - memory::{register_bootloader_areas, register_memory_region, BootloaderMemoryKind}, - KernelArgs, - }, + startup::KernelArgs, }; /// Test of zero values in BSS. @@ -54,7 +50,7 @@ pub unsafe extern "C" fn kstart(args_ptr: *const KernelArgs) -> ! { ); let bootstrap = { - let args = &*args_ptr; + let args = args_ptr.read(); // BSS should already be zero { @@ -62,11 +58,6 @@ pub unsafe extern "C" fn kstart(args_ptr: *const KernelArgs) -> ! { assert_eq!(DATA_TEST_NONZERO, 0xFFFF_FFFF_FFFF_FFFF); } - let env = slice::from_raw_parts( - (crate::PHYS_OFFSET + args.env_base as usize) as *const u8, - args.env_size as usize, - ); - let dtb_data = if args.hwdesc_base != 0 { Some(( crate::PHYS_OFFSET + args.hwdesc_base as usize, @@ -75,11 +66,9 @@ pub unsafe extern "C" fn kstart(args_ptr: *const KernelArgs) -> ! { } else { None }; - let dtb = dtb_data - .map(|(base, size)| unsafe { slice::from_raw_parts(base as *const u8, size) }) - .and_then(|data| Fdt::new(data).ok()); + let dtb = args.dtb(); - graphical_debug::init(env); + graphical_debug::init(args.env()); if let Some(dtb) = &dtb { init_early(dtb); @@ -94,48 +83,11 @@ pub unsafe extern "C" fn kstart(args_ptr: *const KernelArgs) -> ! { interrupt::init(); - let bootstrap = crate::Bootstrap { - base: Frame::containing(PhysicalAddress::new(args.bootstrap_base as usize)), - page_count: args.bootstrap_size as usize / PAGE_SIZE, - env, - }; - // Initialize RMM - register_bootloader_areas(args.areas_base as usize, args.areas_size as usize); - if let Some(dt) = &dtb { - register_dev_memory_ranges(dt); - } - - register_memory_region( - args.kernel_base as usize, - args.kernel_size as usize, - BootloaderMemoryKind::Kernel, - ); - register_memory_region( - args.stack_base as usize, - args.stack_size as usize, - BootloaderMemoryKind::IdentityMap, - ); - register_memory_region( - args.env_base as usize, - args.env_size as usize, - BootloaderMemoryKind::IdentityMap, - ); - register_memory_region( - args.hwdesc_base as usize, - args.hwdesc_size as usize, - BootloaderMemoryKind::IdentityMap, - ); - register_memory_region( - args.bootstrap_base as usize, - args.bootstrap_size as usize, - BootloaderMemoryKind::IdentityMap, - ); - - crate::startup::memory::init(None, None); + crate::startup::memory::init(&args, None, None); let boot_hart_id = - get_boot_hart_id(env).expect("Didn't get boot HART id from bootloader"); + get_boot_hart_id(args.env()).expect("Didn't get boot HART id from bootloader"); info!("Booting on HART {}", boot_hart_id); BOOT_HART_ID.store(boot_hart_id, Ordering::Relaxed); @@ -159,7 +111,7 @@ pub unsafe extern "C" fn kstart(args_ptr: *const KernelArgs) -> ! { // FIXME bringup AP HARTs - bootstrap + args.bootstrap() }; crate::kmain(bootstrap); diff --git a/src/arch/x86_shared/start.rs b/src/arch/x86_shared/start.rs index 728accd256..8317c7361b 100644 --- a/src/arch/x86_shared/start.rs +++ b/src/arch/x86_shared/start.rs @@ -4,7 +4,7 @@ //! defined in other files inside of the `arch` module use core::{ cell::SyncUnsafeCell, - hint, slice, + hint, sync::atomic::{AtomicBool, Ordering}, }; @@ -18,10 +18,7 @@ use crate::{ devices::graphical_debug, gdt, idt, interrupt, paging::{self, PhysicalAddress, RmmA, RmmArch, TableKind}, - startup::{ - memory::{register_bootloader_areas, register_memory_region, BootloaderMemoryKind}, - KernelArgs, - }, + startup::KernelArgs, }; /// Test of zero values in BSS. @@ -45,17 +42,11 @@ pub unsafe extern "C" fn kstart(args_ptr: *const KernelArgs) -> ! { assert_eq!(DATA_TEST_NONZERO.get().read(), usize::max_value()); } - // Convert env to slice - let env = slice::from_raw_parts( - (args.env_base as usize + crate::PHYS_OFFSET) as *const u8, - args.env_size as usize, - ); - // Set up serial debug device::serial::init(); // Set up graphical debug - graphical_debug::init(env); + graphical_debug::init(args.env()); info!("Redox OS starting..."); args.print(); @@ -67,36 +58,10 @@ pub unsafe extern "C" fn kstart(args_ptr: *const KernelArgs) -> ! { idt::init_bsp(); // Initialize RMM - register_bootloader_areas(args.areas_base as usize, args.areas_size as usize); - register_memory_region( - args.kernel_base as usize, - args.kernel_size as usize, - BootloaderMemoryKind::Kernel, - ); - register_memory_region( - args.stack_base as usize, - args.stack_size as usize, - BootloaderMemoryKind::IdentityMap, - ); - register_memory_region( - args.env_base as usize, - args.env_size as usize, - BootloaderMemoryKind::IdentityMap, - ); - register_memory_region( - args.hwdesc_base as usize, - args.hwdesc_size as usize, - BootloaderMemoryKind::IdentityMap, - ); - register_memory_region( - args.bootstrap_base as usize, - args.bootstrap_size as usize, - BootloaderMemoryKind::IdentityMap, - ); #[cfg(target_arch = "x86")] - crate::startup::memory::init(Some(0x100000), Some(0x40000000)); + crate::startup::memory::init(&args, Some(0x100000), Some(0x40000000)); #[cfg(target_arch = "x86_64")] - crate::startup::memory::init(Some(0x100000), None); + crate::startup::memory::init(&args, Some(0x100000), None); // Initialize paging paging::init(); @@ -130,11 +95,7 @@ pub unsafe extern "C" fn kstart(args_ptr: *const KernelArgs) -> ! { // Read ACPI tables, starts APs #[cfg(feature = "acpi")] { - acpi::init(if args.hwdesc_base != 0 { - Some((args.hwdesc_base as usize + crate::PHYS_OFFSET) as *const u8) - } else { - None - }); + acpi::init(args.acpi_rsdp()); device::init_after_acpi(); } @@ -143,13 +104,7 @@ pub unsafe extern "C" fn kstart(args_ptr: *const KernelArgs) -> ! { BSP_READY.store(true, Ordering::SeqCst); - crate::Bootstrap { - base: crate::memory::Frame::containing(crate::paging::PhysicalAddress::new( - args.bootstrap_base as usize, - )), - page_count: (args.bootstrap_size as usize) / crate::memory::PAGE_SIZE, - env, - } + args.bootstrap() }; crate::kmain(bootstrap); diff --git a/src/startup/memory.rs b/src/startup/memory.rs index e2f51876c3..59b691e71a 100644 --- a/src/startup/memory.rs +++ b/src/startup/memory.rs @@ -1,7 +1,7 @@ use crate::{ arch::{consts::KERNEL_OFFSET, paging::entry::EntryFlags, rmm::page_flags, CurrentRmmArch}, memory::PAGE_SIZE, - startup::memory::BootloaderMemoryKind::Null, + startup::{memory::BootloaderMemoryKind::Null, KernelArgs}, }; use core::{ cell::SyncUnsafeCell, @@ -144,6 +144,39 @@ fn align_down(x: usize) -> usize { x / PAGE_SIZE * PAGE_SIZE } +fn register_memory_from_kernel_args(args: &KernelArgs) { + register_bootloader_areas(args.areas_base as usize, args.areas_size as usize); + #[cfg(dtb)] + if let Some(dt) = args.dtb() { + crate::dtb::register_dev_memory_ranges(&dt); + } + register_memory_region( + args.kernel_base as usize, + args.kernel_size as usize, + BootloaderMemoryKind::Kernel, + ); + register_memory_region( + args.stack_base as usize, + args.stack_size as usize, + BootloaderMemoryKind::IdentityMap, + ); + register_memory_region( + args.env_base as usize, + args.env_size as usize, + BootloaderMemoryKind::IdentityMap, + ); + register_memory_region( + args.hwdesc_base as usize, + args.hwdesc_size as usize, + BootloaderMemoryKind::IdentityMap, + ); + register_memory_region( + args.bootstrap_base as usize, + args.bootstrap_size as usize, + BootloaderMemoryKind::IdentityMap, + ); +} + pub fn register_memory_region(base: usize, size: usize, kind: BootloaderMemoryKind) { if kind != Null && size != 0 { debug!("Registering {:?} memory {:X} size {:X}", kind, base, size); @@ -151,7 +184,7 @@ pub fn register_memory_region(base: usize, size: usize, kind: BootloaderMemoryKi } } -pub fn register_bootloader_areas(areas_base: usize, areas_size: usize) { +fn register_bootloader_areas(areas_base: usize, areas_size: usize) { let bootloader_areas = unsafe { slice::from_raw_parts( areas_base as *const BootloaderMemoryEntry, @@ -379,7 +412,9 @@ unsafe fn map_memory(areas: &[MemoryArea], mut bump_allocator: &mut Bum } } -pub unsafe fn init(low_limit: Option, high_limit: Option) { +pub unsafe fn init(args: &KernelArgs, low_limit: Option, high_limit: Option) { + register_memory_from_kernel_args(args); + unsafe { let physmem_limit = MemoryEntry { start: align_up(low_limit.unwrap_or(0)), diff --git a/src/startup/mod.rs b/src/startup/mod.rs index 3b24328537..16e33b1ae7 100644 --- a/src/startup/mod.rs +++ b/src/startup/mod.rs @@ -1,15 +1,17 @@ +use core::slice; + pub mod memory; #[repr(C, packed(8))] pub(crate) struct KernelArgs { - pub(crate) kernel_base: u64, - pub(crate) kernel_size: u64, + kernel_base: u64, + kernel_size: u64, pub(crate) stack_base: u64, pub(crate) stack_size: u64, - pub(crate) env_base: u64, - pub(crate) env_size: u64, + env_base: u64, + env_size: u64, /// The base pointer to the saved RSDP or device tree blob. /// @@ -22,13 +24,13 @@ pub(crate) struct KernelArgs { pub(crate) hwdesc_base: u64, pub(crate) hwdesc_size: u64, - pub(crate) areas_base: u64, - pub(crate) areas_size: u64, + areas_base: u64, + areas_size: u64, /// The physical base 64-bit pointer to the contiguous bootstrap/initfs. - pub(crate) bootstrap_base: u64, + bootstrap_base: u64, /// Size of contiguous bootstrap/initfs physical region, not necessarily page aligned. - pub(crate) bootstrap_size: u64, + bootstrap_size: u64, } impl KernelArgs { @@ -64,4 +66,57 @@ impl KernelArgs { self.bootstrap_base + self.bootstrap_size ); } + + pub(crate) fn bootstrap(&self) -> crate::Bootstrap { + crate::Bootstrap { + base: crate::memory::Frame::containing(crate::paging::PhysicalAddress::new( + self.bootstrap_base as usize, + )), + page_count: (self.bootstrap_size as usize) / crate::memory::PAGE_SIZE, + env: self.env(), + } + } + + pub(crate) fn env(&self) -> &'static [u8] { + unsafe { + slice::from_raw_parts( + (crate::PHYS_OFFSET + self.env_base as usize) as *const u8, + self.env_size as usize, + ) + } + } + + #[cfg(feature = "acpi")] + pub(crate) fn acpi_rsdp(&self) -> Option<*const u8> { + if self.hwdesc_base != 0 { + let data = unsafe { + slice::from_raw_parts( + (crate::PHYS_OFFSET + self.hwdesc_base as usize) as *const u8, + self.hwdesc_size as usize, + ) + }; + if data.starts_with(b"RSD PTR ") { + Some(data.as_ptr()) + } else { + None + } + } else { + None + } + } + + #[cfg(dtb)] + pub(crate) fn dtb(&self) -> Option> { + if self.hwdesc_base != 0 { + let data = unsafe { + slice::from_raw_parts( + (crate::PHYS_OFFSET + self.hwdesc_base as usize) as *const u8, + self.hwdesc_size as usize, + ) + }; + fdt::Fdt::new(data).ok() + } else { + None + } + } }