Skip to content

Commit c72f5f7

Browse files
committed
multiboot2: Get a mutable reference to the EFI memory map
1 parent 2b385a0 commit c72f5f7

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
@@ -520,6 +520,11 @@ impl<T: AsRef<BootInformationInner> + AsMut<BootInformationInner>> BootInformati
520520
self.get_tag_mut::<BasicMemoryInfoTag, _>(TagType::BasicMeminfo)
521521
}
522522

523+
/// Search for the EFI Memory map tag, return a mutable reference.
524+
pub fn efi_memory_map_tag_mut(&mut self) -> Option<&mut EFIMemoryMapTag> {
525+
self.get_tag_mut::<EFIMemoryMapTag, _>(TagType::EfiMmap)
526+
}
527+
523528
fn get_tag_mut<TagT: TagTrait + ?Sized, TagType: Into<TagTypeId>>(
524529
&mut self,
525530
typ: TagType,

multiboot2/src/memory_map.rs

+38
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,22 @@ impl EFIMemoryMapTag {
328328
phantom: PhantomData,
329329
}
330330
}
331+
332+
/// Return an iterator over ALL marked memory areas, mutably.
333+
///
334+
/// This differs from `MemoryMapTag` as for UEFI, the OS needs some non-
335+
/// available memory areas for tables and such.
336+
pub fn memory_areas_mut(&mut self) -> EFIMemoryAreaIterMut {
337+
let self_ptr = self as *mut EFIMemoryMapTag;
338+
let start_area = (&mut self.descs[0]) as *mut EFIMemoryDesc;
339+
EFIMemoryAreaIterMut {
340+
current_area: start_area as u64,
341+
// NOTE: `last_area` is only a bound, it doesn't necessarily point exactly to the last element
342+
last_area: (self_ptr as *mut () as u64 + self.size as u64),
343+
entry_size: self.desc_size,
344+
phantom: PhantomData,
345+
}
346+
}
331347
}
332348

333349
impl TagTrait for EFIMemoryMapTag {
@@ -393,3 +409,25 @@ impl<'a> Iterator for EFIMemoryAreaIter<'a> {
393409
}
394410
}
395411
}
412+
413+
/// An iterator over ALL EFI memory areas, mutably.
414+
#[derive(Clone, Debug)]
415+
pub struct EFIMemoryAreaIterMut<'a> {
416+
current_area: u64,
417+
last_area: u64,
418+
entry_size: u32,
419+
phantom: PhantomData<&'a mut EFIMemoryDesc>,
420+
}
421+
422+
impl<'a> Iterator for EFIMemoryAreaIterMut<'a> {
423+
type Item = &'a mut EFIMemoryDesc;
424+
fn next(&mut self) -> Option<&'a mut EFIMemoryDesc> {
425+
if self.current_area > self.last_area {
426+
None
427+
} else {
428+
let area = unsafe { &mut *(self.current_area as *mut EFIMemoryDesc) };
429+
self.current_area += self.entry_size as u64;
430+
Some(area)
431+
}
432+
}
433+
}

0 commit comments

Comments
 (0)