diff options
Diffstat (limited to 'src/arch/x86/common/boot/multiboot.rs')
| -rw-r--r-- | src/arch/x86/common/boot/multiboot.rs | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/src/arch/x86/common/boot/multiboot.rs b/src/arch/x86/common/boot/multiboot.rs new file mode 100644 index 0000000..09789ce --- /dev/null +++ b/src/arch/x86/common/boot/multiboot.rs @@ -0,0 +1,79 @@ +pub const MULTIBOOT2_BOOTLOADER_MAGIC: u32 = 0x36d76289; +pub const MULTIBOOT_TAG_TYPE_END: u32 = 0; +pub const MULTIBOOT_TAG_TYPE_MMAP: u32 = 6; +pub const MULTIBOOT_TAG_TYPE_FB: u32 = 8; + +use crate::{print, println}; + +pub fn parse_fb_multiboot(mut mem: *mut u32) { + let framebuffer_addr: u64 = unsafe { *(mem as *mut u64) }; + let framebuffer_pitch: u32 = unsafe { *mem.wrapping_add(2) }; + let framebuffer_width: u32 = unsafe { *mem.wrapping_add(3) }; + let framebuffer_height: u32 = unsafe { *mem.wrapping_add(4) }; + let framebuffer_bpp: u8 = unsafe { *(mem.wrapping_add(5) as *mut u8) }; + let framebuffer_type: u8 = unsafe { *(mem.wrapping_add(5) as *mut u8).wrapping_add(1) }; + let reserved: u8 = unsafe { *(mem.wrapping_add(5) as *mut u8).wrapping_add(1) }; + + println!( + "0x{:x} {:x} {:x} {:x}", + framebuffer_addr, framebuffer_pitch, framebuffer_width, framebuffer_height + ); +} + +pub fn parse_mem_multiboot(mut mem: *mut u32, _size: u32) { + let mut curr_size: u32 = 16; + + while curr_size < _size { + let base_addr: u64 = unsafe { *(mem as *mut u64) }; + let length: u64 = unsafe { *(mem.wrapping_add(2) as *mut u64) }; + let _type: u32 = unsafe { *mem.wrapping_add(4) }; + let reserved: u32 = unsafe { *mem.wrapping_add(5) }; + assert_eq!(reserved, 0, "reserved not 0"); + + //println!("{:x} {:x} {:x}", base_addr, length, _type); + + mem = mem.wrapping_add(6); + curr_size += 24; + } +} + +pub fn parse_multiboot(mut multiboot_bootinfo: *mut u32, multiboot_magic: u32) { + assert_eq!( + multiboot_magic, MULTIBOOT2_BOOTLOADER_MAGIC, + "MULTIBOOT2_BOOTLOADER_MAGIC" + ); + + let total_size: u32 = unsafe { *multiboot_bootinfo }; + let mut size = 8; + multiboot_bootinfo = multiboot_bootinfo.wrapping_add(2); + + while size < total_size { + let _type: u32 = unsafe { *multiboot_bootinfo }; + let _size: u32 = unsafe { *(multiboot_bootinfo.wrapping_add(1)) }; + let mem: *mut u32 = multiboot_bootinfo.wrapping_add(4); + let mem2: *mut u32 = multiboot_bootinfo.wrapping_add(2); + + match _type { + MULTIBOOT_TAG_TYPE_FB => { + parse_fb_multiboot(mem2); + } + MULTIBOOT_TAG_TYPE_MMAP => { + parse_mem_multiboot(mem, _size); + } + _ => {} + } + + let inc_size = (_size / 8 + (_size % 8 != 0) as u32) * 8; + size += inc_size; + + println!("{} {} {}", _type, _size, inc_size); + multiboot_bootinfo = multiboot_bootinfo.wrapping_add((inc_size / 4).try_into().unwrap()); + + if _type == MULTIBOOT_TAG_TYPE_END { + assert_eq!(_size, 8, "MULTIBOOT_TAG_TYPE_END"); + break; + } + } + + assert_eq!(total_size, size, "Multiboot"); +} |
