11//! DTB (Device Tree Blob) related functionality.
2- use fdt_parser :: { Fdt , FdtHeader } ;
2+ extern crate alloc ;
33
4+ use alloc:: boxed:: Box ;
45use core:: fmt:: Write ;
6+ use fdt_parser:: { Fdt , FdtHeader } ;
57use lazyinit:: LazyInit ;
68
7- static BOOTARGS_STR : LazyInit < heapless:: String < 256 > > = LazyInit :: new ( ) ;
9+ pub static BOOT_ARG : LazyInit < usize > = LazyInit :: new ( ) ;
10+ static CACHED_FDT : LazyInit < Fdt < ' static > > = LazyInit :: new ( ) ;
11+ static BOOTARGS_STR : LazyInit < heapless:: String < 1024 > > = LazyInit :: new ( ) ;
812
9- /// Get the bootargs from the device tree.
10- pub fn bootargs_message ( ) -> Option < & ' static str > {
11- let fdt_addr = crate :: get_bootarg ( ) ;
13+ /// Returns the boot argument.
14+ /// This is typically the device tree blob address passed from the bootloader.
15+ pub fn get_bootarg ( ) -> usize {
16+ * BOOT_ARG
17+ }
1218
19+ /// Get the cached FDT or initialize it if not already done.
20+ fn get_fdt ( ) -> Option < & ' static Fdt < ' static > > {
21+ // Return cached FDT if available
22+ if let Some ( fdt) = CACHED_FDT . get ( ) {
23+ return Some ( fdt) ;
24+ }
25+
26+ // Parse and cache the FDT
27+ let fdt_addr = get_bootarg ( ) ;
1328 if fdt_addr == 0 {
1429 return None ;
1530 }
@@ -33,18 +48,38 @@ pub fn bootargs_message() -> Option<&'static str> {
3348 core:: slice:: from_raw_parts ( ptr, size)
3449 } ;
3550
36- let fdt = match Fdt :: from_bytes ( fdt_bytes) {
37- Ok ( fdt) => fdt,
38- Err ( _) => return None ,
39- } ;
51+ // Leak the FDT bytes to create a 'static reference
52+ let fdt_bytes_static = Box :: leak ( fdt_bytes. to_vec ( ) . into_boxed_slice ( ) ) ;
53+
54+ match Fdt :: from_bytes ( fdt_bytes_static) {
55+ Ok ( fdt) => {
56+ // Store the FDT in the cache
57+ CACHED_FDT . init_once ( fdt) ;
58+ CACHED_FDT . get ( )
59+ }
60+ Err ( _) => None ,
61+ }
62+ }
63+
64+ /// Get the bootargs chosen from the device tree.
65+ pub fn get_chosen ( ) -> Option < & ' static str > {
66+ // If bootargs are already cached, return them
67+ if let Some ( bootargs) = BOOTARGS_STR . get ( ) {
68+ return Some ( bootargs. as_str ( ) ) ;
69+ }
70+
71+ // Get or initialize the cached FDT
72+ let fdt = get_fdt ( ) ?;
4073
4174 if let Some ( chosen) = fdt. chosen ( ) {
4275 if let Some ( bootargs) = chosen. bootargs ( ) {
4376 // Store bootargs in static variable
44- let mut bootargs_str = heapless:: String :: < 256 > :: new ( ) ;
77+ let mut bootargs_str = heapless:: String :: < 1024 > :: new ( ) ;
4578 if write ! ( bootargs_str, "{}" , bootargs) . is_ok ( ) {
4679 BOOTARGS_STR . init_once ( bootargs_str) ;
4780 return Some ( BOOTARGS_STR . as_str ( ) ) ;
81+ } else {
82+ warn ! ( "Failed to write bootargs" ) ;
4883 }
4984 }
5085 }
0 commit comments