Compiler misinterpreting SystemTable::exit_boot_services signature and uefi::boot module resolution with uefi = "0.30.0"
Closed this issue · 2 comments
Hello,
I'm encountering persistent compilation errors when trying to use uefi = "0.30.0" (with uefi-services = "0.25.0" initially, then relying on uefi crate's own handlers via features logger, alloc, global_allocator, panic_handler) for a no_std UEFI application targeting x86_64-unknown-uefi with a nightly Rust toolchain.
The primary issue is with SystemTable<Boot>::exit_boot_services. The documentation for uefi v0.30.0 indicates the method signature is: pub unsafe fn exit_boot_services(self, memory_type: MemoryType) -> Result<(SystemTable<Runtime>, MemoryMap<'_>), ExitBootServicesError>
However, when I call it as unsafe { system_table.exit_boot_services(MemoryType::LOADER_DATA) } and try to match on the Result, the compiler gives an error: error[E0308]: mismatched types note: expected tuple (SystemTable<Runtime>, MemoryMap<'_>) found enum Result<_, _> This suggests the compiler believes the method directly returns a tuple, which matches a much older API style (e.g., pre-v0.15.0 where it wasn't unsafe and didn't return a Result, and MemoryMap was 'static).
Additionally, I'm facing issues resolving freestanding functions from the uefi::boot module:
use uefi::boot::memory_map_size; results in error[E0432]: unresolved import uefi::boot Calls like uefi::boot::memory_map_size(bt) result in error[E0433]: failed to resolve: could not find boot in uefi
This occurs even though the uefi v0.30.0 documentation indicates these functions (like memory_map_size, memory_map, open_protocol_exclusive, exit_boot_services as a freestanding alternative) exist in the uefi::boot module.
Other related issues include:
SystemTableExt::find_gop() (from prelude) not being found on SystemTable<Boot> instances.
Difficulty resolving uefi::proto::loaded_image::Protocol (the struct for loaded image data, not the GUID).
Cargo.toml dependencies:
[dependencies]
spin = "0.9.8"
uefi = { version = "0.30.0", features = ["logger", "alloc", "global_allocator", "panic_handler"] }
log = "0.4.20"Environment:
Target: x86_64-unknown-uefi
Toolchain: Nightly (latest available in the environment, e.g., 1.89.0-nightly)
.cargo/config.toml specifies build-std = ["core", "compiler_builtins", "alloc"] under [unstable].
Could there be a known issue with feature flag interactions, version resolution subtleties with Cargo for this target, or specific rust-toolchain.toml configurations that might lead to the compiler effectively seeing an older/different API for parts of the uefi crate than specified by the version string?
Any guidance on what might be causing this discrepancy between documented v0.30.0 API and compiler behavior would be greatly appreciated.
Thank you!
Hey there, thanks for reaching out! It seems you are new to GitHub. Please use proper markdown next time. I already revisited your issue to improve the readability.
- Why are you using
uefi-servicesat all? It is deprecated and does nothing anymore. - Why are you using
uefiin version 0.30.0 in an apparently new project? It is almost one year old. I think the most pragmatic way forward is to use a fresh version of uefi (such as 0.35). There, the "new API" using free-standing functions is much more mature - Please provide code/a minimal reproducer, such as a link to a GitHub repository. It is hard to make an assumption from your detailed writeup. Thanks for the detailed write-up but reproducers are typically a more productive way to help with these kinds of issues!
Sorry for my poor manners phip1611. I did resolve the issue, entirely my bad, here is what I did:
The main breakthrough came from correctly aligning the uefi crate versions and understanding the specific API for uefi = "0.30.0".
Here's a summary of the key resolutions:
Dependency Versioning: The most critical fix was realizing that uefi-services was pulling in a slightly different (older patch or minor) version of the uefi crate than what torux_kernel was directly depending on. This caused type mismatches for SystemTable and made the compiler resolve to incorrect method signatures (especially for exit_boot_services). Switching to uefi::helpers::init (provided by the uefi crate itself when features like "logger", "panic_handler", "global_allocator" are enabled) and ensuring torux_kernel used uefi = "0.30.0" consistently resolved this version conflict.
exit_boot_services API: For uefi v0.30.0, SystemTable::exit_boot_services is an unsafe method that takes self, image_handle, and map_buffer as arguments and returns a Result. My previous attempts were either calling it as a freestanding function (incorrect for this specific version's method) or with the wrong arguments based on misleading compiler notes that pointed to a much older API style. Correctly calling unsafe { system_table.exit_boot_services(image_handle, &mut map_buffer) } and matching on the Result was key.
Freestanding vs. Methods for Boot Services: For uefi v0.30.0, some boot service operations are freestanding functions in the uefi::boot module (e.g., memory_map_size), while others are methods on BootServices (e.g., memory_map). I had to correctly distinguish and use these based on the v0.30.0 API. My initial attempts to use freestanding functions for everything (based on v0.31.0 an_d newer trends) were incorrect for v0.30.0.
Specific API Details:
Correctly importing the LOADED_IMAGE_PROTOCOL struct (it's Protocol aliased within uefi::proto::loaded_image).
Using bt.locate_protocol_mut() for GOP (which started working once versioning issues were clearer and uefi::prelude::* could resolve traits properly).
Using load_options_cstr16_res.ok().unwrap_or(CStr16::EMPTY) for command-line options.
Ensuring CStr16::iter() correctly yields u16 values for char processing.
Stubbing: Finally, to get a clean compile while deferring full UEFI data processing, I stubbed UefiAdapter::get_boot_info to return BootInfo::default() and simplified the logic in efi_main immediately after the (now correctly compiling) exit_boot_services call.
Essentially, it was a process of version alignment, careful API checking for the specific version (v0.30.0), and then strategic stubbing to achieve a clean build milestone.
Apologies for the false issue.
I will try to shift to v0.35.
Thanks!!!