Skip to content

Commit a9faea2

Browse files
committed
multiboot2: Get a mutable reference to the EFI memory map
1 parent b563d1f commit a9faea2

File tree

2 files changed

+43
-0
lines changed

2 files changed

+43
-0
lines changed

multiboot2/src/lib.rs

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

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

multiboot2/src/memory_map.rs

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

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

0 commit comments

Comments
 (0)