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