aboutsummaryrefslogtreecommitdiff
path: root/src/machine
diff options
context:
space:
mode:
authorTianhao Wang <shrik3@mailbox.org>2024-05-29 01:18:02 +0200
committerTianhao Wang <shrik3@mailbox.org>2024-06-11 15:17:10 +0200
commit959a93e653684b1ed8db4bd21eaca9831e372fb0 (patch)
tree152426d2f9eb39ff26941204aaa149840e59578a /src/machine
parent590d29c3e44fc06bc79c2624fc94273434505b9d (diff)
multiboot: basic support for multiboot info
well, it's not trivial to use bios function because thanks to grub + multiboot, we are already in protected mode when the startup code takes control. Also the MB info is easier to play with than BIOS (or ACPI) Signed-off-by: Tianhao Wang <shrik3@mailbox.org>
Diffstat (limited to 'src/machine')
-rw-r--r--src/machine/mod.rs1
-rw-r--r--src/machine/multiboot.rs77
2 files changed, 78 insertions, 0 deletions
diff --git a/src/machine/mod.rs b/src/machine/mod.rs
index 46ca961..a2cf730 100644
--- a/src/machine/mod.rs
+++ b/src/machine/mod.rs
@@ -4,5 +4,6 @@ pub mod interrupt;
pub mod key;
pub mod keyctrl;
pub mod mem;
+pub mod multiboot;
// TODO: this module *should* be arch independent.
diff --git a/src/machine/multiboot.rs b/src/machine/multiboot.rs
new file mode 100644
index 0000000..3056db3
--- /dev/null
+++ b/src/machine/multiboot.rs
@@ -0,0 +1,77 @@
+use crate::io::*;
+// provide functions to parse information provided by grub multiboot
+// see docs/multiboot.txt
+extern "C" {
+ static mb_magic: u32;
+ static mb_info_addr: u32;
+}
+
+#[repr(C)]
+#[repr(packed)]
+#[derive(Debug)]
+pub struct MultibootMmap {
+ pub size: u32,
+ pub addr: u64,
+ pub len: u64,
+ pub mtype: u32,
+}
+
+#[repr(C)]
+#[repr(packed)]
+#[derive(Debug, Clone, Copy)]
+pub struct MultibootInfo {
+ pub flags: MultibootInfoFlags,
+ pub mem_lower: u32,
+ pub mem_upper: u32,
+}
+
+use bitflags::bitflags;
+bitflags! {
+ /// the MultibootInfoFlags indicate which fields are valid in the MultibootInfo
+ /// atm we only need the MEM and MMAP flags for memory management info.
+ #[derive(Copy, Clone, Debug)]
+ pub struct MultibootInfoFlags: u32 {
+ const MEM = 1 << 0;
+ const BOOT_DEVICE = 1 << 1;
+ const CMDLINE = 1 << 2;
+ const MODS = 1 << 3;
+ const SYM_TBL = 1 << 4;
+ const SHDR = 1 << 5;
+ const MMAP = 1 << 6;
+ const DRIVES = 1 << 7;
+ const CONF_TBL = 1 << 8;
+ const BL_NAME = 1 << 9;
+ const APM_TBL = 1 << 10;
+ const VBE_TBL = 1 << 11;
+ const FRAMEBUFFER = 1 << 12;
+ }
+}
+
+impl MultibootInfoFlags {
+ /// only 13 bits of the MB info flags are defined. The other flag bits must
+ /// be zero for the info block to be valie.
+ const VALID_MASK: u32 = 0x1FFF;
+
+ pub fn check_valid(&self) -> bool {
+ return self.bits() <= Self::VALID_MASK;
+ }
+}
+
+pub fn check_magic() -> bool {
+ return unsafe { mb_magic == 0x2BADB002 };
+}
+
+pub fn get_mb_info() -> Option<MultibootInfo> {
+ if !check_magic() {
+ return None;
+ }
+ let mbi = unsafe { *(mb_info_addr as *mut MultibootInfo) };
+ let flags = mbi.flags;
+ if !flags.check_valid() {
+ return None;
+ }
+ return Some(mbi);
+}
+
+// TODO: expand MultibootInfo struct defs if needed.
+