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)]
boot_params() -> &'static RwLock<BootParams>18 pub fn boot_params() -> &'static RwLock<BootParams> {
19     &BOOT_PARAMS
20 }
21 
22 #[inline(never)]
init_intertrait()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 
new() -> Self44     const fn new() -> Self {
45         Self::DEFAULT
46     }
47 
48     /// 开机命令行参数(原始字节数组)
49     #[allow(dead_code)]
boot_cmdline(&self) -> &[u8]50     pub fn boot_cmdline(&self) -> &[u8] {
51         &self.boot_command_line
52     }
53 
54     /// 开机命令行参数字符串
boot_cmdline_str(&self) -> &str55     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`:追加的数据
boot_cmdline_append(&mut self, data: &[u8])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)]
fdt(&self) -> Option<VirtAddr>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)]
fdt_paddr(&self) -> Option<PhysAddr>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