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