Skip to content

Commit ac14387

Browse files
authored
Merge branch 'main' into mr-devpathutil
2 parents 61bf575 + c8ccc4f commit ac14387

File tree

3 files changed

+27
-9
lines changed

3 files changed

+27
-9
lines changed

uefi-test-runner/src/main.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ extern crate alloc;
1010

1111
use alloc::string::ToString;
1212
use alloc::vec::Vec;
13-
use uefi::mem::memory_map::{MemoryMap, MemoryType};
13+
use uefi::mem::memory_map::MemoryMap;
1414
use uefi::prelude::*;
1515
use uefi::proto::console::serial::Serial;
1616
use uefi::proto::device_path::build::{self, DevicePathBuilder};
@@ -209,7 +209,7 @@ fn shutdown() -> ! {
209209
info!("Testing complete, exiting boot services...");
210210

211211
// Exit boot services as a proof that it works :)
212-
let mmap = unsafe { uefi::boot::exit_boot_services(MemoryType::LOADER_DATA) };
212+
let mmap = unsafe { uefi::boot::exit_boot_services(None) };
213213

214214
info!("Memory Map:");
215215
for desc in mmap.entries() {

uefi/CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
mode data instead of direct field access.
2121
- **Breaking:** `PoolDevicePathNode` and `PoolDevicePath` moved from module
2222
`proto::device_path::text` to `proto::device_path`.
23+
- **Breaking:** `exit_boot_services` now consumes a `Option<MemoryType>` which
24+
defaults to the recommended value of `MemoryType::LOADER_DATA`.
2325
- `boot::memory_map()` will never return `Status::BUFFER_TOO_SMALL` from now on,
2426
as this is considered a hard internal error where users can't do anything
2527
about it anyway. It will panic instead.

uefi/src/boot.rs

+23-7
Original file line numberDiff line numberDiff line change
@@ -1258,17 +1258,23 @@ unsafe fn get_memory_map_and_exit_boot_services(buf: &mut [u8]) -> Result<Memory
12581258
.to_result_with_val(|| memory_map)
12591259
}
12601260

1261-
/// Exit UEFI boot services.
1261+
/// Convenient wrapper to exit UEFI boot services along with corresponding
1262+
/// essential steps to get the memory map.
1263+
///
1264+
/// Exiting UEFI boot services requires a **non-trivial sequence of steps**,
1265+
/// including safe retrieval and finalization of the memory map. This wrapper
1266+
/// ensures a safe and spec-compliant transition from UEFI boot services to
1267+
/// runtime services by retrieving the system memory map and invoking
1268+
/// `ExitBootServices()` with the correct memory map key, retrying if necessary.
12621269
///
12631270
/// After this function completes, UEFI hands over control of the hardware
12641271
/// to the executing OS loader, which implies that the UEFI boot services
12651272
/// are shut down and cannot be used anymore. Only UEFI configuration tables
1266-
/// and run-time services can be used.
1273+
/// and runtime services can be used.
12671274
///
1268-
/// The memory map at the time of exiting boot services returned. The map is
1269-
/// backed by a pool allocation of the given `memory_type`. Since the boot
1270-
/// services function to free that memory is no longer available after calling
1271-
/// `exit_boot_services`, the allocation will not be freed on drop.
1275+
/// Since the boot services function to free memory is no longer available after
1276+
/// this function returns, the allocation will not be freed on drop. It will
1277+
/// however be reflected by the memory map itself (self-contained).
12721278
///
12731279
/// Note that once the boot services are exited, associated loggers and
12741280
/// allocators can't use the boot services anymore. For the corresponding
@@ -1277,6 +1283,13 @@ unsafe fn get_memory_map_and_exit_boot_services(buf: &mut [u8]) -> Result<Memory
12771283
/// `global_allocator` feature is enabled, attempting to use the allocator
12781284
/// after exiting boot services will panic.
12791285
///
1286+
/// # Arguments
1287+
/// - `custom_memory_type`: The [`MemoryType`] for the UEFI allocation that will
1288+
/// store the final memory map. If you pass `None`, this defaults to the
1289+
/// recommended default value of [`MemoryType::LOADER_DATA`]. If you want a
1290+
/// specific memory region for the memory map, you can pass the desired
1291+
/// [`MemoryType`].
1292+
///
12801293
/// # Safety
12811294
///
12821295
/// The caller is responsible for ensuring that no references to
@@ -1307,7 +1320,10 @@ unsafe fn get_memory_map_and_exit_boot_services(buf: &mut [u8]) -> Result<Memory
13071320
/// [`Output`]: crate::proto::console::text::Output
13081321
/// [`PoolString`]: crate::proto::device_path::text::PoolString
13091322
#[must_use]
1310-
pub unsafe fn exit_boot_services(memory_type: MemoryType) -> MemoryMapOwned {
1323+
pub unsafe fn exit_boot_services(custom_memory_type: Option<MemoryType>) -> MemoryMapOwned {
1324+
// LOADER_DATA is the default and also used by the Linux kernel:
1325+
// https://elixir.bootlin.com/linux/v6.13.7/source/drivers/firmware/efi/libstub/mem.c#L24
1326+
let memory_type = custom_memory_type.unwrap_or(MemoryType::LOADER_DATA);
13111327
crate::helpers::exit();
13121328

13131329
let mut buf = MemoryMapBackingMemory::new(memory_type).expect("Failed to allocate memory");

0 commit comments

Comments
 (0)