@@ -1258,17 +1258,23 @@ unsafe fn get_memory_map_and_exit_boot_services(buf: &mut [u8]) -> Result<Memory
1258
1258
. to_result_with_val ( || memory_map)
1259
1259
}
1260
1260
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.
1262
1269
///
1263
1270
/// After this function completes, UEFI hands over control of the hardware
1264
1271
/// to the executing OS loader, which implies that the UEFI boot services
1265
1272
/// 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.
1267
1274
///
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).
1272
1278
///
1273
1279
/// Note that once the boot services are exited, associated loggers and
1274
1280
/// 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
1277
1283
/// `global_allocator` feature is enabled, attempting to use the allocator
1278
1284
/// after exiting boot services will panic.
1279
1285
///
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
+ ///
1280
1293
/// # Safety
1281
1294
///
1282
1295
/// 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
1307
1320
/// [`Output`]: crate::proto::console::text::Output
1308
1321
/// [`PoolString`]: crate::proto::device_path::text::PoolString
1309
1322
#[ 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 ) ;
1311
1327
crate :: helpers:: exit ( ) ;
1312
1328
1313
1329
let mut buf = MemoryMapBackingMemory :: new ( memory_type) . expect ( "Failed to allocate memory" ) ;
0 commit comments