boot.rs 5.0 KB

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