1*2b7818e8SLoGin use core::cmp::min; 2*2b7818e8SLoGin 3*2b7818e8SLoGin use acpi::rsdp::Rsdp; 4*2b7818e8SLoGin use alloc::string::String; 5*2b7818e8SLoGin use system_error::SystemError; 6*2b7818e8SLoGin 7*2b7818e8SLoGin use crate::{ 8*2b7818e8SLoGin arch::init::ArchBootParams, 9*2b7818e8SLoGin driver::video::fbdev::base::BootTimeScreenInfo, 10*2b7818e8SLoGin libs::lazy_init::Lazy, 11*2b7818e8SLoGin mm::{PhysAddr, VirtAddr}, 12*2b7818e8SLoGin }; 13*2b7818e8SLoGin 14*2b7818e8SLoGin use super::boot_params; 15*2b7818e8SLoGin #[derive(Debug)] 16*2b7818e8SLoGin pub struct BootParams { 17*2b7818e8SLoGin pub screen_info: BootTimeScreenInfo, 18*2b7818e8SLoGin bootloader_name: Option<String>, 19*2b7818e8SLoGin #[allow(dead_code)] 20*2b7818e8SLoGin pub arch: ArchBootParams, 21*2b7818e8SLoGin boot_command_line: [u8; Self::BOOT_COMMAND_LINE_SIZE], 22*2b7818e8SLoGin pub acpi: BootloaderAcpiArg, 23*2b7818e8SLoGin } 24*2b7818e8SLoGin 25*2b7818e8SLoGin impl BootParams { 26*2b7818e8SLoGin const DEFAULT: Self = BootParams { 27*2b7818e8SLoGin screen_info: BootTimeScreenInfo::DEFAULT, 28*2b7818e8SLoGin bootloader_name: None, 29*2b7818e8SLoGin arch: ArchBootParams::DEFAULT, 30*2b7818e8SLoGin boot_command_line: [0u8; Self::BOOT_COMMAND_LINE_SIZE], 31*2b7818e8SLoGin acpi: BootloaderAcpiArg::NotProvided, 32*2b7818e8SLoGin }; 33*2b7818e8SLoGin 34*2b7818e8SLoGin /// 开机命令行参数字符串最大大小 35*2b7818e8SLoGin pub const BOOT_COMMAND_LINE_SIZE: usize = 2048; 36*2b7818e8SLoGin 37*2b7818e8SLoGin pub(super) const fn new() -> Self { 38*2b7818e8SLoGin Self::DEFAULT 39*2b7818e8SLoGin } 40*2b7818e8SLoGin 41*2b7818e8SLoGin /// 开机命令行参数(原始字节数组) 42*2b7818e8SLoGin #[allow(dead_code)] 43*2b7818e8SLoGin pub fn boot_cmdline(&self) -> &[u8] { 44*2b7818e8SLoGin &self.boot_command_line 45*2b7818e8SLoGin } 46*2b7818e8SLoGin 47*2b7818e8SLoGin /// 开机命令行参数字符串 48*2b7818e8SLoGin pub fn boot_cmdline_str(&self) -> &str { 49*2b7818e8SLoGin core::str::from_utf8(self.boot_cmdline()).unwrap() 50*2b7818e8SLoGin } 51*2b7818e8SLoGin 52*2b7818e8SLoGin pub fn bootloader_name(&self) -> Option<&str> { 53*2b7818e8SLoGin self.bootloader_name.as_deref() 54*2b7818e8SLoGin } 55*2b7818e8SLoGin 56*2b7818e8SLoGin /// 追加开机命令行参数 57*2b7818e8SLoGin /// 58*2b7818e8SLoGin /// 如果开机命令行参数已经满了,则不会追加。 59*2b7818e8SLoGin /// 如果超过了最大长度,则截断。 60*2b7818e8SLoGin /// 61*2b7818e8SLoGin /// ## 参数 62*2b7818e8SLoGin /// 63*2b7818e8SLoGin /// - `data`:追加的数据 64*2b7818e8SLoGin pub fn boot_cmdline_append(&mut self, data: &[u8]) { 65*2b7818e8SLoGin if data.is_empty() { 66*2b7818e8SLoGin return; 67*2b7818e8SLoGin } 68*2b7818e8SLoGin 69*2b7818e8SLoGin let mut pos: Option<usize> = None; 70*2b7818e8SLoGin // 寻找结尾 71*2b7818e8SLoGin for (i, x) in self.boot_command_line.iter().enumerate() { 72*2b7818e8SLoGin if *x == 0 { 73*2b7818e8SLoGin pos = Some(i); 74*2b7818e8SLoGin break; 75*2b7818e8SLoGin } 76*2b7818e8SLoGin } 77*2b7818e8SLoGin let pos = pos.unwrap_or(self.boot_command_line.len() - 1) as isize; 78*2b7818e8SLoGin 79*2b7818e8SLoGin let avail = self.boot_command_line.len() as isize - pos - 1; 80*2b7818e8SLoGin if avail <= 0 { 81*2b7818e8SLoGin return; 82*2b7818e8SLoGin } 83*2b7818e8SLoGin 84*2b7818e8SLoGin let len = min(avail as usize, data.len()); 85*2b7818e8SLoGin let pos = pos as usize; 86*2b7818e8SLoGin self.boot_command_line[pos..pos + len].copy_from_slice(&data[0..len]); 87*2b7818e8SLoGin 88*2b7818e8SLoGin self.boot_command_line[pos + len] = 0; 89*2b7818e8SLoGin } 90*2b7818e8SLoGin 91*2b7818e8SLoGin /// 获取FDT的虚拟地址 92*2b7818e8SLoGin #[allow(dead_code)] 93*2b7818e8SLoGin pub fn fdt(&self) -> Option<VirtAddr> { 94*2b7818e8SLoGin #[cfg(target_arch = "riscv64")] 95*2b7818e8SLoGin return Some(self.arch.arch_fdt()); 96*2b7818e8SLoGin 97*2b7818e8SLoGin #[cfg(target_arch = "x86_64")] 98*2b7818e8SLoGin return None; 99*2b7818e8SLoGin } 100*2b7818e8SLoGin 101*2b7818e8SLoGin /// 获取FDT的物理地址 102*2b7818e8SLoGin #[allow(dead_code)] 103*2b7818e8SLoGin pub fn fdt_paddr(&self) -> Option<PhysAddr> { 104*2b7818e8SLoGin #[cfg(target_arch = "riscv64")] 105*2b7818e8SLoGin return Some(self.arch.fdt_paddr); 106*2b7818e8SLoGin 107*2b7818e8SLoGin #[cfg(target_arch = "x86_64")] 108*2b7818e8SLoGin return None; 109*2b7818e8SLoGin } 110*2b7818e8SLoGin } 111*2b7818e8SLoGin 112*2b7818e8SLoGin /// 开机引导回调,用于初始化内核启动参数 113*2b7818e8SLoGin pub trait BootCallbacks: Send + Sync { 114*2b7818e8SLoGin /// 初始化引导程序名称 115*2b7818e8SLoGin fn init_bootloader_name(&self) -> Result<Option<String>, SystemError>; 116*2b7818e8SLoGin /// 初始化ACPI参数 117*2b7818e8SLoGin fn init_acpi_args(&self) -> Result<BootloaderAcpiArg, SystemError>; 118*2b7818e8SLoGin /// 初始化内核命令行参数 119*2b7818e8SLoGin /// 120*2b7818e8SLoGin /// 该函数应该把内核命令行参数追加到`boot_params().boot_cmdline`中 121*2b7818e8SLoGin fn init_kernel_cmdline(&self) -> Result<(), SystemError>; 122*2b7818e8SLoGin /// 初始化帧缓冲区信息 123*2b7818e8SLoGin /// 124*2b7818e8SLoGin /// - 该函数应该把帧缓冲区信息写入`scinfo`中。 125*2b7818e8SLoGin /// - 该函数应该在内存管理初始化之前调用。 126*2b7818e8SLoGin fn early_init_framebuffer_info( 127*2b7818e8SLoGin &self, 128*2b7818e8SLoGin scinfo: &mut BootTimeScreenInfo, 129*2b7818e8SLoGin ) -> Result<(), SystemError>; 130*2b7818e8SLoGin 131*2b7818e8SLoGin /// 初始化内存块 132*2b7818e8SLoGin fn early_init_memory_blocks(&self) -> Result<(), SystemError>; 133*2b7818e8SLoGin } 134*2b7818e8SLoGin 135*2b7818e8SLoGin static BOOT_CALLBACKS: Lazy<&'static dyn BootCallbacks> = Lazy::new(); 136*2b7818e8SLoGin 137*2b7818e8SLoGin /// 注册开机引导回调 138*2b7818e8SLoGin pub fn register_boot_callbacks(callbacks: &'static dyn BootCallbacks) { 139*2b7818e8SLoGin BOOT_CALLBACKS.init(callbacks); 140*2b7818e8SLoGin } 141*2b7818e8SLoGin 142*2b7818e8SLoGin /// 获取开机引导回调 143*2b7818e8SLoGin pub fn boot_callbacks() -> &'static dyn BootCallbacks { 144*2b7818e8SLoGin let p = BOOT_CALLBACKS 145*2b7818e8SLoGin .try_get() 146*2b7818e8SLoGin .expect("Boot callbacks not initialized"); 147*2b7818e8SLoGin 148*2b7818e8SLoGin *p 149*2b7818e8SLoGin } 150*2b7818e8SLoGin 151*2b7818e8SLoGin pub(super) fn boot_callback_except_early() { 152*2b7818e8SLoGin boot_callbacks() 153*2b7818e8SLoGin .init_kernel_cmdline() 154*2b7818e8SLoGin .expect("Failed to init kernel cmdline"); 155*2b7818e8SLoGin let mut boot_params = boot_params().write(); 156*2b7818e8SLoGin boot_params.bootloader_name = boot_callbacks() 157*2b7818e8SLoGin .init_bootloader_name() 158*2b7818e8SLoGin .expect("Failed to init bootloader name"); 159*2b7818e8SLoGin boot_params.acpi = boot_callbacks() 160*2b7818e8SLoGin .init_acpi_args() 161*2b7818e8SLoGin .unwrap_or(BootloaderAcpiArg::NotProvided); 162*2b7818e8SLoGin } 163*2b7818e8SLoGin 164*2b7818e8SLoGin /// ACPI information from the bootloader. 165*2b7818e8SLoGin #[derive(Copy, Clone, Debug)] 166*2b7818e8SLoGin pub enum BootloaderAcpiArg { 167*2b7818e8SLoGin /// The bootloader does not provide one, a manual search is needed. 168*2b7818e8SLoGin NotProvided, 169*2b7818e8SLoGin /// Physical address of the RSDP. 170*2b7818e8SLoGin #[allow(dead_code)] 171*2b7818e8SLoGin Rsdp(PhysAddr), 172*2b7818e8SLoGin /// Address of RSDT provided in RSDP v1. 173*2b7818e8SLoGin Rsdt(Rsdp), 174*2b7818e8SLoGin /// Address of XSDT provided in RSDP v2+. 175*2b7818e8SLoGin Xsdt(Rsdp), 176*2b7818e8SLoGin } 177