Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitaca0025

Browse files
boot: Add freestanding exit_boot_services
1 parent942e316 commitaca0025

File tree

1 file changed

+94
-0
lines changed

1 file changed

+94
-0
lines changed

‎uefi/src/boot.rs

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use crate::proto::device_path::DevicePath;
99
usecrate::proto::loaded_image::LoadedImage;
1010
usecrate::proto::media::fs::SimpleFileSystem;
1111
usecrate::proto::{Protocol,ProtocolPointer};
12+
usecrate::runtime::{self,ResetType};
1213
usecrate::table::Revision;
1314
usecrate::util::opt_nonnull_to_ptr;
1415
use core::ffi::c_void;
@@ -1070,6 +1071,99 @@ pub unsafe fn exit(
10701071
)
10711072
}
10721073

1074+
/// Get the current memory map and exit boot services.
1075+
unsafefnget_memory_map_and_exit_boot_services(buf:&mut[u8]) ->Result<MemoryMapMeta>{
1076+
let bt =boot_services_raw_panicking();
1077+
let bt =unsafe{ bt.as_ref()};
1078+
1079+
// Get the memory map.
1080+
let memory_map =get_memory_map(buf)?;
1081+
1082+
// Try to exit boot services using the memory map key. Note that after
1083+
// the first call to `exit_boot_services`, there are restrictions on
1084+
// what boot services functions can be called. In UEFI 2.8 and earlier,
1085+
// only `get_memory_map` and `exit_boot_services` are allowed. Starting
1086+
// in UEFI 2.9 other memory allocation functions may also be called.
1087+
(bt.exit_boot_services)(image_handle().as_ptr(), memory_map.map_key.0)
1088+
.to_result_with_val(|| memory_map)
1089+
}
1090+
1091+
/// Exit UEFI boot services.
1092+
///
1093+
/// After this function completes, UEFI hands over control of the hardware
1094+
/// to the executing OS loader, which implies that the UEFI boot services
1095+
/// are shut down and cannot be used anymore. Only UEFI configuration tables
1096+
/// and run-time services can be used.
1097+
///
1098+
/// The memory map at the time of exiting boot services returned. The map is
1099+
/// backed by a pool allocation of the given `memory_type`. Since the boot
1100+
/// services function to free that memory is no longer available after calling
1101+
/// `exit_boot_services`, the allocation will not be freed on drop.
1102+
///
1103+
/// Note that once the boot services are exited, associated loggers and
1104+
/// allocators can't use the boot services anymore. For the corresponding
1105+
/// abstractions provided by this crate (see the [`helpers`] module),
1106+
/// invoking this function will automatically disable them. If the
1107+
/// `global_allocator` feature is enabled, attempting to use the allocator
1108+
/// after exiting boot services will panic.
1109+
///
1110+
/// # Safety
1111+
///
1112+
/// The caller is responsible for ensuring that no references to
1113+
/// boot-services data remain. A non-exhaustive list of resources to check:
1114+
///
1115+
/// * All protocols will be invalid after exiting boot services. This
1116+
/// includes the [`Output`] protocols attached to stdout/stderr. The
1117+
/// caller must ensure that no protocol references remain.
1118+
/// * The pool allocator is not usable after exiting boot services. Types
1119+
/// such as [`PoolString`] which call [`BootServices::free_pool`] on drop
1120+
/// must be cleaned up before calling `exit_boot_services`, or leaked to
1121+
/// avoid drop ever being called.
1122+
/// * All data in the memory map marked as
1123+
/// [`MemoryType::BOOT_SERVICES_CODE`] and
1124+
/// [`MemoryType::BOOT_SERVICES_DATA`] will become free memory.
1125+
///
1126+
/// # Errors
1127+
///
1128+
/// This function will fail if it is unable to allocate memory for
1129+
/// the memory map, if it fails to retrieve the memory map, or if
1130+
/// exiting boot services fails (with up to one retry).
1131+
///
1132+
/// All errors are treated as unrecoverable because the system is
1133+
/// now in an undefined state. Rather than returning control to the
1134+
/// caller, the system will be reset.
1135+
///
1136+
/// [`helpers`]: crate::helpers
1137+
/// [`Output`]: crate::proto::console::text::Output
1138+
/// [`PoolString`]: crate::proto::device_path::text::PoolString
1139+
#[must_use]
1140+
pubunsafefnexit_boot_services(memory_type:MemoryType) ->MemoryMapOwned{
1141+
crate::helpers::exit();
1142+
1143+
letmut buf =MemoryMapBackingMemory::new(memory_type).expect("Failed to allocate memory");
1144+
1145+
// Calling `exit_boot_services` can fail if the memory map key is not
1146+
// current. Retry a second time if that occurs. This matches the
1147+
// behavior of the Linux kernel:
1148+
// https://github.com/torvalds/linux/blob/e544a0743/drivers/firmware/efi/libstub/efi-stub-helper.c#L375
1149+
letmut status =Status::ABORTED;
1150+
for _in0..2{
1151+
matchunsafe{get_memory_map_and_exit_boot_services(buf.as_mut_slice())}{
1152+
Ok(memory_map) =>{
1153+
returnMemoryMapOwned::from_initialized_mem(buf, memory_map);
1154+
}
1155+
Err(err) =>{
1156+
log::error!("Error retrieving the memory map for exiting the boot services");
1157+
status = err.status()
1158+
}
1159+
}
1160+
}
1161+
1162+
// Failed to exit boot services.
1163+
log::warn!("Resetting the machine");
1164+
runtime::reset(ResetType::COLD, status,None);
1165+
}
1166+
10731167
/// Adds, updates, or removes a configuration table entry
10741168
/// from the EFI System Table.
10751169
///

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp