Skip to content

Commit 0d4201b

Browse files
YtvwlDphip1611
authored andcommitted
multiboot2: Get a mutable reference to the EFI memory map
1 parent 6a4e05b commit 0d4201b

File tree

2 files changed

+43
-0
lines changed

2 files changed

+43
-0
lines changed

multiboot2/src/lib.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,11 @@ impl<T: AsRef<BootInformationInner> + AsMut<BootInformationInner>> BootInformati
524524
self.get_tag_mut::<BasicMemoryInfoTag, _>(TagType::BasicMeminfo)
525525
}
526526

527+
/// Search for the EFI Memory map tag, return a mutable reference.
528+
pub fn efi_memory_map_tag_mut(&mut self) -> Option<&mut EFIMemoryMapTag> {
529+
self.get_tag_mut::<EFIMemoryMapTag, _>(TagType::EfiMmap)
530+
}
531+
527532
fn get_tag_mut<TagT: TagTrait + ?Sized, TagType: Into<TagTypeId>>(
528533
&mut self,
529534
typ: TagType,

multiboot2/src/memory_map.rs

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

331347
impl TagTrait for EFIMemoryMapTag {
@@ -404,3 +420,25 @@ impl<'a> Iterator for EFIMemoryAreaIter<'a> {
404420
}
405421
}
406422
}
423+
424+
/// An iterator over ALL EFI memory areas, mutably.
425+
#[derive(Clone, Debug)]
426+
pub struct EFIMemoryAreaIterMut<'a> {
427+
current_area: u64,
428+
last_area: u64,
429+
entry_size: u32,
430+
phantom: PhantomData<&'a mut EFIMemoryDesc>,
431+
}
432+
433+
impl<'a> Iterator for EFIMemoryAreaIterMut<'a> {
434+
type Item = &'a mut EFIMemoryDesc;
435+
fn next(&mut self) -> Option<&'a mut EFIMemoryDesc> {
436+
if self.current_area > self.last_area {
437+
None
438+
} else {
439+
let area = unsafe { &mut *(self.current_area as *mut EFIMemoryDesc) };
440+
self.current_area += self.entry_size as u64;
441+
Some(area)
442+
}
443+
}
444+
}

0 commit comments

Comments
 (0)