浏览代码

multiboot2: streamline tags

- all public fields -> methods
- Added missing InformationBuilder support for VBEInfoTag
Philipp Schuster 8 月之前
父节点
当前提交
4edcf47fde

+ 5 - 3
multiboot2/src/boot_information.rs

@@ -8,7 +8,7 @@ use crate::{
     module, BasicMemoryInfoTag, BootLoaderNameTag, CommandLineTag, EFIBootServicesNotExitedTag,
     EFIImageHandle32Tag, EFIImageHandle64Tag, EFIMemoryMapTag, EFISdt32Tag, EFISdt64Tag,
     ElfSectionIter, ElfSectionsTag, EndTag, FramebufferTag, ImageLoadPhysAddrTag, MemoryMapTag,
-    ModuleIter, RsdpV1Tag, RsdpV2Tag, SmbiosTag, TagTrait, TagType, VBEInfoTag,
+    ModuleIter, RsdpV1Tag, RsdpV2Tag, SmbiosTag, TagTrait, VBEInfoTag,
 };
 use core::fmt;
 use core::mem;
@@ -279,8 +279,8 @@ impl<'a> BootInformation<'a> {
     pub fn elf_sections(&self) -> Option<ElfSectionIter> {
         let tag = self.get_tag::<ElfSectionsTag>();
         tag.map(|t| {
-            assert!((t.entry_size * t.shndx) <= t.size() as u32);
-            t.sections()
+            assert!((t.entry_size() * t.shndx()) <= t.size() as u32);
+            t.sections_iter()
         })
     }
 
@@ -397,6 +397,8 @@ impl<'a> BootInformation<'a> {
     ///     .unwrap();
     /// assert_eq!(tag.name(), Ok("name"));
     /// ```
+    ///
+    /// [`TagType`]: crate::TagType
     #[must_use]
     pub fn get_tag<TagT: TagTrait + ?Sized + 'a>(&'a self) -> Option<&'a TagT> {
         self.tags()

+ 3 - 3
multiboot2/src/boot_loader_name.rs

@@ -1,11 +1,11 @@
 //! Module for [`BootLoaderNameTag`].
 
 use crate::tag::TagHeader;
-use crate::{new_boxed, parse_slice_as_string, StringError, TagTrait, TagType};
-#[cfg(feature = "builder")]
-use alloc::boxed::Box;
+use crate::{parse_slice_as_string, StringError, TagTrait, TagType};
 use core::fmt::{Debug, Formatter};
 use core::mem;
+#[cfg(feature = "builder")]
+use {crate::new_boxed, alloc::boxed::Box};
 
 const METADATA_SIZE: usize = mem::size_of::<TagHeader>();
 

+ 9 - 1
multiboot2/src/builder/information.rs

@@ -5,7 +5,8 @@ use crate::{
     BasicMemoryInfoTag, BootInformationHeader, BootLoaderNameTag, CommandLineTag,
     EFIBootServicesNotExitedTag, EFIImageHandle32Tag, EFIImageHandle64Tag, EFIMemoryMapTag,
     EFISdt32Tag, EFISdt64Tag, ElfSectionsTag, EndTag, FramebufferTag, ImageLoadPhysAddrTag,
-    MemoryMapTag, ModuleTag, RsdpV1Tag, RsdpV2Tag, SmbiosTag, TagTrait, TagType, ALIGNMENT,
+    MemoryMapTag, ModuleTag, RsdpV1Tag, RsdpV2Tag, SmbiosTag, TagTrait, TagType, VBEInfoTag,
+    ALIGNMENT,
 };
 use alloc::vec::Vec;
 use core::fmt::{Display, Formatter};
@@ -300,6 +301,13 @@ impl InformationBuilder {
         self.add_tag(tag).unwrap()
     }
 
+    /// Adds a 'VBE Info' tag (represented by [`VBEInfoTag`]) to the builder.
+    #[must_use]
+    pub fn vbe_info_tag(self, tag: &VBEInfoTag) -> Self {
+        self.add_tag(tag).unwrap()
+    }
+
+    #[must_use]
     const fn tag_is_allowed_multiple_times(tag_type: TagType) -> bool {
         matches!(
             tag_type,

+ 23 - 4
multiboot2/src/elf_sections.rs

@@ -18,8 +18,8 @@ const METADATA_SIZE: usize = mem::size_of::<TagHeader>() + 3 * mem::size_of::<u3
 pub struct ElfSectionsTag {
     header: TagHeader,
     number_of_sections: u32,
-    pub(crate) entry_size: u32,
-    pub(crate) shndx: u32, // string table
+    entry_size: u32,
+    shndx: u32,
     sections: [u8],
 }
 
@@ -35,7 +35,8 @@ impl ElfSectionsTag {
     }
 
     /// Get an iterator of loaded ELF sections.
-    pub(crate) const fn sections(&self) -> ElfSectionIter {
+    #[must_use]
+    pub(crate) const fn sections_iter(&self) -> ElfSectionIter {
         let string_section_offset = (self.shndx * self.entry_size) as isize;
         let string_section_ptr =
             unsafe { self.sections.as_ptr().offset(string_section_offset) as *const _ };
@@ -47,6 +48,24 @@ impl ElfSectionsTag {
             _phantom_data: PhantomData,
         }
     }
+
+    /// Returns the amount of sections.
+    #[must_use]
+    pub const fn number_of_sections(&self) -> u32 {
+        self.number_of_sections
+    }
+
+    /// Returns the size of each entry.
+    #[must_use]
+    pub const fn entry_size(&self) -> u32 {
+        self.entry_size
+    }
+
+    /// Returns the index of the section header string table.
+    #[must_use]
+    pub const fn shndx(&self) -> u32 {
+        self.shndx
+    }
 }
 
 impl TagTrait for ElfSectionsTag {
@@ -66,7 +85,7 @@ impl Debug for ElfSectionsTag {
             .field("number_of_sections", &self.number_of_sections)
             .field("entry_size", &self.entry_size)
             .field("shndx", &self.shndx)
-            .field("sections", &self.sections())
+            .field("sections", &self.sections_iter())
             .finish()
     }
 }

+ 37 - 37
multiboot2/src/lib.rs

@@ -448,83 +448,83 @@ mod tests {
         let vbe = bi.vbe_info_tag().unwrap();
         use vbe_info::*;
 
-        assert_eq!({ vbe.mode }, 16762);
-        assert_eq!({ vbe.interface_segment }, 65535);
-        assert_eq!({ vbe.interface_offset }, 24576);
-        assert_eq!({ vbe.interface_length }, 79);
-        assert_eq!({ vbe.control_info.signature }, [86, 69, 83, 65]);
-        assert_eq!({ vbe.control_info.version }, 768);
-        assert_eq!({ vbe.control_info.oem_string_ptr }, 3221247964);
+        assert_eq!({ vbe.mode() }, 16762);
+        assert_eq!({ vbe.interface_segment() }, 65535);
+        assert_eq!({ vbe.interface_offset() }, 24576);
+        assert_eq!({ vbe.interface_length() }, 79);
+        assert_eq!({ vbe.control_info().signature }, [86, 69, 83, 65]);
+        assert_eq!({ vbe.control_info().version }, 768);
+        assert_eq!({ vbe.control_info().oem_string_ptr }, 3221247964);
         assert_eq!(
-            { vbe.control_info.capabilities },
+            { vbe.control_info().capabilities },
             VBECapabilities::SWITCHABLE_DAC
         );
-        assert_eq!({ vbe.control_info.mode_list_ptr }, 1610645538);
-        assert_eq!({ vbe.control_info.total_memory }, 256);
-        assert_eq!({ vbe.control_info.oem_software_revision }, 0);
-        assert_eq!({ vbe.control_info.oem_vendor_name_ptr }, 3221247984);
-        assert_eq!({ vbe.control_info.oem_product_name_ptr }, 3221248003);
-        assert_eq!({ vbe.control_info.oem_product_revision_ptr }, 3221248023);
-        assert!({ vbe.mode_info.mode_attributes }.contains(
+        assert_eq!({ vbe.control_info().mode_list_ptr }, 1610645538);
+        assert_eq!({ vbe.control_info().total_memory }, 256);
+        assert_eq!({ vbe.control_info().oem_software_revision }, 0);
+        assert_eq!({ vbe.control_info().oem_vendor_name_ptr }, 3221247984);
+        assert_eq!({ vbe.control_info().oem_product_name_ptr }, 3221248003);
+        assert_eq!({ vbe.control_info().oem_product_revision_ptr }, 3221248023);
+        assert!({ vbe.mode_info().mode_attributes }.contains(
             VBEModeAttributes::SUPPORTED
                 | VBEModeAttributes::COLOR
                 | VBEModeAttributes::GRAPHICS
                 | VBEModeAttributes::NOT_VGA_COMPATIBLE
                 | VBEModeAttributes::LINEAR_FRAMEBUFFER
         ));
-        assert!(vbe.mode_info.window_a_attributes.contains(
+        assert!(vbe.mode_info().window_a_attributes.contains(
             VBEWindowAttributes::RELOCATABLE
                 | VBEWindowAttributes::READABLE
                 | VBEWindowAttributes::WRITEABLE
         ));
-        assert_eq!({ vbe.mode_info.window_granularity }, 64);
-        assert_eq!({ vbe.mode_info.window_size }, 64);
-        assert_eq!({ vbe.mode_info.window_a_segment }, 40960);
-        assert_eq!({ vbe.mode_info.window_function_ptr }, 3221247162);
-        assert_eq!({ vbe.mode_info.pitch }, 5120);
-        assert_eq!({ vbe.mode_info.resolution }, (1280, 800));
-        assert_eq!(vbe.mode_info.character_size, (8, 16));
-        assert_eq!(vbe.mode_info.number_of_planes, 1);
-        assert_eq!(vbe.mode_info.bpp, 32);
-        assert_eq!(vbe.mode_info.number_of_banks, 1);
-        assert_eq!(vbe.mode_info.memory_model, VBEMemoryModel::DirectColor);
-        assert_eq!(vbe.mode_info.bank_size, 0);
-        assert_eq!(vbe.mode_info.number_of_image_pages, 3);
+        assert_eq!({ vbe.mode_info().window_granularity }, 64);
+        assert_eq!({ vbe.mode_info().window_size }, 64);
+        assert_eq!({ vbe.mode_info().window_a_segment }, 40960);
+        assert_eq!({ vbe.mode_info().window_function_ptr }, 3221247162);
+        assert_eq!({ vbe.mode_info().pitch }, 5120);
+        assert_eq!({ vbe.mode_info().resolution }, (1280, 800));
+        assert_eq!(vbe.mode_info().character_size, (8, 16));
+        assert_eq!(vbe.mode_info().number_of_planes, 1);
+        assert_eq!(vbe.mode_info().bpp, 32);
+        assert_eq!(vbe.mode_info().number_of_banks, 1);
+        assert_eq!(vbe.mode_info().memory_model, VBEMemoryModel::DirectColor);
+        assert_eq!(vbe.mode_info().bank_size, 0);
+        assert_eq!(vbe.mode_info().number_of_image_pages, 3);
         assert_eq!(
-            vbe.mode_info.red_field,
+            vbe.mode_info().red_field,
             VBEField {
                 position: 16,
                 size: 8,
             }
         );
         assert_eq!(
-            vbe.mode_info.green_field,
+            vbe.mode_info().green_field,
             VBEField {
                 position: 8,
                 size: 8,
             }
         );
         assert_eq!(
-            vbe.mode_info.blue_field,
+            vbe.mode_info().blue_field,
             VBEField {
                 position: 0,
                 size: 8,
             }
         );
         assert_eq!(
-            vbe.mode_info.reserved_field,
+            vbe.mode_info().reserved_field,
             VBEField {
                 position: 24,
                 size: 8,
             }
         );
         assert_eq!(
-            vbe.mode_info.direct_color_attributes,
+            vbe.mode_info().direct_color_attributes,
             VBEDirectColorAttributes::RESERVED_USABLE
         );
-        assert_eq!({ vbe.mode_info.framebuffer_base_ptr }, 4244635648);
-        assert_eq!({ vbe.mode_info.offscreen_memory_offset }, 0);
-        assert_eq!({ vbe.mode_info.offscreen_memory_size }, 0);
+        assert_eq!({ vbe.mode_info().framebuffer_base_ptr }, 4244635648);
+        assert_eq!({ vbe.mode_info().offscreen_memory_offset }, 0);
+        assert_eq!({ vbe.mode_info().offscreen_memory_size }, 0);
     }
 
     #[test]

+ 62 - 18
multiboot2/src/vbe_info.rs

@@ -1,42 +1,86 @@
 //! Module for [`VBEInfoTag`].
 
-use crate::{TagHeader, TagTrait, TagType, TagTypeId};
+use crate::{TagHeader, TagTrait, TagType};
 use core::fmt;
+use core::mem;
 
 /// This tag contains VBE metadata, VBE controller information returned by the
 /// VBE Function 00h and VBE mode information returned by the VBE Function 01h.
 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
 #[repr(C, align(8))]
 pub struct VBEInfoTag {
-    typ: TagTypeId,
-    length: u32,
+    header: TagHeader,
+    mode: u16,
+    interface_segment: u16,
+    interface_offset: u16,
+    interface_length: u16,
+    control_info: VBEControlInfo,
+    mode_info: VBEModeInfo,
+}
+
+impl VBEInfoTag {
+    /// Constructs a new tag.
+    #[cfg(feature = "builder")]
+    #[must_use]
+    pub fn new(
+        mode: u16,
+        interface_segment: u16,
+        interface_offset: u16,
+        interface_length: u16,
+        control_info: VBEControlInfo,
+        mode_info: VBEModeInfo,
+    ) -> Self {
+        Self {
+            header: TagHeader::new(Self::ID, mem::size_of::<Self>().try_into().unwrap()),
+            mode,
+            interface_segment,
+            interface_offset,
+            interface_length,
+            control_info,
+            mode_info,
+        }
+    }
 
     /// Indicates current video mode in the format specified in VBE 3.0.
-    pub mode: u16,
+    #[must_use]
+    pub const fn mode(&self) -> u16 {
+        self.mode
+    }
 
-    /// Contain the segment of the table of a protected mode interface defined in VBE 2.0+.
+    /// Returns the segment of the table of a protected mode interface defined in VBE 2.0+.
     ///
     /// If the information for a protected mode interface is not available
     /// this field is set to zero.
-    pub interface_segment: u16,
-
-    /// Contain the segment offset of the table of a protected mode interface defined in VBE 2.0+.
+    #[must_use]
+    pub const fn interface_segment(&self) -> u16 {
+        self.interface_segment
+    }
+    /// Returns the segment offset of the table of a protected mode interface defined in VBE 2.0+.
     ///
     /// If the information for a protected mode interface is not available
     /// this field is set to zero.
-    pub interface_offset: u16,
-
-    /// Contain the segment length of the table of a protected mode interface defined in VBE 2.0+.
+    #[must_use]
+    pub const fn interface_offset(&self) -> u16 {
+        self.interface_offset
+    }
+    /// Returns the segment length of the table of a protected mode interface defined in VBE 2.0+.
     ///
     /// If the information for a protected mode interface is not available
     /// this field is set to zero.
-    pub interface_length: u16,
-
-    /// Contains VBE controller information returned by the VBE Function `00h`.
-    pub control_info: VBEControlInfo,
-
-    /// Contains VBE mode information returned by the VBE Function `01h`.
-    pub mode_info: VBEModeInfo,
+    #[must_use]
+    pub const fn interface_length(&self) -> u16 {
+        self.interface_length
+    }
+    /// Returns VBE controller information returned by the VBE Function `00h`.
+    #[must_use]
+    pub const fn control_info(&self) -> VBEControlInfo {
+        self.control_info
+    }
+    /// Returns VBE mode information returned by the VBE Function `01h`.
+    #[must_use]
+    pub const fn mode_info(&self) -> VBEModeInfo {
+        self.mode_info
+    }
 }
 
 impl TagTrait for VBEInfoTag {