Browse Source

multiboot2: Support setting Boot Services not exited tag

Niklas Sombert 2 years ago
parent
commit
12f4642bec
3 changed files with 42 additions and 6 deletions
  1. 15 3
      multiboot2/src/builder/information.rs
  2. 2 2
      multiboot2/src/lib.rs
  3. 25 1
      multiboot2/src/memory_map.rs

+ 15 - 3
multiboot2/src/builder/information.rs

@@ -1,9 +1,9 @@
 //! Exports item [`Multiboot2InformationBuilder`].
 use crate::builder::traits::StructAsBytes;
 use crate::{
-    BasicMemoryInfoTag, BootInformationInner, BootLoaderNameTag, CommandLineTag, EFIMemoryMapTag,
-    EFISdt32, EFISdt64, ElfSectionsTag, EndTag, FramebufferTag, MemoryMapTag, ModuleTag, RsdpV1Tag,
-    RsdpV2Tag, SmbiosTag,
+    BasicMemoryInfoTag, BootInformationInner, BootLoaderNameTag, CommandLineTag,
+    EFIBootServicesNotExited, EFIMemoryMapTag, EFISdt32, EFISdt64, ElfSectionsTag, EndTag,
+    FramebufferTag, MemoryMapTag, ModuleTag, RsdpV1Tag, RsdpV2Tag, SmbiosTag,
 };
 
 use alloc::boxed::Box;
@@ -18,6 +18,7 @@ pub struct Multiboot2InformationBuilder {
     basic_memory_info_tag: Option<BasicMemoryInfoTag>,
     boot_loader_name_tag: Option<Box<BootLoaderNameTag>>,
     command_line_tag: Option<Box<CommandLineTag>>,
+    efi_boot_services_not_exited: Option<EFIBootServicesNotExited>,
     efi_memory_map_tag: Option<Box<EFIMemoryMapTag>>,
     elf_sections_tag: Option<Box<ElfSectionsTag>>,
     framebuffer_tag: Option<Box<FramebufferTag>>,
@@ -38,6 +39,7 @@ impl Multiboot2InformationBuilder {
             command_line_tag: None,
             efisdt32: None,
             efisdt64: None,
+            efi_boot_services_not_exited: None,
             efi_memory_map_tag: None,
             elf_sections_tag: None,
             framebuffer_tag: None,
@@ -85,6 +87,9 @@ impl Multiboot2InformationBuilder {
         if let Some(tag) = &self.efisdt64 {
             len += Self::size_or_up_aligned(tag.byte_size())
         }
+        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_memory_map_tag {
             len += Self::size_or_up_aligned(tag.byte_size())
         }
@@ -154,6 +159,9 @@ impl Multiboot2InformationBuilder {
         if let Some(tag) = self.efisdt64.as_ref() {
             Self::build_add_bytes(&mut data, &tag.struct_as_bytes(), false)
         }
+        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_memory_map_tag.as_ref() {
             Self::build_add_bytes(&mut data, &tag.struct_as_bytes(), false)
         }
@@ -204,6 +212,10 @@ impl Multiboot2InformationBuilder {
         self.efisdt64 = Some(efisdt64);
     }
 
+    pub fn efi_boot_services_not_exited(&mut self) {
+        self.efi_boot_services_not_exited = Some(EFIBootServicesNotExited::new());
+    }
+
     pub fn efi_memory_map_tag(&mut self, efi_memory_map_tag: Box<EFIMemoryMapTag>) {
         self.efi_memory_map_tag = Some(efi_memory_map_tag);
     }

+ 2 - 2
multiboot2/src/lib.rs

@@ -57,8 +57,8 @@ pub use elf_sections::{
 pub use framebuffer::{FramebufferColor, FramebufferField, FramebufferTag, FramebufferType};
 pub use image_load_addr::ImageLoadPhysAddr;
 pub use memory_map::{
-    BasicMemoryInfoTag, EFIMemoryAreaType, EFIMemoryDesc, EFIMemoryMapTag, MemoryArea,
-    MemoryAreaIter, MemoryAreaType, MemoryMapTag,
+    BasicMemoryInfoTag, EFIBootServicesNotExited, EFIMemoryAreaType, EFIMemoryDesc,
+    EFIMemoryMapTag, MemoryArea, MemoryAreaIter, MemoryAreaType, MemoryMapTag,
 };
 pub use module::{ModuleIter, ModuleTag};
 pub use rsdp::{RsdpV1Tag, RsdpV2Tag};

+ 25 - 1
multiboot2/src/memory_map.rs

@@ -449,10 +449,34 @@ impl Default for EFIMemoryDesc {
 #[derive(Debug)]
 #[repr(C)]
 pub struct EFIBootServicesNotExited {
-    typ: u32,
+    typ: TagTypeId,
     size: u32,
 }
 
+impl EFIBootServicesNotExited {
+    #[cfg(feature = "builder")]
+    pub fn new() -> Self {
+        Self::default()
+    }
+}
+
+#[cfg(feature = "builder")]
+impl Default for EFIBootServicesNotExited {
+    fn default() -> Self {
+        Self {
+            typ: TagType::EfiBs.into(),
+            size: mem::size_of::<Self>().try_into().unwrap(),
+        }
+    }
+}
+
+#[cfg(feature = "builder")]
+impl StructAsBytes for EFIBootServicesNotExited {
+    fn byte_size(&self) -> usize {
+        mem::size_of::<Self>()
+    }
+}
+
 /// An iterator over ALL EFI memory areas.
 #[derive(Clone, Debug)]
 pub struct EFIMemoryAreaIter<'a> {