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