Expand description
Rusty wrapper for the Unified Extensible Firmware Interface.
This crate makes it easy to develop Rust software that leverages safe, convenient, and performant abstractions for UEFI functionality.
See the Rust UEFI Book for a tutorial, how-tos, and overviews of some important UEFI concepts. For more details of UEFI, see the latest UEFI Specification.
§Minimal Example
Minimal example for an UEFI application using functionality of the
uefi crate:
#![no_main]
#![no_std]
use uefi::prelude::*;
#[entry]
fn main() -> Status {
uefi::helpers::init().unwrap();
Status::SUCCESS
}Please find more info in our Rust UEFI Book.
§Value-add and Use Cases
uefi supports writing code for both pre- and post-exit boot services
epochs, but its true strength shines when you create UEFI images that heavily
interact with UEFI boot services. Still, you have the flexibility to just
integrate selected types and abstractions into your project, for example to
parse the UEFI memory map.
Note that for producing UEFI images, you also need to use a corresponding
uefi compiler target of Rust, such as x86_64-unknown-uefi.
§Example Use Cases
This library significantly simplifies the process of creating UEFI images
by abstracting away much of the UEFI API complexity and by providing
convenient wrappers. When we mention UEFI images, we are talking about UEFI
applications, UEFI boot service drivers, and EFI runtime service drivers,
which typically have the .efi file extension. For instance, an UEFI
application could be an OS-specific loader, similar to GRUB or Limine.
Additionally, you can use this crate in non-UEFI images (such as a kernel in ELF format) to perform tasks like parsing the UEFI memory map embedded in the boot information provided by a bootloader. It also enables access to UEFI runtime services from a non-UEFI image kernel.
§Supported Compiler Versions and Architectures
uefi works with stable Rust, but additional nightly-only features are
gated behind the unstable Cargo feature. Please find more information
about additional crate features below.
uefi is compatible with all platforms that both the Rust compiler and
UEFI support, such as i686, x86_64, and aarch64. Please note that we
can’t test all possible hardware/firmware/platform combinations in CI.
§MSRV
The minimum supported Rust version is currently 1.81. Our policy is to support at least the past two stable releases.
§API/User Documentation, Documentation Structure, and other Resources
Down below, you find typical technical documentation of all types, modules,
and functions exported by uefi.
For a TL;DR quick start with an example on how to create your own EFI application, please check out the UEFI application template. The Rust UEFI Book is a more beginner-friendly tutorial with How-Tos, and overviews of some important UEFI concepts and the abstractions provided by this library.
For more details of UEFI itself, see the latest UEFI Specification.
§Library Structure & Tips
The top-level module contains some of the most used types and macros,
including the Handle and Result types, the CStr16 and
CString16 types for working with UCS-2 strings, and the entry and
guid macros.
§UEFI Strings
Rust string literals are UTF-8 encoded and thus, not compatible with most
UEFI interfaces. We provide CStr16 and CString16 for proper working
with UCS-2 strings, including various transformation functions from standard
Rust strings. You can use cstr16! to create UCS-2 string literals at
compile time.
§Tables
Most UEFI functionality comes from the system, boot, and runtime
tables. These can be accessed via the system, boot, and runtime
modules.
§Protocols
When boot services are active, most functionality is provided via UEFI protocols. Protocols provide operations such as reading and writing files, drawing to the screen, sending and receiving network requests, and much more. The list of protocols that are actually available when running an application depends on the device. For example, a PC with no network card may not provide network protocols.
See the boot documentation for details of how to open a
protocol, and see the proto module for protocol implementations. New
protocols can be defined with the unsafe_protocol macro.
§Optional Cargo crate features
A list of recommended default features follows below.
§Feature List
alloc: Enable functionality requiring thealloccrate from the Rust standard library. For example, methods that return aVecrather than filling a statically-sized array. This requires a global allocator; you can use theglobal_allocatorfeature or provide your own. This is independent of internal direct usages of the UEFI boot service allocator which may happen anyway, where necessary.global_allocator: Setallocator::Allocatoras the global Rust allocator. This is a simple allocator that relies on the UEFI pool allocator. You can choose to provide your own allocator instead of using this feature, or no allocator at all if you don’t need to dynamically allocate any memory. Note that even without that feature, some code might use the internal UEFI allocator.logger: Logging implementation for the standardlogcrate that prints output to the UEFI console. No buffering is done; this is not a high-performance logger.log-debugcon: Whether the logger set up byloggershould also log to the debugcon device (available in QEMU or Cloud Hypervisor on x86).panic_handler: Add a default panic handler that logs tostdout.unstable: Enable functionality that depends on unstable features in the Rust compiler (nightly version).qemu: Enable some code paths to adapt their execution when executed in QEMU, such as using the specialqemu-exitdevice when the panic handler is called.
Some of these features, such as the logger or panic_handler features,
only unfold their potential when you invoke uefi::helpers::init as soon
as possible in your application.
§Recommended Default Features
In typical use-cases, the following features are useful for you:
- Building a UEFI image:
- Recommended:
alloc,global_allocator,logger,panic_handler - Optional:
log-debugcon,qemu,unstable
- Recommended:
- Building another application/library:
- Recommended:
alloc - Optional:
unstable
- Recommended:
§Discuss and Contribute
For general discussions, feel free to join us in our Zulip and ask your questions there.
Further, you can submit bugs and also ask questions in our issue tracker. Contributions in the form of a PR are also highly welcome. Check our contributing guide for details.
§Comparison to other Projects in the Ecosystem
§Rust std implementation
There is an ongoing effort for a std implementation of
the Rust standard library, which allows you to write UEFI programs that look
very similar to normal Rust programs running on top of an OS.
It is still under development. You can track the progress in the corresponding tracking issue.
Using the std implementation simplifies the overall process of producing
the binary. For example, our #[entry] macro won’t be
required any longer. As the std implementation evolves over time, you’ll
need fewer and fewer abstractions of this crate. For everything not covered
by the std implementation, you can obtain relevant structures to work with
our crate via:
std::os::uefi::env::boot_services()std::os::uefi::env::get_system_handle()std::os::uefi::env::get_system_table()
§r-efi
r-efi provides Raw UEFI bindings without high-level convenience similar
to our uefi-raw crate, which is part of this project, but more
feature-complete. It targets a lower-level than our uefi crate does.
§License
Licensed under either of Apache License, Version 2.0 or MIT license at your option.
§Terminology
Both “EFI” and “UEFI” can be used interchangeably, such as “UEFI image” or “EFI image”. We prefer “UEFI” in our crate and its documentation.
Re-exports§
pub use data_types::CString16;allocpub use data_types::CStr8;pub use data_types::CStr16;pub use data_types::Char8;pub use data_types::Char16;pub use data_types::Event;pub use data_types::Handle;pub use data_types::Identify;
Modules§
- allocator
- This module exports
Allocator. - boot
- UEFI boot services.
- data_
types - Data type definitions
- fs
alloc - A high-level file system API for UEFI applications close to the
std::fsmodule from Rust’s standard library. The main export of this module isFileSystem. - helpers
- This module provides miscellaneous opinionated but optional helpers to better integrate your application with the Rust runtime and the Rust ecosystem.
- mem
- Types, functions, traits, and other helpers to work with memory in UEFI libraries and applications.
- prelude
- This module is used to simplify importing the most common UEFI types.
- proto
- High-level wrappers for UEFI protocols.
- runtime
- UEFI runtime services.
- system
- Functions for accessing fields of the system table.
- table
- Standard UEFI tables.
Macros§
- cstr8
- Encode a string literal as a
&CStr8. - cstr16
- Encode a string literal as a
&CStr16. - guid
- Create a
Guidfrom a string at compile time. - opaque_
type - Create an opaque struct suitable for use as an FFI pointer.
- Prints to the standard output of the UEFI boot service console.
- println
- Prints to the standard output of the UEFI boot service console, but with a newline.
Structs§
- Error
- An UEFI-related error with optionally additional payload data. The error
kind is encoded in the
statusfield (seeStatus). Additional payload may be inside thedatafield. - Guid
- Globally-unique identifier.
- Status
- UEFI uses status codes in order to report successes, errors, and warnings.
Traits§
- Result
Ext - Extension trait which provides some convenience methods for
Result. - Status
Ext - Extension trait which provides some convenience methods for
Status.
Type Aliases§
- Result
- Return type of most UEFI functions. Both success and error payloads are optional.
Attribute Macros§
- entry
- Custom attribute for a UEFI executable entry point.