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 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 pub arch: ArchBootParams, 31 boot_command_line: [u8; Self::BOOT_COMMAND_LINE_SIZE], 32 } 33 34 impl BootParams { 35 const DEFAULT: Self = BootParams { 36 screen_info: BootTimeScreenInfo::DEFAULT, 37 arch: ArchBootParams::DEFAULT, 38 boot_command_line: [0u8; Self::BOOT_COMMAND_LINE_SIZE], 39 }; 40 41 /// 开机命令行参数字符串最大大小 42 pub const BOOT_COMMAND_LINE_SIZE: usize = 2048; 43 44 const fn new() -> Self { 45 Self::DEFAULT 46 } 47 48 /// 开机命令行参数(原始字节数组) 49 #[allow(dead_code)] 50 pub fn boot_cmdline(&self) -> &[u8] { 51 &self.boot_command_line 52 } 53 54 /// 开机命令行参数字符串 55 pub fn boot_cmdline_str(&self) -> &str { 56 core::str::from_utf8(self.boot_cmdline()).unwrap() 57 } 58 59 /// 追加开机命令行参数 60 /// 61 /// 如果开机命令行参数已经满了,则不会追加。 62 /// 如果超过了最大长度,则截断。 63 /// 64 /// ## 参数 65 /// 66 /// - `data`:追加的数据 67 pub fn boot_cmdline_append(&mut self, data: &[u8]) { 68 if data.is_empty() { 69 return; 70 } 71 72 let mut pos: Option<usize> = None; 73 // 寻找结尾 74 for (i, x) in self.boot_command_line.iter().enumerate() { 75 if *x == 0 { 76 pos = Some(i); 77 break; 78 } 79 } 80 let pos = pos.unwrap_or_else(|| self.boot_command_line.len() - 1) as isize; 81 82 let avail = self.boot_command_line.len() as isize - pos - 1; 83 if avail <= 0 { 84 return; 85 } 86 87 let len = min(avail as usize, data.len()); 88 let pos = pos as usize; 89 self.boot_command_line[pos..pos + len].copy_from_slice(&data[0..len]); 90 91 self.boot_command_line[pos + len] = 0; 92 } 93 94 /// 获取FDT的虚拟地址 95 #[allow(dead_code)] 96 pub fn fdt(&self) -> Option<VirtAddr> { 97 #[cfg(target_arch = "riscv64")] 98 return Some(self.arch.arch_fdt()); 99 100 #[cfg(target_arch = "x86_64")] 101 return None; 102 } 103 104 /// 获取FDT的物理地址 105 #[allow(dead_code)] 106 pub fn fdt_paddr(&self) -> Option<PhysAddr> { 107 #[cfg(target_arch = "riscv64")] 108 return Some(self.arch.fdt_paddr); 109 110 #[cfg(target_arch = "x86_64")] 111 return None; 112 } 113 } 114