Quellcode durchsuchen

multiboot2: Support setting the image handle pointer

Niklas Sombert vor 2 Jahren
Ursprung
Commit
ed316cbcff
2 geänderte Dateien mit 72 neuen und 3 gelöschten Zeilen
  1. 27 2
      multiboot2/src/builder/information.rs
  2. 45 1
      multiboot2/src/efi.rs

+ 27 - 2
multiboot2/src/builder/information.rs

@@ -2,8 +2,9 @@
 use crate::builder::traits::StructAsBytes;
 use crate::{
     BasicMemoryInfoTag, BootInformationInner, BootLoaderNameTag, CommandLineTag,
-    EFIBootServicesNotExited, EFIMemoryMapTag, EFISdt32, EFISdt64, ElfSectionsTag, EndTag,
-    FramebufferTag, MemoryMapTag, ModuleTag, RsdpV1Tag, RsdpV2Tag, SmbiosTag,
+    EFIBootServicesNotExited, EFIImageHandle32, EFIImageHandle64, EFIMemoryMapTag, EFISdt32,
+    EFISdt64, ElfSectionsTag, EndTag, FramebufferTag, MemoryMapTag, ModuleTag, RsdpV1Tag,
+    RsdpV2Tag, SmbiosTag,
 };
 
 use alloc::boxed::Box;
@@ -19,6 +20,8 @@ pub struct Multiboot2InformationBuilder {
     boot_loader_name_tag: Option<Box<BootLoaderNameTag>>,
     command_line_tag: Option<Box<CommandLineTag>>,
     efi_boot_services_not_exited: Option<EFIBootServicesNotExited>,
+    efi_image_handle32: Option<EFIImageHandle32>,
+    efi_image_handle64: Option<EFIImageHandle64>,
     efi_memory_map_tag: Option<Box<EFIMemoryMapTag>>,
     elf_sections_tag: Option<Box<ElfSectionsTag>>,
     framebuffer_tag: Option<Box<FramebufferTag>>,
@@ -40,6 +43,8 @@ impl Multiboot2InformationBuilder {
             efisdt32: None,
             efisdt64: None,
             efi_boot_services_not_exited: None,
+            efi_image_handle32: None,
+            efi_image_handle64: None,
             efi_memory_map_tag: None,
             elf_sections_tag: None,
             framebuffer_tag: None,
@@ -90,6 +95,12 @@ impl Multiboot2InformationBuilder {
         if let Some(tag) = &self.efi_boot_services_not_exited {
             len += Self::size_or_up_aligned(tag.byte_size())
         }
+        if let Some(tag) = &self.efi_image_handle32 {
+            len += Self::size_or_up_aligned(tag.byte_size())
+        }
+        if let Some(tag) = &self.efi_image_handle64 {
+            len += Self::size_or_up_aligned(tag.byte_size())
+        }
         if let Some(tag) = &self.efi_memory_map_tag {
             len += Self::size_or_up_aligned(tag.byte_size())
         }
@@ -162,6 +173,12 @@ impl Multiboot2InformationBuilder {
         if let Some(tag) = self.efi_boot_services_not_exited.as_ref() {
             Self::build_add_bytes(&mut data, &tag.struct_as_bytes(), false)
         }
+        if let Some(tag) = self.efi_image_handle32.as_ref() {
+            Self::build_add_bytes(&mut data, &tag.struct_as_bytes(), false)
+        }
+        if let Some(tag) = self.efi_image_handle64.as_ref() {
+            Self::build_add_bytes(&mut data, &tag.struct_as_bytes(), false)
+        }
         if let Some(tag) = self.efi_memory_map_tag.as_ref() {
             Self::build_add_bytes(&mut data, &tag.struct_as_bytes(), false)
         }
@@ -216,6 +233,14 @@ impl Multiboot2InformationBuilder {
         self.efi_boot_services_not_exited = Some(EFIBootServicesNotExited::new());
     }
 
+    pub fn efi_image_handle32(&mut self, efi_image_handle32: EFIImageHandle32) {
+        self.efi_image_handle32 = Some(efi_image_handle32);
+    }
+
+    pub fn efi_image_handle64(&mut self, efi_image_handle64: EFIImageHandle64) {
+        self.efi_image_handle64 = Some(efi_image_handle64);
+    }
+
     pub fn efi_memory_map_tag(&mut self, efi_memory_map_tag: Box<EFIMemoryMapTag>) {
         self.efi_memory_map_tag = Some(efi_memory_map_tag);
     }

+ 45 - 1
multiboot2/src/efi.rs

@@ -82,12 +82,28 @@ pub struct EFIImageHandle32 {
 }
 
 impl EFIImageHandle32 {
+    #[cfg(feature = "builder")]
+    pub fn new(pointer: u32) -> Self {
+        Self {
+            typ: TagType::Efi32Ih.into(),
+            size: size_of::<Self>().try_into().unwrap(),
+            pointer,
+        }
+    }
+
     /// Returns the physical address of the EFI image handle.
     pub fn image_handle(&self) -> usize {
         self.pointer as usize
     }
 }
 
+#[cfg(feature = "builder")]
+impl StructAsBytes for EFIImageHandle32 {
+    fn byte_size(&self) -> usize {
+        size_of::<Self>()
+    }
+}
+
 /// Contains pointer to boot loader image handle.
 #[derive(Debug)]
 #[repr(C)]
@@ -98,15 +114,31 @@ pub struct EFIImageHandle64 {
 }
 
 impl EFIImageHandle64 {
+    #[cfg(feature = "builder")]
+    pub fn new(pointer: u64) -> Self {
+        Self {
+            typ: TagType::Efi64Ih.into(),
+            size: size_of::<Self>().try_into().unwrap(),
+            pointer,
+        }
+    }
+
     /// Returns the physical address of the EFI image handle.
     pub fn image_handle(&self) -> usize {
         self.pointer as usize
     }
 }
 
+#[cfg(feature = "builder")]
+impl StructAsBytes for EFIImageHandle64 {
+    fn byte_size(&self) -> usize {
+        size_of::<Self>()
+    }
+}
+
 #[cfg(test)]
 mod tests {
-    use super::{EFISdt32, EFISdt64};
+    use super::{EFIImageHandle32, EFIImageHandle64, EFISdt32, EFISdt64};
 
     const ADDR: usize = 0xABCDEF;
 
@@ -121,4 +153,16 @@ mod tests {
         let tag = EFISdt64::new(ADDR.try_into().unwrap());
         assert_eq!(tag.sdt_address(), ADDR);
     }
+
+    #[test]
+    fn test_build_eftih32() {
+        let tag = EFIImageHandle32::new(ADDR.try_into().unwrap());
+        assert_eq!(tag.image_handle(), ADDR);
+    }
+
+    #[test]
+    fn test_build_eftih64() {
+        let tag = EFIImageHandle32::new(ADDR.try_into().unwrap());
+        assert_eq!(tag.image_handle(), ADDR);
+    }
 }