Skip to content

Commit

Permalink
protocol+limine: pass module IDs to kernel via module basenames
Browse files Browse the repository at this point in the history
  • Loading branch information
Qix- committed Sep 15, 2024
1 parent 494a604 commit bf761ed
Show file tree
Hide file tree
Showing 6 changed files with 122 additions and 21 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions oro-arch-x86_64/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ oro-sync.workspace = true
oro-debug.workspace = true
oro-dbgutil.workspace = true
oro-acpi.workspace = true
oro-id.workspace = true

[lints]
workspace = true
44 changes: 38 additions & 6 deletions oro-arch-x86_64/src/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@

use crate::{handler::Handler, lapic::Lapic};
use core::mem::MaybeUninit;
use oro_debug::dbg;
use oro_debug::{dbg, dbg_warn};
use oro_kernel::KernelState;
use oro_mem::translate::OffsetTranslator;
use oro_mem::translate::{OffsetTranslator, Translator};
use oro_sync::spinlock::unfair_critical::UnfairCriticalSpinlock;

/// The global kernel state. Initialized once during boot
Expand All @@ -18,6 +18,7 @@ pub static mut KERNEL_STATE: MaybeUninit<KernelState<crate::Arch>> = MaybeUninit
/// Must be called exactly once for the lifetime of the system,
/// only by the boot processor at boot time (_not_ at any
/// subsequent bringup).
#[expect(clippy::needless_pass_by_value)]
pub unsafe fn initialize_primary(pat: OffsetTranslator, pfa: crate::Pfa) {
#[cfg(debug_assertions)]
{
Expand All @@ -36,15 +37,46 @@ pub unsafe fn initialize_primary(pat: OffsetTranslator, pfa: crate::Pfa) {

// SAFETY(qix-): We know what we're doing here.
#[expect(static_mut_refs)]
KernelState::init(&mut KERNEL_STATE, pat, UnfairCriticalSpinlock::new(pfa))
.expect("failed to create global kernel state");
KernelState::init(
&mut KERNEL_STATE,
pat.clone(),
UnfairCriticalSpinlock::new(pfa),
)
.expect("failed to create global kernel state");

// XXX TODO(qix-): list out the modules the bootloader sent
// TODO(qix-): Not sure that I like that this is ELF-aware. This may get
// TODO(qix-): refactored at some point.
if let Some(oro_boot_protocol::modules::ModulesKind::V0(modules)) =
crate::boot::protocol::MODULES_REQUEST.response()
{
let modules = modules.assume_init_ref();
dbg!("got modules next: {:016x}", modules.next);
let mut next = modules.next;

while next != 0 {
let module = &*pat.translate::<oro_boot_protocol::Module>(next);
next = module.next;

let id = oro_id::AnyId::from_high_low(module.id_high, module.id_low);

let Ok(id) = oro_id::Id::<{ oro_id::IdType::Module }>::try_from(id) else {
dbg_warn!(
"skipping module; not a valid module ID: {:?}",
id.as_bytes()
);
continue;
};

if id.is_internal() {
dbg_warn!("skipping module; internal module ID: {:?}", id.as_bytes());
continue;
}

dbg!(
"loading module: {id} @ {:016X} ({})",
module.base,
module.length
);
}
}
}

Expand Down
21 changes: 18 additions & 3 deletions oro-boot-protocol/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,13 +187,28 @@ macros::oro_boot_protocol! {
#[repr(C)]
#[derive(Debug, Clone, Copy, Default)]
pub struct Module {
/// The highest 64 bits of the module 128 bit ID.
///
/// The module ID **must not** be reserved, or
/// the kernel will reject loading it.
///
/// See the `oro-id` crate for more information.
pub id_high: u64,
/// The lowest 64 bits of the module 128 bit ID.
///
/// The module ID **must not** be reserved, or
/// the kernel will reject loading it.
///
/// See the `oro-id` crate for more information.
/// The physical base address of the module.
pub base: u64,
pub id_low: u64,
/// The physical start address of the module.
pub base: u64,
/// The length of the module.
pub length: u64,
pub length: u64,
/// The physical address of the next module in the list,
/// or `0` if this is the last module.
pub next: u64,
pub next: u64,
}

#[cfg(feature = "utils")]
Expand Down
1 change: 1 addition & 0 deletions oro-bootloader-limine/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ doc = false
oro-boot.workspace = true
oro-boot-protocol.workspace = true
oro-debug.workspace = true
oro-id.workspace = true
limine.workspace = true

[lints]
Expand Down
74 changes: 62 additions & 12 deletions oro-bootloader-limine/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
//! See the `bin/` directory for architecture-specific entry points.
#![no_std]

use core::ffi::CStr;
use core::{ffi::CStr, str::FromStr};
#[cfg(debug_assertions)]
use limine::request::StackSizeRequest;
use limine::{
Expand Down Expand Up @@ -182,11 +182,12 @@ pub unsafe fn init() -> ! {
};

Module {
// Expects a physical address but the Limine system gives us
// a virtual address. We have to un-translate it.
base: u64::try_from(kernel_module.addr() as usize).unwrap() - hhdm_offset,
length: kernel_module.size(),
next: 0,
id_high: 0,
id_low: 0,
base: u64::try_from(kernel_module.addr() as usize).unwrap()
- hhdm_offset,
length: kernel_module.size(),
next: 0,
}
},
)?;
Expand Down Expand Up @@ -222,13 +223,62 @@ pub unsafe fn init() -> ! {
module.path() != DTB_PATH.to_bytes()
&& module.path() != KERNEL_PATH.to_bytes()
})
.map(|module| {
oro_boot_protocol::Module {
base: u64::try_from(module.addr() as usize).unwrap()
.filter_map(|module| {
// Get the basename by finding the text after
// the last `/`, if any.
let path = module.path();
let basename = path
.iter()
.rev()
.position(|&c| c == b'/')
.map_or(path, |pos| &path[path.len() - pos..]);

let Ok(id_str) = core::str::from_utf8(basename) else {
dbg_err!(
"failed to parse module path (characters after last '/' are \
not utf-8): {basename:?}",
);
return None;
};

let any_id = match oro_id::AnyId::from_str(id_str) {
Ok(id) => id,
Err(err) => {
dbg_err!(
"failed to parse module path as Oro ID: {err:?}: \
{id_str:?}"
);
return None;
}
};

if any_id.ty() != Some(oro_id::IdType::Module) {
dbg_err!(
"failed to parse module path as Oro ID (not a module ID): \
{id_str:?}"
);
return None;
};

if any_id.is_internal() {
dbg_err!(
"failed to parse module path as Oro ID (internal module ID): \
{id_str:?}"
);
return None;
};

let high = any_id.high_bits();
let low = any_id.low_bits();

Some(oro_boot_protocol::Module {
id_high: high,
id_low: low,
base: u64::try_from(module.addr() as usize).unwrap()
- hhdm_offset,
length: module.size(),
next: 0, // will be written by the serializer
}
length: module.size(),
next: 0, // will be written by the serializer
})
}),
)?;

Expand Down

0 comments on commit bf761ed

Please sign in to comment.