1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267
//! Rusty wrapper for the [Unified Extensible Firmware Interface][UEFI].
//!
//! 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][spec].
//!
//! # Minimal Example
//!
//! Minimal example for an UEFI application using functionality of the
//! `uefi` crate:
//!
//! ```no_run
//! #![no_main]
//! #![no_std]
//!
//! use uefi::prelude::*;
//!
//! #[entry]
//! fn main() -> Status {
//! uefi::helpers::init().unwrap();
//!
//! Status::SUCCESS
//! }
//! # extern crate std;
//! ```
//!
//! 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
//! <!-- Keep in Sync with README! -->
//!
//! 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][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][spec].
//!
//! # 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 the [`alloc`] crate from
//! the Rust standard library. For example, methods that return a
//! `Vec` rather than filling a statically-sized array. This requires
//! a global allocator; you can use the `global_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`: Set [`allocator::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 standard [`log`] 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 to `stdout`.
//! - `unstable`: Enable functionality that depends on [unstable
//! features] in the nightly compiler.
//! As example, in conjunction with the `alloc`-feature, this gate allows
//! the `allocator_api` on certain functions.
//! - `qemu`: Enable some code paths to adapt their execution when executed
//! in QEMU, such as using the special `qemu-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][contributing] for details.
//!
//! # Comparison to other Projects in the Ecosystem
//!
//! ## Rust `std` implementation
//!
//! There is an ongoing effort for a [`std` implementation][rustc-uefi-std] 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][uefi-std-tr-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
//! <!-- Keep in Sync with README! -->
//!
//! 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][LICENSE].
//!
//! # 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.
//!
//! [LICENSE]: https://github.com/rust-osdev/uefi-rs/blob/main/uefi/LICENSE
//! [Rust UEFI Book]: https://rust-osdev.github.io/uefi-rs/HEAD/
//! [UEFI]: https://uefi.org/
//! [Zulip]: https://rust-osdev.zulipchat.com
//! [`GlobalAlloc`]: alloc::alloc::GlobalAlloc
//! [`ctr16!`]: crate::cstr16
//! [`entry-macro`]: uefi_macros::entry
//! [`r-efi`]: https://crates.io/crates/r-efi
//! [`unsafe_protocol`]: proto::unsafe_protocol
//! [contributing]: https://github.com/rust-osdev/uefi-rs/blob/main/CONTRIBUTING.md
//! [issue tracker]: https://github.com/rust-osdev/uefi-rs/issues
//! [rustc-uefi-std]: https://doc.rust-lang.org/nightly/rustc/platform-support/unknown-uefi.html
//! [spec]: https://uefi.org/specifications
//! [template]: https://github.com/rust-osdev/uefi-rs/tree/main/template
//! [uefi-std-tr-issue]: https://github.com/rust-lang/rust/issues/100499
//! [unstable features]: https://doc.rust-lang.org/unstable-book/
#![cfg_attr(all(feature = "unstable", feature = "alloc"), feature(allocator_api))]
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
#![no_std]
#![deny(
clippy::all,
clippy::missing_const_for_fn,
clippy::must_use_candidate,
clippy::ptr_as_ptr,
clippy::use_self,
missing_debug_implementations,
missing_docs,
unused
)]
#[cfg(feature = "alloc")]
extern crate alloc;
// allow referring to self as ::uefi for macros to work universally (from this crate and from others)
// see https://github.com/rust-lang/rust/issues/54647
extern crate self as uefi;
#[macro_use]
extern crate uefi_raw;
#[macro_use]
pub mod data_types;
pub mod allocator;
pub mod boot;
#[cfg(feature = "alloc")]
pub mod fs;
pub mod helpers;
pub mod mem;
pub mod prelude;
pub mod proto;
pub mod runtime;
pub mod system;
pub mod table;
pub(crate) mod polyfill;
mod macros;
mod result;
mod util;
#[cfg(feature = "alloc")]
pub use data_types::CString16;
pub use data_types::{CStr16, CStr8, Char16, Char8, Event, Guid, Handle, Identify};
pub use result::{Error, Result, ResultExt, Status, StatusExt};
/// Re-export ucs2_cstr so that it can be used in the implementation of the
/// cstr16 macro. It is hidden since it's not intended to be used directly.
#[doc(hidden)]
pub use ucs2::ucs2_cstr;
pub use uefi_macros::entry;
pub use uguid::guid;