aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTianhao Wang <shrik3@mailbox.org>2024-05-29 04:35:57 +0200
committerTianhao Wang <shrik3@mailbox.org>2024-06-11 15:17:10 +0200
commit890bac538171d231d1dccfb4b28091d016ec6118 (patch)
tree8f0cac1bb96ebee38c783234d8c5b81858507fca
parent959a93e653684b1ed8db4bd21eaca9831e372fb0 (diff)
multiboot: get memory info from MB info
Signed-off-by: Tianhao Wang <shrik3@mailbox.org>
-rw-r--r--src/lib.rs7
-rw-r--r--src/machine/multiboot.rs83
2 files changed, 72 insertions, 18 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 3651a81..25a8768 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -28,9 +28,12 @@ pub extern "C" fn _entry() -> ! {
// init code
io::set_attr(0x1f);
io::clear_screen();
- assert!(multiboot::check_magic(), "bad multiboot magic!");
+ assert!(multiboot::check(), "bad multiboot info from grub!");
let mbi = multiboot::get_mb_info().expect("bad multiboot info flags");
- println!("MB INFO: {:#X?}", mbi);
+ let mem = unsafe { mbi.get_mem() }.unwrap();
+ let mmap = unsafe { mbi.get_mmap() }.unwrap();
+ println!("memory: {:#X?}", mem);
+ println!("mmap (start): {:#X?}", mmap);
interrupt::init();
pic_8259::allow(PicDeviceInt::KEYBOARD);
interrupt::interrupt_enable();
diff --git a/src/machine/multiboot.rs b/src/machine/multiboot.rs
index 3056db3..c420c2b 100644
--- a/src/machine/multiboot.rs
+++ b/src/machine/multiboot.rs
@@ -1,4 +1,5 @@
use crate::io::*;
+use lazy_static::lazy_static;
// provide functions to parse information provided by grub multiboot
// see docs/multiboot.txt
extern "C" {
@@ -6,6 +7,21 @@ extern "C" {
static mb_info_addr: u32;
}
+lazy_static! {
+ pub static ref MBOOTINFO: &'static MultibootInfo =
+ unsafe { &*(mb_info_addr as *const MultibootInfo) };
+}
+
+/// this must be checked before any MB info fields are used.
+pub fn check() -> bool {
+ if unsafe { mb_magic != 0x2BADB002 } {
+ return false;
+ };
+ // must check magic before checking flags
+ let f = MBOOTINFO.get_flags();
+ return f.check_valid();
+}
+
#[repr(C)]
#[repr(packed)]
#[derive(Debug)]
@@ -19,10 +35,55 @@ pub struct MultibootMmap {
#[repr(C)]
#[repr(packed)]
#[derive(Debug, Clone, Copy)]
+pub struct MultibootInfoMmap {
+ pub mmap_length: u32,
+ pub mmap_addr: u32,
+}
+
+#[repr(C)]
+#[repr(packed)]
+#[derive(Debug, Clone, Copy)]
+pub struct MultibootInfoMem {
+ mem_lower: u32,
+ mem_upper: u32,
+}
+
+#[repr(C)]
+#[repr(packed)]
+#[derive(Debug)]
+/// all fields MUST be acquired via unsafe getters, because the MB magic and reserved bits in flags
+/// must be checked for validity before using. It does not suffice to check the corresponding
+/// present bits in the getters.
+/// Some fields are marked as padding because we don't need them (for now)
pub struct MultibootInfo {
- pub flags: MultibootInfoFlags,
- pub mem_lower: u32,
- pub mem_upper: u32,
+ flags: MultibootInfoFlags,
+ mem: MultibootInfoMem,
+ _pad1: [u8; 32],
+ mmap: MultibootInfoMmap,
+ _pad2: [u8; 68],
+}
+
+impl MultibootInfo {
+ // private function. Don't use it outside the module.
+ fn get_flags(&self) -> MultibootInfoFlags {
+ return self.flags;
+ }
+
+ pub unsafe fn get_mem(&self) -> Option<MultibootInfoMem> {
+ if self.get_flags().contains(MultibootInfoFlags::MEM) {
+ return Some(self.mem);
+ } else {
+ return None;
+ }
+ }
+
+ pub unsafe fn get_mmap(&self) -> Option<MultibootInfoMmap> {
+ if self.get_flags().contains(MultibootInfoFlags::MMAP) {
+ return Some(self.mmap);
+ } else {
+ return None;
+ }
+ }
}
use bitflags::bitflags;
@@ -57,21 +118,11 @@ impl MultibootInfoFlags {
}
}
-pub fn check_magic() -> bool {
- return unsafe { mb_magic == 0x2BADB002 };
-}
-
-pub fn get_mb_info() -> Option<MultibootInfo> {
- if !check_magic() {
+pub fn get_mb_info() -> Option<&'static MultibootInfo> {
+ if !check() {
return None;
}
- let mbi = unsafe { *(mb_info_addr as *mut MultibootInfo) };
- let flags = mbi.flags;
- if !flags.check_valid() {
- return None;
- }
- return Some(mbi);
+ return Some(&MBOOTINFO);
}
// TODO: expand MultibootInfo struct defs if needed.
-