Skip to content

Commit 3d36aab

Browse files
committed
multiboot2: Get a mutable reference to the EFI memory map
1 parent 4396721 commit 3d36aab

File tree

2 files changed

+44
-0
lines changed

2 files changed

+44
-0
lines changed

multiboot2/src/lib.rs

+5
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,11 @@ impl BootInformation {
345345
}
346346
}
347347

348+
/// Search for the EFI Memory map tag, return a mutable reference.
349+
pub fn efi_memory_map_tag_mut(&mut self) -> Option<&mut EFIMemoryMapTag> {
350+
self.get_tag_mut::<EFIMemoryMapTag, _>(TagType::EfiMmap)
351+
}
352+
348353
/// Search for the EFI 32-bit image handle pointer.
349354
pub fn efi_32_ih(&self) -> Option<&EFIImageHandle32> {
350355
self.get_tag::<EFIImageHandle32, _>(TagType::Efi32Ih)

multiboot2/src/memory_map.rs

+39
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,23 @@ impl EFIMemoryMapTag {
314314
phantom: PhantomData,
315315
}
316316
}
317+
318+
#[cfg(feature = "builder")]
319+
/// Return an iterator over ALL marked memory areas, mutably.
320+
///
321+
/// This differs from `MemoryMapTag` as for UEFI, the OS needs some non-
322+
/// available memory areas for tables and such.
323+
pub fn memory_areas_mut(&mut self) -> EFIMemoryAreaIterMut {
324+
let self_ptr = self as *const EFIMemoryMapTag;
325+
let start_area = (&self.descs[0]) as *const EFIMemoryDesc;
326+
EFIMemoryAreaIterMut {
327+
current_area: start_area as u64,
328+
// NOTE: `last_area` is only a bound, it doesn't necessarily point exactly to the last element
329+
last_area: (self_ptr as *const () as u64 + self.size as u64),
330+
entry_size: self.desc_size,
331+
phantom: PhantomData,
332+
}
333+
}
317334
}
318335

319336
impl TagTrait for EFIMemoryMapTag {
@@ -532,3 +549,25 @@ impl<'a> Iterator for EFIMemoryAreaIter<'a> {
532549
}
533550
}
534551
}
552+
553+
/// An iterator over ALL EFI memory areas, mutably.
554+
#[derive(Clone, Debug)]
555+
pub struct EFIMemoryAreaIterMut<'a> {
556+
current_area: u64,
557+
last_area: u64,
558+
entry_size: u32,
559+
phantom: PhantomData<&'a mut EFIMemoryDesc>,
560+
}
561+
562+
impl<'a> Iterator for EFIMemoryAreaIterMut<'a> {
563+
type Item = &'a mut EFIMemoryDesc;
564+
fn next(&mut self) -> Option<&'a mut EFIMemoryDesc> {
565+
if self.current_area > self.last_area {
566+
None
567+
} else {
568+
let area = unsafe { &mut *(self.current_area as *mut EFIMemoryDesc) };
569+
self.current_area += self.entry_size as u64;
570+
Some(area)
571+
}
572+
}
573+
}

0 commit comments

Comments
 (0)