ostd/arch/x86/boot/
mod.rs1mod linux_boot;
23mod multiboot;
24mod multiboot2;
25mod pvh;
26
27pub(crate) mod smp;
28
29use core::{arch::global_asm, num::NonZeroUsize};
30
31use acpi::rsdp::Rsdp;
32
33use crate::{
34 arch::kernel::acpi::AcpiMemoryHandler,
35 boot::{
36 BootloaderAcpiArg, BootloaderFramebufferArg, EarlyBootInfo,
37 memory_region::{MemoryRegion, MemoryRegionArray, MemoryRegionType},
38 },
39};
40
41global_asm!(
42 include_str!("bsp_boot.S"),
43 KCODE64 = const super::trap::gdt::KCODE64,
44 KDATA = const super::trap::gdt::KDATA,
45 KCODE32 = const super::trap::gdt::KCODE32,
46);
47global_asm!(include_str!("ap_boot.S"));
48
49trait ToEarlyBootInfo {
51 fn bootloader_name(&self) -> &'static str;
53
54 fn kernel_commandline(&self) -> Option<&'static str>;
56
57 fn initramfs(&self) -> Option<&'static [u8]>;
59
60 fn acpi_arg(&self) -> BootloaderAcpiArg;
62
63 fn framebuffer_arg(&self) -> Option<BootloaderFramebufferArg>;
65
66 fn memory_regions(
69 &self,
70 initramfs: Option<&'static [u8]>,
71 kernel_cmdline: Option<&'static str>,
72 framebuffer_arg: Option<BootloaderFramebufferArg>,
73 ) -> MemoryRegionArray;
74
75 fn to_early_boot_info(&self) -> EarlyBootInfo {
77 let kernel_cmdline = self.kernel_commandline();
78 let initramfs = self.initramfs();
79 let framebuffer_arg = self.framebuffer_arg();
80
81 EarlyBootInfo {
82 bootloader_name: self.bootloader_name(),
83 kernel_cmdline: kernel_cmdline.unwrap_or(""),
84 initramfs,
85 acpi_arg: self.acpi_arg(),
86 framebuffer_arg,
87 memory_regions: self.memory_regions(initramfs, kernel_cmdline, framebuffer_arg),
88 }
89 }
90}
91
92fn finish_memory_regions(
95 mut regions: MemoryRegionArray,
96 framebuffer_arg: Option<BootloaderFramebufferArg>,
97 initramfs: Option<&'static [u8]>,
98 kernel_cmdline: Option<&'static str>,
99) -> MemoryRegionArray {
100 if let Some(fb) = framebuffer_arg {
102 regions.push(MemoryRegion::framebuffer(&fb)).unwrap();
103 }
104
105 regions.push(MemoryRegion::kernel()).unwrap();
107
108 if let Some(initramfs) = initramfs {
110 regions.push(MemoryRegion::module(initramfs)).unwrap();
111 }
112
113 regions.push(smp::reclaimable_memory_region()).unwrap();
115
116 if let Some(kcmdline) = kernel_cmdline {
118 regions
119 .push(MemoryRegion::module(kcmdline.as_bytes()))
120 .unwrap();
121 }
122
123 regions.into_non_overlapping()
124}
125
126fn find_acpi_root_table_address() -> Option<NonZeroUsize> {
128 let Ok(rsdp) = (unsafe { Rsdp::search_for_on_bios(AcpiMemoryHandler {}) }) else {
136 return None;
137 };
138
139 if rsdp.revision() == 0 {
140 NonZeroUsize::new(rsdp.rsdt_address() as usize)
141 } else {
142 NonZeroUsize::new(rsdp.xsdt_address() as usize)
143 }
144}
145
146fn effective_region_type(
148 typ: MemoryRegionType,
149 base: usize,
150 len: usize,
151 acpi_root_table_address: Option<NonZeroUsize>,
152) -> MemoryRegionType {
153 if typ == MemoryRegionType::Reserved
154 && acpi_root_table_address.is_some_and(|addr| (base..(base + len)).contains(&addr.get()))
155 {
156 MemoryRegionType::Reclaimable
157 } else {
158 typ
159 }
160}