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 _}
- }
- }
|