proka_bootloader/lib.rs
1//! This crate provides the struct, enums about the Proka
2//! bootloader, including the boot information, and so on.
3//!
4//! # About proka bootloader
5//! Well, this bootloader is for Proka Kernel, which will obey
6//! its standard. For more information, see <url>.
7
8#![no_std]
9#![no_main]
10#![feature(custom_test_frameworks)]
11#![test_runner(self::test_runner)]
12#![reexport_test_harness_main = "test_main"]
13
14#[cfg(feature = "loader_main")]
15pub mod loader_main;
16pub mod output;
17pub mod memory;
18pub mod header;
19mod version;
20use self::output::Framebuffer;
21use self::memory::MemoryMap;
22
23/// This struct is the boot information struct, which provides
24/// the basic information, *memory map*, and so on.
25#[repr(C, packed)]
26#[derive(Debug, Clone, PartialEq, Eq)]
27pub struct BootInfo {
28 /// The boot mode, see the [`BootMode`] enum.
29 boot_mode: BootMode,
30 framebuffer: Framebuffer,
31 memmap: MemoryMap,
32}
33
34impl BootInfo {
35 /// Initialize a new boot info object.
36 ///
37 /// Note: this object will be initialized by loader
38 /// automatically, so if you are a kernel developer, do
39 /// not use this method, because you needn't and unusable.
40 #[cfg(feature = "loader_main")]
41 pub fn new(boot_mode: BootMode, memmap: MemoryMap, fb: Framebuffer) -> Self {
42 Self {
43 boot_mode,
44 memmap,
45 framebuffer: fb
46 }
47 }
48
49 /// Get the boot mode.
50 pub const fn boot_mode(&self) -> BootMode {
51 self.boot_mode
52 }
53
54 /// Get the framebuffer info.
55 pub const fn framebuffer(&self) -> Framebuffer {
56 self.framebuffer
57 }
58
59 /// Get the memory map.
60 pub const fn memory(&self) -> MemoryMap {
61 self.memmap
62 }
63}
64
65/// This is the boot mode, only support 2 modes, which are legacy(BIOS) and UEFI.
66#[repr(C)]
67#[derive(Debug, Clone, Copy, PartialEq, Eq)]
68pub enum BootMode {
69 /// The Legacy boot mode, also called BIOS boot mode.
70 ///
71 /// This mode is for older machine, and we needs implement
72 /// lots of things in it.
73 Legacy,
74
75 /// The UEFI boot mode, which is the newer mode. Lots of
76 /// new machines uses it.
77 ///
78 /// Also, some machine only support it (such as mine awa).
79 Uefi,
80}
81
82/// Get the bootinfo.
83///
84/// The BootInfo is pre-copied & fixed at the dedicated constant physical address
85/// 0x10000 by UEFI boot stage, never modified nor released in kernel lifetime.
86///
87/// # Safety
88/// Caller must ensure **before invoking**:
89/// 1. Address `0x10000` is allocated & filled with valid initialized BootInfo;
90/// 2. This range is reserved, never overwritten/freed by kernel/UEFI;
91/// 3. No mutable aliasing exists for this memory region.
92///
93/// These steps are already guaranteed by the bootloader, so invocation is generally safe
94/// in normal kernel runtime.
95///
96/// # Returns
97/// - `&'static BootInfo`: immutable static reference to the pre-filled BootInfo
98pub const fn get_bootinfo() -> &'static BootInfo {
99 const BI_PHYS: u64 = 0x10000;
100 unsafe { &*(BI_PHYS as *const BootInfo) }
101}
102
103#[cfg(test)]
104fn test_runner(tests: &[&dyn Fn()]) {
105 for test in tests {
106 test();
107 }
108}