From 0022bd448c59eaee1293cc10a7934e4bc7bdce2d Mon Sep 17 00:00:00 2001 From: Elle Rhumsaa Date: Thu, 18 Sep 2025 20:25:09 +0000 Subject: [PATCH] dtb: remove allocation for in-memory DTB Replaces the `Once>` with `Once<&'static [u8]>` to avoid an unnecessary allocation. Adds some basic documentation. Signed-off-by: Elle Rhumsaa --- src/dtb/mod.rs | 23 ++++++++++++++++------- src/scheme/dtb.rs | 7 +------ 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/src/dtb/mod.rs b/src/dtb/mod.rs index f740980fe3..b71b819b73 100644 --- a/src/dtb/mod.rs +++ b/src/dtb/mod.rs @@ -4,7 +4,6 @@ use crate::{ dtb::irqchip::IrqCell, startup::memory::{register_memory_region, BootloaderMemoryKind}, }; -use alloc::vec::Vec; use byteorder::{ByteOrder, BE}; use core::slice; use fdt::{ @@ -14,19 +13,29 @@ use fdt::{ }; use spin::once::Once; -pub static DTB_BINARY: Once> = Once::new(); +/// Represents the in-memory DTB (DeviceTree) binary. +pub static DTB_BINARY: Once<&'static [u8]> = Once::new(); +/// Initializes the DTB from the provided base address and size. +/// +/// # Safety +/// +/// Caller must ensure the base address and size reference valid memory. +/// +/// The referenced memory must contain a valid DTB for the underliying system. +/// +/// The referenced memory must **not** be mutated for the duration of kernel run-time. pub unsafe fn init(dtb: Option<(usize, usize)>) { let mut initialized = false; DTB_BINARY.call_once(|| { initialized = true; - let mut binary = Vec::new(); if let Some((dtb_base, dtb_size)) = dtb { - let data = unsafe { slice::from_raw_parts(dtb_base as *const u8, dtb_size) }; - binary.extend(data); - }; - binary + // SAFETY: `dtb_base` + `dtb_size` reference valid memory due to caller invariants + unsafe { slice::from_raw_parts(dtb_base as *const u8, dtb_size) } + } else { + &[] + } }); if !initialized { println!("DTB_BINARY INIT TWICE!"); diff --git a/src/scheme/dtb.rs b/src/scheme/dtb.rs index b2c400ce48..bbdc4ddbcd 100644 --- a/src/scheme/dtb.rs +++ b/src/scheme/dtb.rs @@ -40,12 +40,7 @@ impl DtbScheme { DATA.call_once(|| { data_init = true; - let dtb = match DTB_BINARY.get() { - Some(dtb) => dtb.as_slice(), - None => &[], - }; - - Box::from(dtb) + Box::from(DTB_BINARY.get().map(|&d| d).unwrap_or(&[])) }); if !data_init {