Skip to content

Commit b49d4fd

Browse files
committed
multiboot2: Get a mutable reference to the EFI memory map
1 parent 1272d85 commit b49d4fd

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
@@ -380,6 +380,11 @@ impl<'a> BootInformation<'a> {
380380
}
381381
}
382382

383+
/// Search for the EFI Memory map tag, return a mutable reference.
384+
pub fn efi_memory_map_tag_mut<'b: 'a>(&'b mut self) -> Option<&'b mut EFIMemoryMapTag> {
385+
self.get_tag_mut::<EFIMemoryMapTag, _>(TagType::EfiMmap)
386+
}
387+
383388
/// Search for the EFI 32-bit image handle pointer tag.
384389
pub fn efi_32_ih_tag(&self) -> Option<&EFIImageHandle32Tag> {
385390
self.get_tag::<EFIImageHandle32Tag, _>(TagType::Efi32Ih)

multiboot2/src/memory_map.rs

+38
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,22 @@ impl EFIMemoryMapTag {
254254
phantom: PhantomData,
255255
}
256256
}
257+
258+
/// Return an iterator over ALL marked memory areas, mutably.
259+
///
260+
/// This differs from `MemoryMapTag` as for UEFI, the OS needs some non-
261+
/// available memory areas for tables and such.
262+
pub fn memory_areas_mut(&mut self) -> EFIMemoryAreaIterMut {
263+
let self_ptr = self as *const EFIMemoryMapTag;
264+
let start_area = (&self.descs[0]) as *const EFIMemoryDesc;
265+
EFIMemoryAreaIterMut {
266+
current_area: start_area as u64,
267+
// NOTE: `last_area` is only a bound, it doesn't necessarily point exactly to the last element
268+
last_area: (self_ptr as *const () as u64 + self.size as u64),
269+
entry_size: self.desc_size,
270+
phantom: PhantomData,
271+
}
272+
}
257273
}
258274

259275
impl TagTrait for EFIMemoryMapTag {
@@ -332,3 +348,25 @@ impl<'a> Iterator for EFIMemoryAreaIter<'a> {
332348
}
333349
}
334350
}
351+
352+
/// An iterator over ALL EFI memory areas, mutably.
353+
#[derive(Clone, Debug)]
354+
pub struct EFIMemoryAreaIterMut<'a> {
355+
current_area: u64,
356+
last_area: u64,
357+
entry_size: u32,
358+
phantom: PhantomData<&'a mut EFIMemoryDesc>,
359+
}
360+
361+
impl<'a> Iterator for EFIMemoryAreaIterMut<'a> {
362+
type Item = &'a mut EFIMemoryDesc;
363+
fn next(&mut self) -> Option<&'a mut EFIMemoryDesc> {
364+
if self.current_area > self.last_area {
365+
None
366+
} else {
367+
let area = unsafe { &mut *(self.current_area as *mut EFIMemoryDesc) };
368+
self.current_area += self.entry_size as u64;
369+
Some(area)
370+
}
371+
}
372+
}

0 commit comments

Comments
 (0)