xref: /DragonOS/kernel/src/init/mod.rs (revision d46c6d27941a26de14f55a2bbf956219bcc70871)
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