Deduplicate a bunch of things that use KernelArgs between archs

This commit is contained in:
bjorn3
2025-09-20 19:10:01 +02:00
parent 3f385ba79d
commit e7358e3e5b
5 changed files with 120 additions and 183 deletions
+5 -65
View File
@@ -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);
+7 -55
View File
@@ -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);
+7 -52
View File
@@ -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);
+38 -3
View File
@@ -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<A: Arch>(areas: &[MemoryArea], mut bump_allocator: &mut Bum
}
}
pub unsafe fn init(low_limit: Option<usize>, high_limit: Option<usize>) {
pub unsafe fn init(args: &KernelArgs, low_limit: Option<usize>, high_limit: Option<usize>) {
register_memory_from_kernel_args(args);
unsafe {
let physmem_limit = MemoryEntry {
start: align_up(low_limit.unwrap_or(0)),
+63 -8
View File
@@ -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<fdt::Fdt<'static>> {
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
}
}
}