Skip to content

Commit 5f3e1f9

Browse files
committed
multiboot2: Get a mutable reference to the EFI memory map
1 parent 42b3059 commit 5f3e1f9

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
@@ -527,6 +527,11 @@ impl<T: AsRef<BootInformationInner> + AsMut<BootInformationInner>> BootInformati
527527
self.get_tag_mut::<BasicMemoryInfoTag, _>(TagType::BasicMeminfo)
528528
}
529529

530+
/// Search for the EFI Memory map tag, return a mutable reference.
531+
pub fn efi_memory_map_tag_mut(&mut self) -> Option<&mut EFIMemoryMapTag> {
532+
self.get_tag_mut::<EFIMemoryMapTag, _>(TagType::EfiMmap)
533+
}
534+
530535
fn get_tag_mut<TagT: TagTrait + ?Sized, TagType: Into<TagTypeId>>(
531536
&mut self,
532537
typ: TagType,

multiboot2/src/memory_map.rs

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

335351
impl TagTrait for EFIMemoryMapTag {
@@ -364,3 +380,25 @@ impl<'a> Iterator for EFIMemoryAreaIter<'a> {
364380
}
365381
}
366382
}
383+
384+
/// An iterator over ALL EFI memory areas, mutably.
385+
#[derive(Clone, Debug)]
386+
pub struct EFIMemoryAreaIterMut<'a> {
387+
current_area: u64,
388+
last_area: u64,
389+
entry_size: u32,
390+
phantom: PhantomData<&'a mut EFIMemoryDesc>,
391+
}
392+
393+
impl<'a> Iterator for EFIMemoryAreaIterMut<'a> {
394+
type Item = &'a mut EFIMemoryDesc;
395+
fn next(&mut self) -> Option<&'a mut EFIMemoryDesc> {
396+
if self.current_area > self.last_area {
397+
None
398+
} else {
399+
let area = unsafe { &mut *(self.current_area as *mut EFIMemoryDesc) };
400+
self.current_area += self.entry_size as u64;
401+
Some(area)
402+
}
403+
}
404+
}

0 commit comments

Comments
 (0)