lib.rs 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. #![no_std]
  2. pub use elf_sections::{ElfSectionsTag, ElfSection, ElfSectionIter, ElfSectionType, ElfSectionFlags};
  3. pub use elf_sections::{ELF_SECTION_WRITABLE, ELF_SECTION_ALLOCATED, ELF_SECTION_EXECUTABLE};
  4. pub use memory_map::{MemoryMapTag, MemoryArea, MemoryAreaIter};
  5. #[macro_use]
  6. extern crate bitflags;
  7. mod elf_sections;
  8. mod memory_map;
  9. pub unsafe fn load(address: usize) -> &'static BootInformation {
  10. let multiboot = &*(address as *const BootInformation);
  11. assert!(multiboot.has_valid_end_tag());
  12. multiboot
  13. }
  14. #[repr(C)]
  15. pub struct BootInformation {
  16. pub total_size: u32,
  17. _reserved: u32,
  18. first_tag: Tag,
  19. }
  20. impl BootInformation {
  21. pub fn elf_sections_tag(&self) -> Option<&'static ElfSectionsTag> {
  22. self.get_tag(9).map(|tag| unsafe{&*(tag as *const Tag as *const ElfSectionsTag)})
  23. }
  24. pub fn memory_map_tag(&self) -> Option<&'static MemoryMapTag> {
  25. self.get_tag(6).map(|tag| unsafe{&*(tag as *const Tag as *const MemoryMapTag)})
  26. }
  27. fn has_valid_end_tag(&self) -> bool {
  28. const END_TAG: Tag = Tag{typ:0, size:8};
  29. let self_ptr = self as *const _;
  30. let end_tag_addr = self_ptr as usize + (self.total_size - END_TAG.size) as usize;
  31. let end_tag = unsafe{&*(end_tag_addr as *const Tag)};
  32. end_tag.typ == END_TAG.typ && end_tag.size == END_TAG.size
  33. }
  34. fn get_tag(&self, typ: u32) -> Option<&'static Tag> {
  35. self.tags().find(|tag| tag.typ == typ)
  36. }
  37. fn tags(&self) -> TagIter {
  38. TagIter{current: &self.first_tag as *const _}
  39. }
  40. }
  41. #[repr(C)]
  42. struct Tag {
  43. typ: u32,
  44. size: u32,
  45. // tag specific fields
  46. }
  47. struct TagIter {
  48. current: *const Tag,
  49. }
  50. impl Iterator for TagIter {
  51. type Item = &'static Tag;
  52. fn next(&mut self) -> Option<&'static Tag> {
  53. match unsafe{&*self.current} {
  54. &Tag{typ:0, size:8} => None, // end tag
  55. tag => {
  56. // go to next tag
  57. let mut tag_addr = self.current as usize;
  58. tag_addr += tag.size as usize;
  59. tag_addr = ((tag_addr-1) & !0x7) + 0x8; //align at 8 byte
  60. self.current = tag_addr as *const _;
  61. Some(tag)
  62. },
  63. }
  64. }
  65. }