Skip to main content

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
11#[cfg(feature = "loader_main")]
12pub mod loader_main;
13pub mod output;
14pub mod memory;
15use self::output::Framebuffer;
16use self::memory::MemoryMap;
17
18// Panic handler
19use core::panic::PanicInfo;
20
21#[panic_handler]
22fn panic(_info: &PanicInfo) -> ! {
23    loop {}
24}
25
26/// This struct is the boot information struct, which provides
27/// the basic information, *memory map*, and so on.
28#[repr(C, align(4))]
29#[derive(Debug, Clone, PartialEq, Eq)]
30pub struct BootInfo {
31    /// The boot mode, see the [`BootMode`] enum.
32    boot_mode: BootMode,
33    memmap: MemoryMap,
34    framebuffer: Framebuffer,
35    
36}
37
38impl BootInfo {
39    /// Initialize a new boot info object.
40    ///
41    /// Note: this object will be initialized by loader
42    /// automatically, so if you are a kernel developer, do
43    /// not use this method, because you needn't and unusable.
44    #[cfg(feature = "loader_main")]
45    pub fn new(boot_mode: BootMode, memmap: MemoryMap, fb: Framebuffer) -> Self {
46        Self {
47            boot_mode,
48            memmap,
49            framebuffer: fb
50        }
51    }
52
53    /// Put the boot information to a fixed address
54    ///
55    /// # Safety
56    /// This is unsafe because we need to operate the pointer.
57    ///
58    /// This function is for loader only.
59    pub unsafe fn put_addr(self, address: u64) {
60        let pointer = address as *mut BootInfo;
61        unsafe {
62            pointer.write_volatile(self);
63        }
64    }
65
66    /// Load the boot infomation from an address.
67    ///
68    /// # Safety
69    /// This is unsafe because we need to read from a pointer.
70    pub unsafe fn load(address: u64) -> Self {
71        let pointer = address as *const BootInfo;
72        unsafe {
73            pointer.read_volatile()
74        }
75    }
76
77    /// Get the boot mode.
78    pub const fn boot_mode(&self) -> &BootMode {
79        &self.boot_mode
80    }
81
82    /// Get the framebuffer info.
83    pub const fn framebuffer(&self) -> &Framebuffer {
84        &self.framebuffer
85    }
86
87    /// Get the memory map.
88    pub const fn memory(&self) -> &MemoryMap {
89        &self.memmap
90    }
91}
92
93/// This is the boot mode, only support 2 modes, which are legacy(BIOS) and UEFI.
94#[repr(C)]
95#[derive(Debug, Clone, Copy, PartialEq, Eq)]
96pub enum BootMode {
97    /// The Legacy boot mode, also called BIOS boot mode.
98    ///
99    /// This mode is for older machine, and we needs implement
100    /// lots of things in it.
101    Legacy,
102
103    /// The UEFI boot mode, which is the newer mode. Lots of
104    /// new machines uses it.
105    ///
106    /// Also, some machine only support it (such as mine awa).
107    Uefi,
108}