boot.rs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417
  1. use alloc::string::ToString;
  2. use alloc::sync::{Arc, Weak};
  3. use core::any::Any;
  4. use core::cmp::min;
  5. use acpi::rsdp::Rsdp;
  6. use alloc::string::String;
  7. use system_error::SystemError;
  8. use crate::driver::base::kobject::KObjectState;
  9. use crate::filesystem::vfs::syscall::ModeType;
  10. use crate::init::initcall::INITCALL_POSTCORE;
  11. use crate::libs::rwlock::RwLockReadGuard;
  12. use crate::libs::rwlock::RwLockWriteGuard;
  13. use crate::libs::spinlock::{SpinLock, SpinLockGuard};
  14. use crate::{
  15. arch::init::ArchBootParams,
  16. driver::video::fbdev::base::BootTimeScreenInfo,
  17. filesystem::kernfs::KernFSInode,
  18. filesystem::sysfs::{Attribute, AttributeGroup, SysFSOps, SysFSOpsSupport, SYSFS_ATTR_MODE_RO},
  19. libs::lazy_init::Lazy,
  20. misc::ksysfs::sys_kernel_kobj,
  21. mm::{PhysAddr, VirtAddr},
  22. };
  23. use unified_init::macros::unified_init;
  24. use crate::driver::base::{
  25. kobject::{KObjType, KObject, KObjectManager, KObjectSysFSOps, LockedKObjectState},
  26. kset::KSet,
  27. };
  28. /// `/sys/kernel/boot_params`的 kobject, 需要这里加一个引用来保持持久化, 不然会被释放
  29. static mut SYS_KERNEL_BOOT_PARAMS_INSTANCE: Option<Arc<BootParamsSys>> = None;
  30. #[inline(always)]
  31. #[allow(dead_code)]
  32. pub fn sys_kernel_boot_params() -> Arc<BootParamsSys> {
  33. unsafe { SYS_KERNEL_BOOT_PARAMS_INSTANCE.clone().unwrap() }
  34. }
  35. use super::boot_params;
  36. #[derive(Debug)]
  37. pub struct BootParams {
  38. pub screen_info: BootTimeScreenInfo,
  39. bootloader_name: Option<String>,
  40. #[allow(dead_code)]
  41. pub arch: ArchBootParams,
  42. boot_command_line: [u8; Self::BOOT_COMMAND_LINE_SIZE],
  43. pub acpi: BootloaderAcpiArg,
  44. }
  45. impl BootParams {
  46. const DEFAULT: Self = BootParams {
  47. screen_info: BootTimeScreenInfo::DEFAULT,
  48. bootloader_name: None,
  49. arch: ArchBootParams::DEFAULT,
  50. boot_command_line: [0u8; Self::BOOT_COMMAND_LINE_SIZE],
  51. acpi: BootloaderAcpiArg::NotProvided,
  52. };
  53. /// 开机命令行参数字符串最大大小
  54. pub const BOOT_COMMAND_LINE_SIZE: usize = 2048;
  55. pub(super) const fn new() -> Self {
  56. Self::DEFAULT
  57. }
  58. /// 开机命令行参数(原始字节数组)
  59. #[allow(dead_code)]
  60. pub fn boot_cmdline(&self) -> &[u8] {
  61. &self.boot_command_line
  62. }
  63. /// 开机命令行参数字符串
  64. pub fn boot_cmdline_str(&self) -> &str {
  65. core::str::from_utf8(&self.boot_cmdline()[..self.boot_cmdline_len()]).unwrap()
  66. }
  67. #[allow(dead_code)]
  68. pub fn bootloader_name(&self) -> Option<&str> {
  69. self.bootloader_name.as_deref()
  70. }
  71. pub fn boot_cmdline_len(&self) -> usize {
  72. self.boot_command_line
  73. .iter()
  74. .position(|&x| x == 0)
  75. .unwrap_or(self.boot_command_line.len())
  76. }
  77. /// 追加开机命令行参数
  78. ///
  79. /// 如果开机命令行参数已经满了,则不会追加。
  80. /// 如果超过了最大长度,则截断。
  81. ///
  82. /// ## 参数
  83. ///
  84. /// - `data`:追加的数据
  85. pub fn boot_cmdline_append(&mut self, data: &[u8]) {
  86. if data.is_empty() {
  87. return;
  88. }
  89. let mut pos: Option<usize> = None;
  90. // 寻找结尾
  91. for (i, x) in self.boot_command_line.iter().enumerate() {
  92. if *x == 0 {
  93. pos = Some(i);
  94. break;
  95. }
  96. }
  97. let pos = pos.unwrap_or(self.boot_command_line.len() - 1) as isize;
  98. let avail = self.boot_command_line.len() as isize - pos - 1;
  99. if avail <= 0 {
  100. return;
  101. }
  102. let len = min(avail as usize, data.len());
  103. let pos = pos as usize;
  104. self.boot_command_line[pos..pos + len].copy_from_slice(&data[0..len]);
  105. self.boot_command_line[pos + len] = 0;
  106. }
  107. /// 获取FDT的虚拟地址
  108. #[allow(dead_code)]
  109. pub fn fdt(&self) -> Option<VirtAddr> {
  110. #[cfg(target_arch = "riscv64")]
  111. return Some(self.arch.arch_fdt());
  112. #[cfg(any(target_arch = "x86_64", target_arch = "loongarch64"))]
  113. return None;
  114. }
  115. /// 获取FDT的物理地址
  116. #[allow(dead_code)]
  117. pub fn fdt_paddr(&self) -> Option<PhysAddr> {
  118. #[cfg(target_arch = "riscv64")]
  119. return Some(self.arch.fdt_paddr);
  120. #[cfg(any(target_arch = "x86_64", target_arch = "loongarch64"))]
  121. return None;
  122. }
  123. }
  124. /// 开机引导回调,用于初始化内核启动参数
  125. pub trait BootCallbacks: Send + Sync {
  126. /// 初始化引导程序名称
  127. fn init_bootloader_name(&self) -> Result<Option<String>, SystemError>;
  128. /// 初始化ACPI参数
  129. fn init_acpi_args(&self) -> Result<BootloaderAcpiArg, SystemError>;
  130. /// 初始化内核命令行参数
  131. ///
  132. /// 该函数应该把内核命令行参数追加到`boot_params().boot_cmdline`中
  133. fn init_kernel_cmdline(&self) -> Result<(), SystemError>;
  134. /// 初始化initramfs
  135. ///
  136. /// 该函数会检索[外部initramfs]追加到`boot_params().initramfs`中,
  137. /// [外部initramfs] 指由bootloader加载的,如qemu的 -initrd 参数
  138. #[allow(dead_code)]
  139. fn init_initramfs(&self) -> Result<(), SystemError>;
  140. /// 初始化帧缓冲区信息
  141. ///
  142. /// - 该函数应该把帧缓冲区信息写入`scinfo`中。
  143. /// - 该函数应该在内存管理初始化之前调用。
  144. fn early_init_framebuffer_info(
  145. &self,
  146. scinfo: &mut BootTimeScreenInfo,
  147. ) -> Result<(), SystemError>;
  148. // TODO: 下面三个应该合成一个, 都存到 arch/boot_params(linux是这样的)
  149. /// 初始化内存块
  150. fn early_init_memory_blocks(&self) -> Result<(), SystemError>;
  151. /// 初始化内存 memmap 信息到 sysfs
  152. fn early_init_memmap_sysfs(&self) -> Result<(), SystemError>;
  153. /// 初始化内存 memmap 信息到 boot_params
  154. fn init_memmap_bp(&self) -> Result<(), SystemError>;
  155. }
  156. static BOOT_CALLBACKS: Lazy<&'static dyn BootCallbacks> = Lazy::new();
  157. /// 注册开机引导回调
  158. pub fn register_boot_callbacks(callbacks: &'static dyn BootCallbacks) {
  159. BOOT_CALLBACKS.init(callbacks);
  160. }
  161. /// 获取开机引导回调
  162. pub fn boot_callbacks() -> &'static dyn BootCallbacks {
  163. let p = BOOT_CALLBACKS
  164. .try_get()
  165. .expect("Boot callbacks not initialized");
  166. *p
  167. }
  168. pub(super) fn boot_callback_except_early() {
  169. let mut boot_params = boot_params().write();
  170. boot_params.bootloader_name = boot_callbacks()
  171. .init_bootloader_name()
  172. .expect("Failed to init bootloader name");
  173. boot_params.acpi = boot_callbacks()
  174. .init_acpi_args()
  175. .unwrap_or(BootloaderAcpiArg::NotProvided);
  176. }
  177. /// ACPI information from the bootloader.
  178. #[derive(Copy, Clone, Debug)]
  179. pub enum BootloaderAcpiArg {
  180. /// The bootloader does not provide one, a manual search is needed.
  181. NotProvided,
  182. /// Physical address of the RSDP.
  183. #[allow(dead_code)]
  184. Rsdp(PhysAddr),
  185. /// Address of RSDT provided in RSDP v1.
  186. Rsdt(Rsdp),
  187. /// Address of XSDT provided in RSDP v2+.
  188. Xsdt(Rsdp),
  189. }
  190. /// 初始化boot_params模块在sysfs中的目录
  191. #[unified_init(INITCALL_POSTCORE)]
  192. fn bootparams_sysfs_init() -> Result<(), SystemError> {
  193. let bp = BootParamsSys::new("boot_params".to_string());
  194. unsafe {
  195. SYS_KERNEL_BOOT_PARAMS_INSTANCE = Some(bp.clone());
  196. }
  197. let kobj = sys_kernel_kobj();
  198. bp.set_parent(Some(Arc::downgrade(&(kobj as Arc<dyn KObject>))));
  199. KObjectManager::add_kobj(bp.clone() as Arc<dyn KObject>).unwrap_or_else(|e| {
  200. log::warn!("Failed to add boot_params kobject to sysfs: {:?}", e);
  201. });
  202. return Ok(());
  203. }
  204. #[derive(Debug)]
  205. pub struct BootParamsSys {
  206. inner: SpinLock<BootParamsSysInner>,
  207. kobj_state: LockedKObjectState,
  208. name: String,
  209. }
  210. #[derive(Debug)]
  211. pub struct BootParamsSysInner {
  212. kern_inode: Option<Arc<KernFSInode>>,
  213. kset: Option<Arc<KSet>>,
  214. parent_kobj: Option<Weak<dyn KObject>>,
  215. }
  216. #[derive(Debug)]
  217. struct BootParamsAttrGroup;
  218. impl AttributeGroup for BootParamsAttrGroup {
  219. fn name(&self) -> Option<&str> {
  220. None
  221. }
  222. fn attrs(&self) -> &[&'static dyn Attribute] {
  223. &[&AttrData, &AttrVersion]
  224. }
  225. fn is_visible(
  226. &self,
  227. _kobj: Arc<dyn KObject>,
  228. attr: &'static dyn Attribute,
  229. ) -> Option<ModeType> {
  230. Some(attr.mode())
  231. }
  232. }
  233. #[derive(Debug)]
  234. pub struct BootParamsKObjType;
  235. impl KObjType for BootParamsKObjType {
  236. fn sysfs_ops(&self) -> Option<&dyn SysFSOps> {
  237. Some(&KObjectSysFSOps)
  238. }
  239. fn attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]> {
  240. Some(&[&BootParamsAttrGroup])
  241. }
  242. fn release(&self, _kobj: Arc<dyn KObject>) {}
  243. }
  244. impl BootParamsSys {
  245. pub fn new(name: String) -> Arc<Self> {
  246. let bp = BootParamsSys {
  247. inner: SpinLock::new(BootParamsSysInner {
  248. kern_inode: None,
  249. kset: None,
  250. parent_kobj: None,
  251. }),
  252. kobj_state: LockedKObjectState::new(Some(KObjectState::INITIALIZED)),
  253. name: name.clone(),
  254. };
  255. Arc::new(bp)
  256. }
  257. pub fn inner(&self) -> SpinLockGuard<'_, BootParamsSysInner> {
  258. self.inner.lock_irqsave()
  259. }
  260. }
  261. impl KObject for BootParamsSys {
  262. fn as_any_ref(&self) -> &dyn Any {
  263. self
  264. }
  265. fn set_inode(&self, inode: Option<Arc<KernFSInode>>) {
  266. self.inner().kern_inode = inode;
  267. }
  268. fn inode(&self) -> Option<Arc<KernFSInode>> {
  269. self.inner().kern_inode.clone()
  270. }
  271. fn parent(&self) -> Option<Weak<dyn KObject>> {
  272. self.inner().parent_kobj.clone()
  273. }
  274. fn set_parent(&self, parent: Option<Weak<dyn KObject>>) {
  275. self.inner().parent_kobj = parent;
  276. }
  277. fn kset(&self) -> Option<Arc<KSet>> {
  278. self.inner().kset.clone()
  279. }
  280. fn set_kset(&self, kset: Option<Arc<KSet>>) {
  281. self.inner().kset = kset;
  282. }
  283. fn kobj_type(&self) -> Option<&'static dyn KObjType> {
  284. Some(&BootParamsKObjType)
  285. }
  286. fn set_kobj_type(&self, _ktype: Option<&'static dyn KObjType>) {}
  287. fn name(&self) -> String {
  288. self.name.clone()
  289. }
  290. fn set_name(&self, _name: String) {}
  291. fn kobj_state(&self) -> RwLockReadGuard<'_, KObjectState> {
  292. self.kobj_state.read()
  293. }
  294. fn kobj_state_mut(&self) -> RwLockWriteGuard<'_, KObjectState> {
  295. self.kobj_state.write()
  296. }
  297. fn set_kobj_state(&self, state: KObjectState) {
  298. *self.kobj_state_mut() = state;
  299. }
  300. }
  301. #[derive(Debug)]
  302. struct AttrData;
  303. impl Attribute for AttrData {
  304. fn name(&self) -> &str {
  305. "data"
  306. }
  307. fn mode(&self) -> ModeType {
  308. SYSFS_ATTR_MODE_RO
  309. }
  310. fn support(&self) -> SysFSOpsSupport {
  311. SysFSOpsSupport::ATTR_SHOW
  312. }
  313. fn show(&self, _kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> {
  314. let mut bp = boot_params().write();
  315. // 下面boot_params不应该用这些函数初始化, 详情见这些函数里的注释
  316. bp.arch.set_alt_mem_k(0x7fb40);
  317. bp.arch.set_scratch(0x10000d);
  318. bp.arch.init_setupheader();
  319. let bp_buf = bp.arch.convert_to_buf();
  320. let len = core::cmp::min(bp_buf.len(), buf.len());
  321. buf[..len].copy_from_slice(&bp_buf[..len]);
  322. Ok(buf.len())
  323. }
  324. }
  325. #[derive(Debug)]
  326. struct AttrVersion;
  327. impl Attribute for AttrVersion {
  328. fn name(&self) -> &str {
  329. "version"
  330. }
  331. fn mode(&self) -> ModeType {
  332. SYSFS_ATTR_MODE_RO
  333. }
  334. fn support(&self) -> SysFSOpsSupport {
  335. SysFSOpsSupport::ATTR_SHOW
  336. }
  337. fn show(&self, _kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> {
  338. #[cfg(target_arch = "x86_64")]
  339. let version = boot_params().read().arch.hdr.version;
  340. #[cfg(not(target_arch = "x86_64"))]
  341. let version = 0;
  342. let version = format!("{:#x}\n", version);
  343. let len = min(version.len(), buf.len());
  344. buf[..len].copy_from_slice(version.as_bytes());
  345. return Ok(len);
  346. }
  347. }