浏览代码

multiboot2: add ApmTag

Philipp Schuster 7 月之前
父节点
当前提交
17e48f8beb
共有 4 个文件被更改,包括 146 次插入1 次删除
  1. 2 0
      multiboot2/CHANGELOG.md
  2. 126 0
      multiboot2/src/apm.rs
  3. 16 1
      multiboot2/src/builder.rs
  4. 2 0
      multiboot2/src/lib.rs

+ 2 - 0
multiboot2/CHANGELOG.md

@@ -4,6 +4,8 @@
 
 - dependency updates
 - **Breaking:** MSRV is now 1.75
+- Added missing tags:
+    - `ApmTag`
 
 ## v0.22.2 (2024-08-24)
 

+ 126 - 0
multiboot2/src/apm.rs

@@ -0,0 +1,126 @@
+//! Module for [`ApmTag`].
+
+use crate::{TagHeader, TagType};
+use core::mem;
+use multiboot2_common::{MaybeDynSized, Tag};
+
+/// The Advanced Power Management (APM) tag.
+#[derive(Debug)]
+#[repr(C, align(8))]
+pub struct ApmTag {
+    header: TagHeader,
+    version: u16,
+    cseg: u16,
+    offset: u32,
+    cset_16: u16,
+    dseg: u16,
+    flags: u16,
+    cseg_len: u16,
+    cseg_16_len: u16,
+    dseg_len: u16,
+}
+
+impl ApmTag {
+    /// Creates a new tag.
+    #[allow(clippy::too_many_arguments)]
+    #[must_use]
+    pub fn new(
+        version: u16,
+        cseg: u16,
+        offset: u32,
+        cset_16: u16,
+        dset: u16,
+        flags: u16,
+        cseg_len: u16,
+        cseg_16_len: u16,
+        dseg_len: u16,
+    ) -> Self {
+        Self {
+            header: TagHeader::new(TagType::Apm, mem::size_of::<Self>() as u32),
+            version,
+            cseg,
+            offset,
+            cset_16,
+            dseg: dset,
+            flags,
+            cseg_len,
+            cseg_16_len,
+            dseg_len,
+        }
+    }
+
+    /// The version number of the APM BIOS.
+    #[must_use]
+    pub const fn version(&self) -> u16 {
+        self.version
+    }
+
+    /// Contains the 16-bit code segment (CS) address for the APM entry point.
+    #[must_use]
+    pub const fn cseg(&self) -> u16 {
+        self.cseg
+    }
+
+    /// Represents the offset address within the code segment (`cseg`) for the
+    /// APM entry point.
+    #[must_use]
+    pub const fn offset(&self) -> u32 {
+        self.offset
+    }
+
+    /// Contains the 16-bit code segment (CS) address used for 16-bit protected
+    /// mode APM functions.
+    #[must_use]
+    pub const fn cset_16(&self) -> u16 {
+        self.cset_16
+    }
+
+    /// Holds the 16-bit data segment (DS) address used by the APM BIOS for
+    /// data operations.
+    #[must_use]
+    pub const fn dseg(&self) -> u16 {
+        self.dseg
+    }
+
+    /// Indicates the status and characteristics of the APM connection, such as
+    /// if APM is present and its capabilities.
+    #[must_use]
+    pub const fn flags(&self) -> u16 {
+        self.flags
+    }
+
+    /// Indicates the length, in bytes, of the data segment (`dseg`) used by
+    /// the APM BIOS
+    #[must_use]
+    pub const fn cseg_len(&self) -> u16 {
+        self.cseg_len
+    }
+
+    /// Provides the length, in bytes, of the 16-bit code segment (`cseg_16`)
+    /// used for APM functions.
+    #[must_use]
+    pub const fn cseg_16_len(&self) -> u16 {
+        self.cseg_16_len
+    }
+
+    /// Indicates the length, in bytes, of the data segment (`dseg`) used by
+    /// the APM BIOS.
+    #[must_use]
+    pub const fn dseg_len(&self) -> u16 {
+        self.dseg_len
+    }
+}
+
+impl MaybeDynSized for ApmTag {
+    type Header = TagHeader;
+
+    const BASE_SIZE: usize = mem::size_of::<Self>();
+
+    fn dst_len(_: &TagHeader) {}
+}
+
+impl Tag for ApmTag {
+    type IDType = TagType;
+
+    const ID: TagType = TagType::Apm;
+}

+ 16 - 1
multiboot2/src/builder.rs

@@ -1,5 +1,6 @@
 //! Module for [`Builder`].
 
+use crate::apm::ApmTag;
 use crate::{
     BasicMemoryInfoTag, BootInformationHeader, BootLoaderNameTag, CommandLineTag,
     EFIBootServicesNotExitedTag, EFIImageHandle32Tag, EFIImageHandle64Tag, EFIMemoryMapTag,
@@ -23,7 +24,7 @@ pub struct Builder {
     vbe: Option<VBEInfoTag>,
     framebuffer: Option<Box<FramebufferTag>>,
     elf_sections: Option<Box<ElfSectionsTag>>,
-    // missing apm:
+    apm: Option<ApmTag>,
     efi32: Option<EFISdt32Tag>,
     efi64: Option<EFISdt64Tag>,
     smbios: Vec<Box<SmbiosTag>>,
@@ -57,6 +58,7 @@ impl Builder {
             vbe: None,
             framebuffer: None,
             elf_sections: None,
+            apm: None,
             efi32: None,
             efi64: None,
             smbios: vec![],
@@ -127,6 +129,13 @@ impl Builder {
         self
     }
 
+    /// Sets the [`ApmTag`] tag.
+    #[must_use]
+    pub fn apm(mut self, apm: ApmTag) -> Self {
+        self.apm = Some(apm);
+        self
+    }
+
     /// Sets the [`EFISdt32Tag`] tag.
     #[must_use]
     pub const fn efi32(mut self, efi32: EFISdt32Tag) -> Self {
@@ -214,6 +223,9 @@ impl Builder {
     pub fn build(self) -> Box<DynSizedStructure<BootInformationHeader>> {
         let header = BootInformationHeader::new(0);
         let mut byte_refs = Vec::new();
+        if let Some(tag) = self.apm.as_ref() {
+            byte_refs.push(tag.as_bytes().as_ref());
+        }
         if let Some(tag) = self.cmdline.as_ref() {
             byte_refs.push(tag.as_bytes().as_ref());
         }
@@ -238,6 +250,9 @@ impl Builder {
         if let Some(tag) = self.elf_sections.as_ref() {
             byte_refs.push(tag.as_bytes().as_ref());
         }
+        if let Some(tag) = self.apm.as_ref() {
+            byte_refs.push(tag.as_bytes().as_ref());
+        }
         if let Some(tag) = self.efi32.as_ref() {
             byte_refs.push(tag.as_bytes().as_ref());
         }

+ 2 - 0
multiboot2/src/lib.rs

@@ -66,6 +66,7 @@ pub type TagIter<'a> = multiboot2_common::TagIter<'a, TagHeader>;
 #[cfg(test)]
 pub type GenericInfoTag = multiboot2_common::DynSizedStructure<TagHeader>;
 
+mod apm;
 mod boot_information;
 mod boot_loader_name;
 mod command_line;
@@ -85,6 +86,7 @@ mod vbe_info;
 
 pub use multiboot2_common::{DynSizedStructure, MaybeDynSized, Tag};
 
+pub use apm::ApmTag;
 pub use boot_information::{BootInformation, BootInformationHeader, LoadError};
 pub use boot_loader_name::BootLoaderNameTag;
 #[cfg(feature = "builder")]