Skip to main content

ostd/boot/
mod.rs

1// SPDX-License-Identifier: MPL-2.0
2//! The architecture-independent boot module, which provides
3//!  1. a universal information getter interface from the bootloader to the
4//!     rest of OSTD;
5//!  2. the routine booting into the actual kernel;
6//!  3. the routine booting the other processors in the SMP context.
7pub mod memory_region;
8//pub mod smp;
9
10/* use alloc::{
11    string::{String, ToString},
12    vec::Vec,
13}; */
14
15use memory_region::{MemoryRegion, MemoryRegionArray};
16use spin::Once;
17
18/*
19/// The boot information provided by the bootloader.
20pub struct BootInfo {
21    /// The name of the bootloader.
22    pub bootloader_name: String,
23    /// The kernel command line arguments.
24    pub kernel_cmdline: String,
25    /// The initial ramfs raw bytes.
26    pub initramfs: Option<&'static [u8]>,
27    /// The framebuffer arguments.
28    pub framebuffer_arg: Option<BootloaderFramebufferArg>,
29    /// The memory regions provided by the bootloader.
30    pub memory_regions: Vec<MemoryRegion>,
31}
32
33/// Gets the boot information.
34//
35// This function is usable after initialization with `init_after_heap`.
36pub fn boot_info() -> &'static BootInfo {
37    INFO.get().unwrap()
38}
39
40static INFO: Once<BootInfo> = Once::new();
41*/
42/// ACPI information from the bootloader.
43///
44/// The boot crate can choose either providing the raw RSDP physical address or
45/// providing the RSDT/XSDT physical address after parsing RSDP.
46/// This is because bootloaders differ in such behaviors.
47#[derive(Copy, Clone, Debug)]
48pub enum BootloaderAcpiArg {
49    /// The bootloader does not provide one, a manual search is needed.
50    NotProvided,
51    /// Physical address of the RSDP.
52    Rsdp(usize),
53    /// Address of RSDT provided in RSDP v1.
54    Rsdt(usize),
55    /// Address of XSDT provided in RSDP v2+.
56    Xsdt(usize),
57}
58
59/// The framebuffer arguments.
60#[derive(Copy, Clone, Debug)]
61pub struct BootloaderFramebufferArg {
62    /// The address of the buffer.
63    pub address: usize,
64    /// The width of the buffer.
65    pub width: usize,
66    /// The height of the buffer.
67    pub height: usize,
68    /// Bits per pixel of the buffer.
69    pub bpp: usize,
70}
71
72/*************************** Boot-time information ***************************/
73
74/// The boot-time boot information.
75///
76/// When supporting multiple boot protocols with a single build, the entrypoint
77/// and boot information getters are dynamically decided. The entry point
78/// function should initializer all arguments at [`EARLY_INFO`].
79///
80/// All the references in this structure should be valid in the boot context.
81/// After the kernel is booted, users should use [`BootInfo`] instead.
82pub(crate) struct EarlyBootInfo {
83    pub(crate) bootloader_name: &'static str,
84    pub(crate) kernel_cmdline: &'static str,
85    pub(crate) initramfs: Option<&'static [u8]>,
86    pub(crate) acpi_arg: BootloaderAcpiArg,
87    pub(crate) framebuffer_arg: Option<BootloaderFramebufferArg>,
88    pub(crate) memory_regions: MemoryRegionArray,
89}
90
91/// The boot-time information.
92pub(crate) static EARLY_INFO: Once<EarlyBootInfo> = Once::new();
93
94/*
95/// Initializes the boot information.
96///
97/// This function copies the boot-time accessible information to the heap to
98/// allow [`boot_info`] to work properly.
99pub(crate) fn init_after_heap() {
100    let boot_time_info = EARLY_INFO.get().unwrap();
101
102    INFO.call_once(|| BootInfo {
103        bootloader_name: boot_time_info.bootloader_name.to_string(),
104        kernel_cmdline: boot_time_info.kernel_cmdline.to_string(),
105        initramfs: boot_time_info.initramfs,
106        framebuffer_arg: boot_time_info.framebuffer_arg,
107        memory_regions: boot_time_info.memory_regions.to_vec(),
108    });
109}
110
111/// Calls the OSTD-user defined entrypoint of the actual kernel.
112///
113/// Any kernel that uses the `ostd` crate should define a function marked with
114/// `ostd::main` as the entrypoint.
115///
116/// This function should be only called from the bootloader-specific module.
117pub(crate) fn call_ostd_main() -> ! {
118    // The entry point of kernel code, which should be defined by the package that
119    // uses OSTD.
120    extern "Rust" {
121        fn __ostd_main() -> !;
122    }
123
124    // SAFETY: The function is called only once on the BSP.
125    unsafe { crate::init() };
126
127    // SAFETY: This external function is defined by the package that uses OSTD,
128    // which should be generated by the `ostd::main` macro. So it is safe.
129    unsafe {
130        __ostd_main();
131    }
132}
133*/