Combining Rust std
with uefi
TL;DR
In Mid-2024, we recommend to stick to our normal guide. Use this document as guide and outlook for the future of UEFI and Rust.
About
Programs created with the uefi
crate are typically created with #![no_std]
and #![no_main]
. A #![no_std]
crate can use the core
and alloc
parts of
Rust's standard library, but not std
. A #![no_main]
executable does not use
the standard main entry point, and must define its own entry point; uefi
provides the #[entry]
macro for this purpose.
Rust has added partial support for building UEFI executables without
#![no_std]
and #![no_main]
, thus, the standard way. Some functionality
requires a nightly toolchain, they are gated by the uefi_std
feature (Rust
language feature, not uefi
crate feature). Follow the
tracking issue for details.
Code Example
Please refer to <repo>/uefi-std-example
to
see a specific example. The relevant main.rs
looks as follows:
// Note: In Rust 1.82.0-nightly and before, the `uefi_std` feature is // required for accessing `std::os::uefi::env::*`. The other default // functionality doesn't need a nightly toolchain (with Rust 1.80 and later), // but with that limited functionality you - currently - also can't integrate // the `uefi` crate. #![feature(uefi_std)] use std::os::uefi as uefi_std; use uefi::runtime::ResetType; use uefi::{Handle, Status}; /// Performs the necessary setup code for the `uefi` crate. fn setup_uefi_crate() { let st = uefi_std::env::system_table(); let ih = uefi_std::env::image_handle(); // Mandatory setup code for `uefi` crate. unsafe { uefi::table::set_system_table(st.as_ptr().cast()); let ih = Handle::from_ptr(ih.as_ptr().cast()).unwrap(); uefi::boot::set_image_handle(ih); } } fn main() { println!("Hello World from uefi_std"); setup_uefi_crate(); println!("UEFI-Version is {}", uefi::system::uefi_revision()); uefi::runtime::reset(ResetType::SHUTDOWN, Status::SUCCESS, None); }