| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374 | #![no_std]use header::{Tag, TagIter};pub use boot_loader_name::BootLoaderNameTag;pub use elf_sections::{ElfSectionsTag, ElfSection, ElfSectionIter, ElfSectionType, ElfSectionFlags, StringTable};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 _}    }}
 |