Skip to content

Commit 6eeefae

Browse files
committed
mem: clarify confusion around MemoryDescriptor
I was wondering why `desc_size` is always 48 even size_of of the properly typed struct reported 40. This is by design to force users to use `desc_size`.
1 parent 9746ee6 commit 6eeefae

File tree

2 files changed

+43
-5
lines changed

2 files changed

+43
-5
lines changed

Diff for: uefi-raw/src/table/boot.rs

+19-1
Original file line numberDiff line numberDiff line change
@@ -326,12 +326,30 @@ bitflags! {
326326
}
327327
}
328328

329-
/// A structure describing a region of memory.
329+
/// A structure describing a region of memory. This type corresponds to [version]
330+
/// of this struct in the UEFI spec and is always bound to a corresponding
331+
/// UEFI memory map.
332+
///
333+
/// # UEFI pitfalls
334+
/// As of May 2024:
335+
/// The memory descriptor struct might be extended in the future by a new UEFI
336+
/// spec revision, which will be reflected in another `version` of that
337+
/// descriptor. The version is reported when using `get_memory_map` of
338+
/// [`BootServices`].
339+
///
340+
/// Also note that you **must never** work with `size_of::<MemoryDescriptor>`
341+
/// but always with `desc_size`, which is reported when using `get_memory_map`
342+
/// as well [[0]]. For example, although the actual size is of version 1
343+
/// descriptors is `40`, the reported `desc_size` is `48`.
344+
///
345+
/// [version]: MemoryDescriptor::VERSION
346+
/// [0]: https://github.com/tianocore/edk2/blob/7142e648416ff5d3eac6c6d607874805f5de0ca8/MdeModulePkg/Core/PiSmmCore/Page.c#L1059
330347
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
331348
#[repr(C)]
332349
pub struct MemoryDescriptor {
333350
/// Type of memory occupying this range.
334351
pub ty: MemoryType,
352+
// Implicit 32-bit padding.
335353
/// Starting physical address.
336354
pub phys_start: PhysicalAddress,
337355
/// Starting virtual address.

Diff for: uefi/src/table/boot.rs

+24-4
Original file line numberDiff line numberDiff line change
@@ -1617,21 +1617,35 @@ pub struct MemoryMapSize {
16171617
/// An accessory to the memory map that can be either iterated or
16181618
/// indexed like an array.
16191619
///
1620-
/// A [`MemoryMap`] is always associated with the
1621-
/// unique [`MemoryMapKey`] contained in the struct.
1620+
/// A [`MemoryMap`] is always associated with the unique [`MemoryMapKey`]
1621+
/// contained in the struct.
16221622
///
16231623
/// To iterate over the entries, call [`MemoryMap::entries`]. To get a sorted
16241624
/// map, you manually have to call [`MemoryMap::sort`] first.
1625+
///
1626+
/// ## UEFI pitfalls
1627+
/// **Please note that when working with memory maps, the `entry_size` is
1628+
/// usually larger than `size_of::<MemoryDescriptor` [[0]]. So to be safe,
1629+
/// always use `entry_size` as step-size when interfacing with the memory map on
1630+
/// a low level.
1631+
///
1632+
///
1633+
///
1634+
/// [0]:. https://github.com/tianocore/edk2/blob/7142e648416ff5d3eac6c6d607874805f5de0ca8/MdeModulePkg/Core/PiSmmCore/Page.c#L1059
16251635
#[derive(Debug)]
16261636
pub struct MemoryMap<'buf> {
16271637
key: MemoryMapKey,
16281638
buf: &'buf mut [u8],
1639+
/// Usually bound to the size of a [`MemoryDescriptor`] but can indicate if
1640+
/// this field is ever extended by a new UEFI standard.
16291641
entry_size: usize,
16301642
len: usize,
16311643
}
16321644

16331645
impl<'buf> MemoryMap<'buf> {
16341646
/// Creates a [`MemoryMap`] from the given buffer and entry size.
1647+
/// The entry size is usually bound to the size of a [`MemoryDescriptor`]
1648+
/// but can indicate if this field is ever extended by a new UEFI standard.
16351649
///
16361650
/// This allows parsing a memory map provided by a kernel after boot
16371651
/// services have already exited.
@@ -1722,8 +1736,14 @@ impl<'buf> MemoryMap<'buf> {
17221736
elem.phys_start
17231737
}
17241738

1725-
/// Returns an iterator over the contained memory map. To get a sorted map,
1726-
/// call [`MemoryMap::sort`] first.
1739+
/// Returns an [`MemoryMapIter`] emitting [`MemoryDescriptor`]s.
1740+
///
1741+
/// To get a sorted map, call [`MemoryMap::sort`] first.
1742+
///
1743+
/// # UEFI pitfalls
1744+
/// Currently, only the descriptor version specified in
1745+
/// [`MemoryDescriptor`] is supported. This is going to change if the UEFI
1746+
/// spec ever introduces a new memory descriptor version.
17271747
#[must_use]
17281748
pub fn entries(&self) -> MemoryMapIter {
17291749
MemoryMapIter {

0 commit comments

Comments
 (0)