xref: /DragonOS/kernel/src/init/boot.rs (revision db7c782a9aaacb320027167bda4f23751b8f36e1)
12b7818e8SLoGin use core::cmp::min;
22b7818e8SLoGin 
32b7818e8SLoGin use acpi::rsdp::Rsdp;
42b7818e8SLoGin use alloc::string::String;
52b7818e8SLoGin use system_error::SystemError;
62b7818e8SLoGin 
72b7818e8SLoGin use crate::{
82b7818e8SLoGin     arch::init::ArchBootParams,
92b7818e8SLoGin     driver::video::fbdev::base::BootTimeScreenInfo,
102b7818e8SLoGin     libs::lazy_init::Lazy,
112b7818e8SLoGin     mm::{PhysAddr, VirtAddr},
122b7818e8SLoGin };
132b7818e8SLoGin 
142b7818e8SLoGin use super::boot_params;
152b7818e8SLoGin #[derive(Debug)]
162b7818e8SLoGin pub struct BootParams {
172b7818e8SLoGin     pub screen_info: BootTimeScreenInfo,
182b7818e8SLoGin     bootloader_name: Option<String>,
192b7818e8SLoGin     #[allow(dead_code)]
202b7818e8SLoGin     pub arch: ArchBootParams,
212b7818e8SLoGin     boot_command_line: [u8; Self::BOOT_COMMAND_LINE_SIZE],
222b7818e8SLoGin     pub acpi: BootloaderAcpiArg,
232b7818e8SLoGin }
242b7818e8SLoGin 
252b7818e8SLoGin impl BootParams {
262b7818e8SLoGin     const DEFAULT: Self = BootParams {
272b7818e8SLoGin         screen_info: BootTimeScreenInfo::DEFAULT,
282b7818e8SLoGin         bootloader_name: None,
292b7818e8SLoGin         arch: ArchBootParams::DEFAULT,
302b7818e8SLoGin         boot_command_line: [0u8; Self::BOOT_COMMAND_LINE_SIZE],
312b7818e8SLoGin         acpi: BootloaderAcpiArg::NotProvided,
322b7818e8SLoGin     };
332b7818e8SLoGin 
342b7818e8SLoGin     /// 开机命令行参数字符串最大大小
352b7818e8SLoGin     pub const BOOT_COMMAND_LINE_SIZE: usize = 2048;
362b7818e8SLoGin 
new() -> Self372b7818e8SLoGin     pub(super) const fn new() -> Self {
382b7818e8SLoGin         Self::DEFAULT
392b7818e8SLoGin     }
402b7818e8SLoGin 
412b7818e8SLoGin     /// 开机命令行参数(原始字节数组)
422b7818e8SLoGin     #[allow(dead_code)]
boot_cmdline(&self) -> &[u8]432b7818e8SLoGin     pub fn boot_cmdline(&self) -> &[u8] {
442b7818e8SLoGin         &self.boot_command_line
452b7818e8SLoGin     }
462b7818e8SLoGin 
472b7818e8SLoGin     /// 开机命令行参数字符串
boot_cmdline_str(&self) -> &str482b7818e8SLoGin     pub fn boot_cmdline_str(&self) -> &str {
492b7818e8SLoGin         core::str::from_utf8(self.boot_cmdline()).unwrap()
502b7818e8SLoGin     }
512b7818e8SLoGin 
bootloader_name(&self) -> Option<&str>522b7818e8SLoGin     pub fn bootloader_name(&self) -> Option<&str> {
532b7818e8SLoGin         self.bootloader_name.as_deref()
542b7818e8SLoGin     }
552b7818e8SLoGin 
562b7818e8SLoGin     /// 追加开机命令行参数
572b7818e8SLoGin     ///
582b7818e8SLoGin     /// 如果开机命令行参数已经满了,则不会追加。
592b7818e8SLoGin     /// 如果超过了最大长度,则截断。
602b7818e8SLoGin     ///
612b7818e8SLoGin     /// ## 参数
622b7818e8SLoGin     ///
632b7818e8SLoGin     /// - `data`:追加的数据
boot_cmdline_append(&mut self, data: &[u8])642b7818e8SLoGin     pub fn boot_cmdline_append(&mut self, data: &[u8]) {
652b7818e8SLoGin         if data.is_empty() {
662b7818e8SLoGin             return;
672b7818e8SLoGin         }
682b7818e8SLoGin 
692b7818e8SLoGin         let mut pos: Option<usize> = None;
702b7818e8SLoGin         // 寻找结尾
712b7818e8SLoGin         for (i, x) in self.boot_command_line.iter().enumerate() {
722b7818e8SLoGin             if *x == 0 {
732b7818e8SLoGin                 pos = Some(i);
742b7818e8SLoGin                 break;
752b7818e8SLoGin             }
762b7818e8SLoGin         }
772b7818e8SLoGin         let pos = pos.unwrap_or(self.boot_command_line.len() - 1) as isize;
782b7818e8SLoGin 
792b7818e8SLoGin         let avail = self.boot_command_line.len() as isize - pos - 1;
802b7818e8SLoGin         if avail <= 0 {
812b7818e8SLoGin             return;
822b7818e8SLoGin         }
832b7818e8SLoGin 
842b7818e8SLoGin         let len = min(avail as usize, data.len());
852b7818e8SLoGin         let pos = pos as usize;
862b7818e8SLoGin         self.boot_command_line[pos..pos + len].copy_from_slice(&data[0..len]);
872b7818e8SLoGin 
882b7818e8SLoGin         self.boot_command_line[pos + len] = 0;
892b7818e8SLoGin     }
902b7818e8SLoGin 
912b7818e8SLoGin     /// 获取FDT的虚拟地址
922b7818e8SLoGin     #[allow(dead_code)]
fdt(&self) -> Option<VirtAddr>932b7818e8SLoGin     pub fn fdt(&self) -> Option<VirtAddr> {
942b7818e8SLoGin         #[cfg(target_arch = "riscv64")]
952b7818e8SLoGin         return Some(self.arch.arch_fdt());
962b7818e8SLoGin 
972b7818e8SLoGin         #[cfg(target_arch = "x86_64")]
982b7818e8SLoGin         return None;
992b7818e8SLoGin     }
1002b7818e8SLoGin 
1012b7818e8SLoGin     /// 获取FDT的物理地址
1022b7818e8SLoGin     #[allow(dead_code)]
fdt_paddr(&self) -> Option<PhysAddr>1032b7818e8SLoGin     pub fn fdt_paddr(&self) -> Option<PhysAddr> {
1042b7818e8SLoGin         #[cfg(target_arch = "riscv64")]
1052b7818e8SLoGin         return Some(self.arch.fdt_paddr);
1062b7818e8SLoGin 
1072b7818e8SLoGin         #[cfg(target_arch = "x86_64")]
1082b7818e8SLoGin         return None;
1092b7818e8SLoGin     }
1102b7818e8SLoGin }
1112b7818e8SLoGin 
1122b7818e8SLoGin /// 开机引导回调,用于初始化内核启动参数
1132b7818e8SLoGin pub trait BootCallbacks: Send + Sync {
1142b7818e8SLoGin     /// 初始化引导程序名称
init_bootloader_name(&self) -> Result<Option<String>, SystemError>1152b7818e8SLoGin     fn init_bootloader_name(&self) -> Result<Option<String>, SystemError>;
1162b7818e8SLoGin     /// 初始化ACPI参数
init_acpi_args(&self) -> Result<BootloaderAcpiArg, SystemError>1172b7818e8SLoGin     fn init_acpi_args(&self) -> Result<BootloaderAcpiArg, SystemError>;
1182b7818e8SLoGin     /// 初始化内核命令行参数
1192b7818e8SLoGin     ///
1202b7818e8SLoGin     /// 该函数应该把内核命令行参数追加到`boot_params().boot_cmdline`中
init_kernel_cmdline(&self) -> Result<(), SystemError>1212b7818e8SLoGin     fn init_kernel_cmdline(&self) -> Result<(), SystemError>;
1222b7818e8SLoGin     /// 初始化帧缓冲区信息
1232b7818e8SLoGin     ///
1242b7818e8SLoGin     /// - 该函数应该把帧缓冲区信息写入`scinfo`中。
1252b7818e8SLoGin     /// - 该函数应该在内存管理初始化之前调用。
early_init_framebuffer_info( &self, scinfo: &mut BootTimeScreenInfo, ) -> Result<(), SystemError>1262b7818e8SLoGin     fn early_init_framebuffer_info(
1272b7818e8SLoGin         &self,
1282b7818e8SLoGin         scinfo: &mut BootTimeScreenInfo,
1292b7818e8SLoGin     ) -> Result<(), SystemError>;
1302b7818e8SLoGin 
1312b7818e8SLoGin     /// 初始化内存块
early_init_memory_blocks(&self) -> Result<(), SystemError>1322b7818e8SLoGin     fn early_init_memory_blocks(&self) -> Result<(), SystemError>;
1332b7818e8SLoGin }
1342b7818e8SLoGin 
1352b7818e8SLoGin static BOOT_CALLBACKS: Lazy<&'static dyn BootCallbacks> = Lazy::new();
1362b7818e8SLoGin 
1372b7818e8SLoGin /// 注册开机引导回调
register_boot_callbacks(callbacks: &'static dyn BootCallbacks)1382b7818e8SLoGin pub fn register_boot_callbacks(callbacks: &'static dyn BootCallbacks) {
1392b7818e8SLoGin     BOOT_CALLBACKS.init(callbacks);
1402b7818e8SLoGin }
1412b7818e8SLoGin 
1422b7818e8SLoGin /// 获取开机引导回调
boot_callbacks() -> &'static dyn BootCallbacks1432b7818e8SLoGin pub fn boot_callbacks() -> &'static dyn BootCallbacks {
1442b7818e8SLoGin     let p = BOOT_CALLBACKS
1452b7818e8SLoGin         .try_get()
1462b7818e8SLoGin         .expect("Boot callbacks not initialized");
1472b7818e8SLoGin 
1482b7818e8SLoGin     *p
1492b7818e8SLoGin }
1502b7818e8SLoGin 
boot_callback_except_early()1512b7818e8SLoGin pub(super) fn boot_callback_except_early() {
1522b7818e8SLoGin     boot_callbacks()
1532b7818e8SLoGin         .init_kernel_cmdline()
154*db7c782aSLoGin         .inspect_err(|e| {
155*db7c782aSLoGin             log::error!("Failed to init kernel cmdline: {:?}", e);
156*db7c782aSLoGin         })
157*db7c782aSLoGin         .ok();
158*db7c782aSLoGin 
1592b7818e8SLoGin     let mut boot_params = boot_params().write();
1602b7818e8SLoGin     boot_params.bootloader_name = boot_callbacks()
1612b7818e8SLoGin         .init_bootloader_name()
1622b7818e8SLoGin         .expect("Failed to init bootloader name");
1632b7818e8SLoGin     boot_params.acpi = boot_callbacks()
1642b7818e8SLoGin         .init_acpi_args()
1652b7818e8SLoGin         .unwrap_or(BootloaderAcpiArg::NotProvided);
1662b7818e8SLoGin }
1672b7818e8SLoGin 
1682b7818e8SLoGin /// ACPI information from the bootloader.
1692b7818e8SLoGin #[derive(Copy, Clone, Debug)]
1702b7818e8SLoGin pub enum BootloaderAcpiArg {
1712b7818e8SLoGin     /// The bootloader does not provide one, a manual search is needed.
1722b7818e8SLoGin     NotProvided,
1732b7818e8SLoGin     /// Physical address of the RSDP.
1742b7818e8SLoGin     #[allow(dead_code)]
1752b7818e8SLoGin     Rsdp(PhysAddr),
1762b7818e8SLoGin     /// Address of RSDT provided in RSDP v1.
1772b7818e8SLoGin     Rsdt(Rsdp),
1782b7818e8SLoGin     /// Address of XSDT provided in RSDP v2+.
1792b7818e8SLoGin     Xsdt(Rsdp),
1802b7818e8SLoGin }
181