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