1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
#![no_std] use header::{Tag, TagIter}; pub use boot_loader_name::BootLoaderNameTag; pub use elf_sections::{ElfSectionsTag, ElfSection, ElfSectionIter, ElfSectionType, ElfSectionFlags}; pub use elf_sections::{ELF_SECTION_WRITABLE, ELF_SECTION_ALLOCATED, ELF_SECTION_EXECUTABLE}; pub use memory_map::{MemoryMapTag, MemoryArea, MemoryAreaIter}; pub use module::{ModuleTag, ModuleIter}; #[macro_use] extern crate bitflags; mod header; mod boot_loader_name; mod elf_sections; mod memory_map; mod module; pub unsafe fn load(address: usize) -> &'static BootInformation { let multiboot = &*(address as *const BootInformation); assert!(multiboot.has_valid_end_tag()); multiboot } #[repr(C)] pub struct BootInformation { pub total_size: u32, _reserved: u32, first_tag: Tag, } impl BootInformation { pub fn start_address(&self) -> usize { self as *const _ as usize } pub fn end_address(&self) -> usize { self.start_address() + self.total_size as usize } pub fn elf_sections_tag(&self) -> Option<&'static ElfSectionsTag> { self.get_tag(9).map(|tag| unsafe{&*(tag as *const Tag as *const ElfSectionsTag)}) } pub fn memory_map_tag(&self) -> Option<&'static MemoryMapTag> { self.get_tag(6).map(|tag| unsafe{&*(tag as *const Tag as *const MemoryMapTag)}) } pub fn module_tags(&self) -> ModuleIter { ModuleIter{ iter: self.tags() } } pub fn boot_loader_name_tag(&self) -> Option<&'static BootLoaderNameTag> { self.get_tag(2).map(|tag| unsafe{&*(tag as *const Tag as *const BootLoaderNameTag)}) } fn has_valid_end_tag(&self) -> bool { const END_TAG: Tag = Tag{typ:0, size:8}; let self_ptr = self as *const _; let end_tag_addr = self_ptr as usize + (self.total_size - END_TAG.size) as usize; let end_tag = unsafe{&*(end_tag_addr as *const Tag)}; end_tag.typ == END_TAG.typ && end_tag.size == END_TAG.size } fn get_tag(&self, typ: u32) -> Option<&'static Tag> { self.tags().find(|tag| tag.typ == typ) } fn tags(&self) -> TagIter { TagIter{current: &self.first_tag as *const _} } }