|  | @@ -1,8 +1,8 @@
 | 
	
		
			
				|  |  |  use crate::{
 | 
	
		
			
				|  |  |      AddressHeaderTag, ConsoleHeaderTag, EfiBootServiceHeaderTag, EndHeaderTag,
 | 
	
		
			
				|  |  |      EntryAddressHeaderTag, EntryEfi32HeaderTag, EntryEfi64HeaderTag, FramebufferHeaderTag,
 | 
	
		
			
				|  |  | -    HeaderTag, HeaderTagISA, HeaderTagType, InformationRequestHeaderTag, ModuleAlignHeaderTag,
 | 
	
		
			
				|  |  | -    RelocatableHeaderTag,
 | 
	
		
			
				|  |  | +    HeaderTagHeader, HeaderTagISA, HeaderTagType, InformationRequestHeaderTag,
 | 
	
		
			
				|  |  | +    ModuleAlignHeaderTag, RelocatableHeaderTag,
 | 
	
		
			
				|  |  |  };
 | 
	
		
			
				|  |  |  use core::fmt::{Debug, Formatter};
 | 
	
		
			
				|  |  |  use core::mem::size_of;
 | 
	
	
		
			
				|  | @@ -103,89 +103,106 @@ impl<'a> Multiboot2Header<'a> {
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      /// Wrapper around [`Multiboot2BasicHeader::verify_checksum`].
 | 
	
		
			
				|  |  | +    #[must_use]
 | 
	
		
			
				|  |  |      pub const fn verify_checksum(&self) -> bool {
 | 
	
		
			
				|  |  |          self.0.verify_checksum()
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |      /// Wrapper around [`Multiboot2BasicHeader::header_magic`].
 | 
	
		
			
				|  |  | +    #[must_use]
 | 
	
		
			
				|  |  |      pub const fn header_magic(&self) -> u32 {
 | 
	
		
			
				|  |  |          self.0.header_magic()
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |      /// Wrapper around [`Multiboot2BasicHeader::arch`].
 | 
	
		
			
				|  |  | +    #[must_use]
 | 
	
		
			
				|  |  |      pub const fn arch(&self) -> HeaderTagISA {
 | 
	
		
			
				|  |  |          self.0.arch()
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |      /// Wrapper around [`Multiboot2BasicHeader::length`].
 | 
	
		
			
				|  |  | +    #[must_use]
 | 
	
		
			
				|  |  |      pub const fn length(&self) -> u32 {
 | 
	
		
			
				|  |  |          self.0.length()
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |      /// Wrapper around [`Multiboot2BasicHeader::checksum`].
 | 
	
		
			
				|  |  | +    #[must_use]
 | 
	
		
			
				|  |  |      pub const fn checksum(&self) -> u32 {
 | 
	
		
			
				|  |  |          self.0.checksum()
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |      /// Wrapper around [`Multiboot2BasicHeader::tag_iter`].
 | 
	
		
			
				|  |  | +    #[must_use]
 | 
	
		
			
				|  |  |      pub fn iter(&self) -> Multiboot2HeaderTagIter {
 | 
	
		
			
				|  |  |          self.0.tag_iter()
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |      /// Wrapper around [`Multiboot2BasicHeader::calc_checksum`].
 | 
	
		
			
				|  |  | +    #[must_use]
 | 
	
		
			
				|  |  |      pub const fn calc_checksum(magic: u32, arch: HeaderTagISA, length: u32) -> u32 {
 | 
	
		
			
				|  |  |          Multiboot2BasicHeader::calc_checksum(magic, arch, length)
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      /// Search for the address header tag.
 | 
	
		
			
				|  |  | +    #[must_use]
 | 
	
		
			
				|  |  |      pub fn address_tag(&self) -> Option<&AddressHeaderTag> {
 | 
	
		
			
				|  |  |          self.get_tag(HeaderTagType::Address)
 | 
	
		
			
				|  |  | -            .map(|tag| unsafe { &*(tag as *const HeaderTag as *const AddressHeaderTag) })
 | 
	
		
			
				|  |  | +            .map(|tag| unsafe { &*(tag as *const HeaderTagHeader as *const AddressHeaderTag) })
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      /// Search for the entry address header tag.
 | 
	
		
			
				|  |  | +    #[must_use]
 | 
	
		
			
				|  |  |      pub fn entry_address_tag(&self) -> Option<&EntryAddressHeaderTag> {
 | 
	
		
			
				|  |  |          self.get_tag(HeaderTagType::EntryAddress)
 | 
	
		
			
				|  |  | -            .map(|tag| unsafe { &*(tag as *const HeaderTag as *const EntryAddressHeaderTag) })
 | 
	
		
			
				|  |  | +            .map(|tag| unsafe { &*(tag as *const HeaderTagHeader as *const EntryAddressHeaderTag) })
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      /// Search for the EFI32 entry address header tag.
 | 
	
		
			
				|  |  | +    #[must_use]
 | 
	
		
			
				|  |  |      pub fn entry_address_efi32_tag(&self) -> Option<&EntryEfi32HeaderTag> {
 | 
	
		
			
				|  |  |          self.get_tag(HeaderTagType::EntryAddressEFI32)
 | 
	
		
			
				|  |  | -            .map(|tag| unsafe { &*(tag as *const HeaderTag as *const EntryEfi32HeaderTag) })
 | 
	
		
			
				|  |  | +            .map(|tag| unsafe { &*(tag as *const HeaderTagHeader as *const EntryEfi32HeaderTag) })
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      /// Search for the EFI64 entry address header tag.
 | 
	
		
			
				|  |  | +    #[must_use]
 | 
	
		
			
				|  |  |      pub fn entry_address_efi64_tag(&self) -> Option<&EntryEfi64HeaderTag> {
 | 
	
		
			
				|  |  |          self.get_tag(HeaderTagType::EntryAddressEFI64)
 | 
	
		
			
				|  |  | -            .map(|tag| unsafe { &*(tag as *const HeaderTag as *const EntryEfi64HeaderTag) })
 | 
	
		
			
				|  |  | +            .map(|tag| unsafe { &*(tag as *const HeaderTagHeader as *const EntryEfi64HeaderTag) })
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      /// Search for the console flags header tag.
 | 
	
		
			
				|  |  | +    #[must_use]
 | 
	
		
			
				|  |  |      pub fn console_flags_tag(&self) -> Option<&ConsoleHeaderTag> {
 | 
	
		
			
				|  |  |          self.get_tag(HeaderTagType::ConsoleFlags)
 | 
	
		
			
				|  |  | -            .map(|tag| unsafe { &*(tag as *const HeaderTag as *const ConsoleHeaderTag) })
 | 
	
		
			
				|  |  | +            .map(|tag| unsafe { &*(tag as *const HeaderTagHeader as *const ConsoleHeaderTag) })
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      /// Search for the framebuffer header tag.
 | 
	
		
			
				|  |  | +    #[must_use]
 | 
	
		
			
				|  |  |      pub fn framebuffer_tag(&self) -> Option<&FramebufferHeaderTag> {
 | 
	
		
			
				|  |  |          self.get_tag(HeaderTagType::Framebuffer)
 | 
	
		
			
				|  |  | -            .map(|tag| unsafe { &*(tag as *const HeaderTag as *const FramebufferHeaderTag) })
 | 
	
		
			
				|  |  | +            .map(|tag| unsafe { &*(tag as *const HeaderTagHeader as *const FramebufferHeaderTag) })
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      /// Search for the module align header tag.
 | 
	
		
			
				|  |  | +    #[must_use]
 | 
	
		
			
				|  |  |      pub fn module_align_tag(&self) -> Option<&ModuleAlignHeaderTag> {
 | 
	
		
			
				|  |  |          self.get_tag(HeaderTagType::ModuleAlign)
 | 
	
		
			
				|  |  | -            .map(|tag| unsafe { &*(tag as *const HeaderTag as *const ModuleAlignHeaderTag) })
 | 
	
		
			
				|  |  | +            .map(|tag| unsafe { &*(tag as *const HeaderTagHeader as *const ModuleAlignHeaderTag) })
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      /// Search for the EFI Boot Services header tag.
 | 
	
		
			
				|  |  | +    #[must_use]
 | 
	
		
			
				|  |  |      pub fn efi_boot_services_tag(&self) -> Option<&EfiBootServiceHeaderTag> {
 | 
	
		
			
				|  |  | -        self.get_tag(HeaderTagType::EfiBS)
 | 
	
		
			
				|  |  | -            .map(|tag| unsafe { &*(tag as *const HeaderTag as *const EfiBootServiceHeaderTag) })
 | 
	
		
			
				|  |  | +        self.get_tag(HeaderTagType::EfiBS).map(|tag| unsafe {
 | 
	
		
			
				|  |  | +            &*(tag as *const HeaderTagHeader as *const EfiBootServiceHeaderTag)
 | 
	
		
			
				|  |  | +        })
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      /// Search for the EFI32 entry address header tag.
 | 
	
		
			
				|  |  | +    #[must_use]
 | 
	
		
			
				|  |  |      pub fn relocatable_tag(&self) -> Option<&RelocatableHeaderTag> {
 | 
	
		
			
				|  |  |          self.get_tag(HeaderTagType::Relocatable)
 | 
	
		
			
				|  |  | -            .map(|tag| unsafe { &*(tag as *const HeaderTag as *const RelocatableHeaderTag) })
 | 
	
		
			
				|  |  | +            .map(|tag| unsafe { &*(tag as *const HeaderTagHeader as *const RelocatableHeaderTag) })
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    fn get_tag(&self, typ: HeaderTagType) -> Option<&HeaderTag> {
 | 
	
		
			
				|  |  | +    fn get_tag(&self, typ: HeaderTagType) -> Option<&HeaderTagHeader> {
 | 
	
		
			
				|  |  |          self.iter()
 | 
	
		
			
				|  |  |              .map(|tag| unsafe { tag.as_ref() }.unwrap())
 | 
	
		
			
				|  |  |              .find(|tag| tag.typ() == typ)
 | 
	
	
		
			
				|  | @@ -229,7 +246,7 @@ impl Multiboot2BasicHeader {
 | 
	
		
			
				|  |  |      pub(crate) const fn new(arch: HeaderTagISA, length: u32) -> Self {
 | 
	
		
			
				|  |  |          let magic = MAGIC;
 | 
	
		
			
				|  |  |          let checksum = Self::calc_checksum(magic, arch, length);
 | 
	
		
			
				|  |  | -        Multiboot2BasicHeader {
 | 
	
		
			
				|  |  | +        Self {
 | 
	
		
			
				|  |  |              header_magic: magic,
 | 
	
		
			
				|  |  |              arch,
 | 
	
		
			
				|  |  |              length,
 | 
	
	
		
			
				|  | @@ -238,25 +255,38 @@ impl Multiboot2BasicHeader {
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      /// Verifies that a Multiboot2 header is valid.
 | 
	
		
			
				|  |  | +    #[must_use]
 | 
	
		
			
				|  |  |      pub const fn verify_checksum(&self) -> bool {
 | 
	
		
			
				|  |  |          let check = Self::calc_checksum(self.header_magic, self.arch, self.length);
 | 
	
		
			
				|  |  |          check == self.checksum
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      /// Calculates the checksum as described in the spec.
 | 
	
		
			
				|  |  | +    #[must_use]
 | 
	
		
			
				|  |  |      pub const fn calc_checksum(magic: u32, arch: HeaderTagISA, length: u32) -> u32 {
 | 
	
		
			
				|  |  |          (0x100000000 - magic as u64 - arch as u64 - length as u64) as u32
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +    /// Returns the header magic.
 | 
	
		
			
				|  |  | +    #[must_use]
 | 
	
		
			
				|  |  |      pub const fn header_magic(&self) -> u32 {
 | 
	
		
			
				|  |  |          self.header_magic
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    /// Returns the [`HeaderTagISA`].
 | 
	
		
			
				|  |  | +    #[must_use]
 | 
	
		
			
				|  |  |      pub const fn arch(&self) -> HeaderTagISA {
 | 
	
		
			
				|  |  |          self.arch
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    /// Returns the length.
 | 
	
		
			
				|  |  | +    #[must_use]
 | 
	
		
			
				|  |  |      pub const fn length(&self) -> u32 {
 | 
	
		
			
				|  |  |          self.length
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    /// Returns the checksum.
 | 
	
		
			
				|  |  | +    #[must_use]
 | 
	
		
			
				|  |  |      pub const fn checksum(&self) -> u32 {
 | 
	
		
			
				|  |  |          self.checksum
 | 
	
		
			
				|  |  |      }
 | 
	
	
		
			
				|  | @@ -265,12 +295,13 @@ impl Multiboot2BasicHeader {
 | 
	
		
			
				|  |  |      ///
 | 
	
		
			
				|  |  |      /// # Panics
 | 
	
		
			
				|  |  |      /// See doc of [`Multiboot2HeaderTagIter`].
 | 
	
		
			
				|  |  | +    #[must_use]
 | 
	
		
			
				|  |  |      pub fn tag_iter(&self) -> Multiboot2HeaderTagIter {
 | 
	
		
			
				|  |  | -        let base_hdr_size = size_of::<Multiboot2BasicHeader>();
 | 
	
		
			
				|  |  | +        let base_hdr_size = size_of::<Self>();
 | 
	
		
			
				|  |  |          if base_hdr_size == self.length as usize {
 | 
	
		
			
				|  |  |              panic!("No end tag!");
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | -        let tag_base_addr = self as *const Multiboot2BasicHeader;
 | 
	
		
			
				|  |  | +        let tag_base_addr = self as *const Self;
 | 
	
		
			
				|  |  |          // cast to u8 so that the offset in bytes works correctly
 | 
	
		
			
				|  |  |          let tag_base_addr = tag_base_addr as *const u8;
 | 
	
		
			
				|  |  |          // tag_base_addr should now point behind the "static" members
 | 
	
	
		
			
				|  | @@ -278,7 +309,7 @@ impl Multiboot2BasicHeader {
 | 
	
		
			
				|  |  |          // align pointer to 8 byte according to spec
 | 
	
		
			
				|  |  |          let tag_base_addr = unsafe { tag_base_addr.add(tag_base_addr.align_offset(8)) };
 | 
	
		
			
				|  |  |          // cast back
 | 
	
		
			
				|  |  | -        let tag_base_addr = tag_base_addr as *const HeaderTag;
 | 
	
		
			
				|  |  | +        let tag_base_addr = tag_base_addr as *const HeaderTagHeader;
 | 
	
		
			
				|  |  |          let tags_len = self.length as usize - base_hdr_size;
 | 
	
		
			
				|  |  |          Multiboot2HeaderTagIter::new(tag_base_addr, tags_len as u32)
 | 
	
		
			
				|  |  |      }
 | 
	
	
		
			
				|  | @@ -307,7 +338,7 @@ impl Debug for Multiboot2BasicHeader {
 | 
	
		
			
				|  |  |  #[derive(Clone)]
 | 
	
		
			
				|  |  |  pub struct Multiboot2HeaderTagIter {
 | 
	
		
			
				|  |  |      /// 8-byte aligned base address
 | 
	
		
			
				|  |  | -    base: *const HeaderTag,
 | 
	
		
			
				|  |  | +    base: *const HeaderTagHeader,
 | 
	
		
			
				|  |  |      /// Offset in bytes from the base address.
 | 
	
		
			
				|  |  |      /// Always <= than size.
 | 
	
		
			
				|  |  |      n: u32,
 | 
	
	
		
			
				|  | @@ -324,11 +355,11 @@ pub struct Multiboot2HeaderTagIter {
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  impl Multiboot2HeaderTagIter {
 | 
	
		
			
				|  |  | -    fn new(base: *const HeaderTag, size: u32) -> Self {
 | 
	
		
			
				|  |  | +    fn new(base: *const HeaderTagHeader, size: u32) -> Self {
 | 
	
		
			
				|  |  |          // transform to byte pointer => offset works properly
 | 
	
		
			
				|  |  |          let base = base as *const u8;
 | 
	
		
			
				|  |  |          let base = unsafe { base.add(base.align_offset(8)) };
 | 
	
		
			
				|  |  | -        let base = base as *const HeaderTag;
 | 
	
		
			
				|  |  | +        let base = base as *const HeaderTagHeader;
 | 
	
		
			
				|  |  |          Self {
 | 
	
		
			
				|  |  |              base,
 | 
	
		
			
				|  |  |              n: 0,
 | 
	
	
		
			
				|  | @@ -340,7 +371,7 @@ impl Multiboot2HeaderTagIter {
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  impl Iterator for Multiboot2HeaderTagIter {
 | 
	
		
			
				|  |  | -    type Item = *const HeaderTag;
 | 
	
		
			
				|  |  | +    type Item = *const HeaderTagHeader;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      fn next(&mut self) -> Option<Self::Item> {
 | 
	
		
			
				|  |  |          // no more bytes left to check; length reached
 | 
	
	
		
			
				|  | @@ -351,7 +382,7 @@ impl Iterator for Multiboot2HeaderTagIter {
 | 
	
		
			
				|  |  |          // transform to byte ptr => offset works correctly
 | 
	
		
			
				|  |  |          let ptr = self.base as *const u8;
 | 
	
		
			
				|  |  |          let ptr = unsafe { ptr.add(self.n as usize) };
 | 
	
		
			
				|  |  | -        let ptr = ptr as *const HeaderTag;
 | 
	
		
			
				|  |  | +        let ptr = ptr as *const HeaderTagHeader;
 | 
	
		
			
				|  |  |          assert_eq!(ptr as usize % 8, 0, "must be 8-byte aligned");
 | 
	
		
			
				|  |  |          let tag = unsafe { &*ptr };
 | 
	
		
			
				|  |  |          assert!(
 |