diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/arch/x86_64/asm/e820.s | 2 | ||||
| -rw-r--r-- | src/lib.rs | 10 | ||||
| -rw-r--r-- | src/machine/mod.rs | 1 | ||||
| -rw-r--r-- | src/machine/multiboot.rs | 77 |
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? @@ -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. + |
