1 use core::cmp::min; 2 3 use crate::{ 4 arch::init::ArchBootParams, 5 driver::video::fbdev::base::BootTimeScreenInfo, 6 libs::rwlock::RwLock, 7 mm::{PhysAddr, VirtAddr}, 8 }; 9 #[allow(clippy::module_inception)] 10 pub mod init; 11 pub mod initcall; 12 pub mod initial_kthread; 13 14 /// 启动参数 15 static BOOT_PARAMS: RwLock<BootParams> = RwLock::new(BootParams::new()); 16 17 #[inline(always)] 18 pub fn boot_params() -> &'static RwLock<BootParams> { 19 &BOOT_PARAMS 20 } 21 22 #[inline(never)] 23 fn init_intertrait() { 24 intertrait::init_caster_map(); 25 } 26 27 #[derive(Debug)] 28 pub struct BootParams { 29 pub screen_info: BootTimeScreenInfo, 30 #[allow(dead_code)] 31 pub arch: ArchBootParams, 32 boot_command_line: [u8; Self::BOOT_COMMAND_LINE_SIZE], 33 } 34 35 impl BootParams { 36 const DEFAULT: Self = BootParams { 37 screen_info: BootTimeScreenInfo::DEFAULT, 38 arch: ArchBootParams::DEFAULT, 39 boot_command_line: [0u8; Self::BOOT_COMMAND_LINE_SIZE], 40 }; 41 42 /// 开机命令行参数字符串最大大小 43 pub const BOOT_COMMAND_LINE_SIZE: usize = 2048; 44 45 const fn new() -> Self { 46 Self::DEFAULT 47 } 48 49 /// 开机命令行参数(原始字节数组) 50 #[allow(dead_code)] 51 pub fn boot_cmdline(&self) -> &[u8] { 52 &self.boot_command_line 53 } 54 55 /// 开机命令行参数字符串 56 pub fn boot_cmdline_str(&self) -> &str { 57 core::str::from_utf8(self.boot_cmdline()).unwrap() 58 } 59 60 /// 追加开机命令行参数 61 /// 62 /// 如果开机命令行参数已经满了,则不会追加。 63 /// 如果超过了最大长度,则截断。 64 /// 65 /// ## 参数 66 /// 67 /// - `data`:追加的数据 68 pub fn boot_cmdline_append(&mut self, data: &[u8]) { 69 if data.is_empty() { 70 return; 71 } 72 73 let mut pos: Option<usize> = None; 74 // 寻找结尾 75 for (i, x) in self.boot_command_line.iter().enumerate() { 76 if *x == 0 { 77 pos = Some(i); 78 break; 79 } 80 } 81 let pos = pos.unwrap_or(self.boot_command_line.len() - 1) as isize; 82 83 let avail = self.boot_command_line.len() as isize - pos - 1; 84 if avail <= 0 { 85 return; 86 } 87 88 let len = min(avail as usize, data.len()); 89 let pos = pos as usize; 90 self.boot_command_line[pos..pos + len].copy_from_slice(&data[0..len]); 91 92 self.boot_command_line[pos + len] = 0; 93 } 94 95 /// 获取FDT的虚拟地址 96 #[allow(dead_code)] 97 pub fn fdt(&self) -> Option<VirtAddr> { 98 #[cfg(target_arch = "riscv64")] 99 return Some(self.arch.arch_fdt()); 100 101 #[cfg(target_arch = "x86_64")] 102 return None; 103 } 104 105 /// 获取FDT的物理地址 106 #[allow(dead_code)] 107 pub fn fdt_paddr(&self) -> Option<PhysAddr> { 108 #[cfg(target_arch = "riscv64")] 109 return Some(self.arch.fdt_paddr); 110 111 #[cfg(target_arch = "x86_64")] 112 return None; 113 } 114 } 115