aboutsummaryrefslogtreecommitdiff
path: root/src
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
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')
-rw-r--r--src/arch/x86_64/asm/e820.s2
-rw-r--r--src/lib.rs10
-rw-r--r--src/machine/mod.rs1
-rw-r--r--src/machine/multiboot.rs77
4 files changed, 85 insertions, 5 deletions
diff --git a/src/arch/x86_64/asm/e820.s b/src/arch/x86_64/asm/e820.s
deleted file mode 100644
index 59c672a..0000000
--- a/src/arch/x86_64/asm/e820.s
+++ /dev/null
@@ -1,2 +0,0 @@
-; getting an E820 memory map, code from osdev wiki.
-; this only works in real mode ... how to do it in long mode?
diff --git a/src/lib.rs b/src/lib.rs
index 759c7c0..3651a81 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -8,13 +8,13 @@ mod ds;
mod io;
mod machine;
mod mm;
+use crate::machine::key::Modifiers;
use arch::x86_64::interrupt;
use arch::x86_64::interrupt::pic_8259;
use arch::x86_64::interrupt::pic_8259::PicDeviceInt;
use core::panic::PanicInfo;
use machine::cgascr::CGAScreen;
-
-use crate::machine::key::Modifiers;
+use machine::multiboot;
#[cfg(not(test))]
#[panic_handler]
@@ -28,14 +28,18 @@ pub extern "C" fn _entry() -> ! {
// init code
io::set_attr(0x1f);
io::clear_screen();
+ assert!(multiboot::check_magic(), "bad multiboot magic!");
+ let mbi = multiboot::get_mb_info().expect("bad multiboot info flags");
+ println!("MB INFO: {:#X?}", mbi);
interrupt::init();
pic_8259::allow(PicDeviceInt::KEYBOARD);
interrupt::interrupt_enable();
- io::print_welcome();
let mut framemap = mm::pma::FMap::new();
framemap.init();
println!("Bitmap starting from : {:p}", framemap.bm.as_ptr());
println!("Skip first {} bytes", framemap.skip_byte);
+ println!("system init .. done!");
+ // io::print_welcome();
// busy loop query keyboard
loop {
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.
+