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.70. 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 ctr16!
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
alloc
: Enable functionality requiring thealloc
crate from the Rust standard library. For example, methods that return aVec
rather than filling a statically-sized array. This requires a global allocator; you can use theglobal_allocator
feature 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::Allocator
as 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.logger
: Logging implementation for the standardlog
crate that prints output to the UEFI console. No buffering is done; this is not a high-performance logger.panic_handler
: Add a default panic handler that logs tostdout
.unstable
: Enable functionality that depends on unstable features in the nightly compiler. As example, in conjunction with thealloc
-feature, this gate allows theallocator_api
on certain functions.qemu
: Enable some code paths to adapt their execution when executed in QEMU, such as using the specialqemu-exit
device 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.
§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]
][entry-macro] 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
The code in this repository is licensed under the Mozilla Public License 2. This license allows you to use the crate in proprietary programs, but any modifications to the files must be open-sourced.
The full text of the license is available in the license file.
§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;
alloc
pub use data_types::CStr16;
pub use data_types::CStr8;
pub use data_types::Char16;
pub use data_types::Char8;
pub use data_types::Event;
pub use data_types::Handle;
pub use data_types::Identify;
Modules§
- This module implements Rust’s global allocator interface using UEFI’s memory allocation functions.
- UEFI boot services.
- Data type definitions
- fs
alloc
A high-level file system API for UEFI applications close to thestd::fs
module from Rust’s standard library. The main export of this module isFileSystem
. - This module provides miscellaneous opinionated but optional helpers to better integrate your application with the Rust runtime and the Rust ecosystem.
- Types, functions, traits, and other helpers to work with memory in UEFI libraries and applications.
- This module is used to simplify importing the most common UEFI types.
- Protocol definitions.
- UEFI runtime services.
- Functions for accessing fields of the system table.
- Standard UEFI tables.
Macros§
- Encode a string literal as a
&CStr8
. - Encode a string literal as a
&CStr16
. - Create a
Guid
from a string at compile time. - Create an opaque struct suitable for use as an FFI pointer.
- Prints to the standard output of the UEFI boot service console.
- Prints to the standard output of the UEFI boot service console, but with a newline.
Structs§
- An UEFI-related error with optionally additional payload data. The error kind is encoded in the
status
field (seeStatus
). Additional payload may be inside thedata
field. - Globally-unique identifier.
- UEFI uses status codes in order to report successes, errors, and warnings.
Traits§
- Extension trait which provides some convenience methods for
Result
. - Extension trait which provides some convenience methods for
Status
.
Type Aliases§
- Return type of most UEFI functions. Both success and error payloads are optional.
Attribute Macros§
- Custom attribute for a UEFI executable entry point.