strat9_kernel/boot/
modules.rs1use strat9_abi::boot::{ModuleEntry, MAX_BOOT_MODULES};
3
4pub struct InitfsModule<'a> {
5 pub name: &'a str,
6 pub virtual_base: u64,
7 pub len: usize,
8}
9
10impl<'a> InitfsModule<'a> {
11 pub fn from_physical(entry: &'a ModuleEntry, hhdm: u64) -> Result<Self, &'static str> {
14 let name = entry.checked_name()?;
15 if entry.base == 0 || entry.size > isize::MAX as u64 {
16 return Err("invalid module payload extent");
17 }
18 entry
19 .base
20 .checked_add(entry.size)
21 .ok_or("module physical range overflow")?;
22 let virtual_base = hhdm
23 .checked_add(entry.base)
24 .ok_or("module HHDM address overflow")?;
25 let last = virtual_base
26 .checked_add(entry.size.saturating_sub(1))
27 .ok_or("module virtual range overflow")?;
28 if !canonical(virtual_base) || !canonical(last) || (virtual_base >> 47) != (last >> 47) {
31 return Err("module virtual range is not canonical");
32 }
33 Ok(Self {
34 name,
35 virtual_base,
36 len: entry.size as usize,
37 })
38 }
39}
40
41pub fn validate_modules(entries: &[ModuleEntry], hhdm: u64) -> Result<(), &'static str> {
42 if entries.len() > MAX_BOOT_MODULES {
43 return Err("too many initfs modules");
44 }
45 for (index, entry) in entries.iter().enumerate() {
46 let view = InitfsModule::from_physical(entry, hhdm)?;
47 for previous in &entries[..index] {
48 if previous.checked_name()?.eq_ignore_ascii_case(view.name) {
49 return Err("duplicate initfs module name");
50 }
51 }
52 }
53 Ok(())
54}
55
56fn canonical(address: u64) -> bool {
57 address < (1 << 47) || address >= 0xFFFF_8000_0000_0000
58}