Skip to content

Commit 3fb2328

Browse files
boot: Add freestanding memory_map
This follows the same structure as the BootServices version, so get_memory_map can be reused for exiting boot services.
1 parent d4e46c3 commit 3fb2328

File tree

1 file changed

+59
-1
lines changed

1 file changed

+59
-1
lines changed

uefi/src/boot.rs

+59-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
//! These functions will panic if called after exiting boot services.
44
55
use crate::data_types::PhysicalAddress;
6+
use crate::mem::memory_map::{MemoryMapBackingMemory, MemoryMapKey, MemoryMapMeta, MemoryMapOwned};
67
use crate::proto::device_path::DevicePath;
78
use crate::proto::{Protocol, ProtocolPointer};
89
use crate::util::opt_nonnull_to_ptr;
@@ -24,7 +25,7 @@ pub use uefi::table::boot::{
2425
AllocateType, EventNotifyFn, LoadImageSource, OpenProtocolAttributes, OpenProtocolParams,
2526
SearchType, TimerTrigger,
2627
};
27-
pub use uefi_raw::table::boot::{EventType, MemoryType, Tpl};
28+
pub use uefi_raw::table::boot::{EventType, MemoryAttribute, MemoryDescriptor, MemoryType, Tpl};
2829

2930
/// Global image handle. This is only set by [`set_image_handle`], and it is
3031
/// only read by [`image_handle`].
@@ -165,6 +166,63 @@ pub unsafe fn free_pool(ptr: NonNull<u8>) -> Result {
165166
unsafe { (bt.free_pool)(ptr.as_ptr()) }.to_result()
166167
}
167168

169+
/// Stores the current UEFI memory map in an UEFI-heap allocated buffer
170+
/// and returns a [`MemoryMapOwned`].
171+
///
172+
/// # Parameters
173+
///
174+
/// - `mt`: The memory type for the backing memory on the UEFI heap.
175+
/// Usually, this is [`MemoryType::LOADER_DATA`]. You can also use a
176+
/// custom type.
177+
///
178+
/// # Errors
179+
///
180+
/// * [`Status::BUFFER_TOO_SMALL`]
181+
/// * [`Status::INVALID_PARAMETER`]
182+
pub fn memory_map(mt: MemoryType) -> Result<MemoryMapOwned> {
183+
let mut buffer = MemoryMapBackingMemory::new(mt)?;
184+
185+
let meta = get_memory_map(buffer.as_mut_slice())?;
186+
187+
Ok(MemoryMapOwned::from_initialized_mem(buffer, meta))
188+
}
189+
190+
/// Calls the underlying `GetMemoryMap` function of UEFI. On success,
191+
/// the buffer is mutated and contains the map. The map might be shorter
192+
/// than the buffer, which is reflected by the return value.
193+
pub(crate) fn get_memory_map(buf: &mut [u8]) -> Result<MemoryMapMeta> {
194+
let bt = boot_services_raw_panicking();
195+
let bt = unsafe { bt.as_ref() };
196+
197+
let mut map_size = buf.len();
198+
let map_buffer = buf.as_mut_ptr().cast::<MemoryDescriptor>();
199+
let mut map_key = MemoryMapKey(0);
200+
let mut desc_size = 0;
201+
let mut desc_version = 0;
202+
203+
assert_eq!(
204+
(map_buffer as usize) % mem::align_of::<MemoryDescriptor>(),
205+
0,
206+
"Memory map buffers must be aligned like a MemoryDescriptor"
207+
);
208+
209+
unsafe {
210+
(bt.get_memory_map)(
211+
&mut map_size,
212+
map_buffer,
213+
&mut map_key.0,
214+
&mut desc_size,
215+
&mut desc_version,
216+
)
217+
}
218+
.to_result_with_val(|| MemoryMapMeta {
219+
map_size,
220+
desc_size,
221+
map_key,
222+
desc_version,
223+
})
224+
}
225+
168226
/// Creates an event.
169227
///
170228
/// This function creates a new event of the specified type and returns it.

0 commit comments

Comments
 (0)