1 //! Rusty wrapper for the [Unified Extensible Firmware Interface][UEFI]. 2 //! 3 //! This crate makes it easy to develop Rust software that leverages **safe**, 4 //! **convenient**, and **performant** abstractions for [UEFI] functionality. 5 //! 6 //! See the [Rust UEFI Book] for a tutorial, how-tos, and overviews of some 7 //! important UEFI concepts. For more details of UEFI, see the latest [UEFI 8 //! Specification][spec]. 9 //! 10 //! # Minimal Example 11 //! 12 //! Minimal example for an UEFI application using functionality of the 13 //! `uefi` crate: 14 //! 15 //! ```no_run 16 //! #![no_main] 17 //! #![no_std] 18 //! 19 //! use uefi::prelude::*; 20 //! 21 //! #[entry] 22 //! fn main() -> Status { 23 //! uefi::helpers::init().unwrap(); 24 //! 25 //! Status::SUCCESS 26 //! } 27 //! # extern crate std; 28 //! ``` 29 //! 30 //! Please find more info in our [Rust UEFI Book]. 31 //! 32 //! # Value-add and Use Cases 33 //! 34 //! `uefi` supports writing code for both pre- and post-exit boot services 35 //! epochs, but its true strength shines when you create UEFI images that heavily 36 //! interact with UEFI boot services. Still, you have the flexibility to just 37 //! integrate selected types and abstractions into your project, for example to 38 //! parse the UEFI memory map. 39 //! 40 //! _Note that for producing UEFI images, you also need to use a corresponding 41 //! `uefi` compiler target of Rust, such as `x86_64-unknown-uefi`._ 42 //! 43 //! ## Example Use Cases 44 //! 45 //! This library significantly simplifies the process of creating **UEFI images** 46 //! by abstracting away much of the UEFI API complexity and by providing 47 //! convenient wrappers. When we mention UEFI images, we are talking about UEFI 48 //! applications, UEFI boot service drivers, and EFI runtime service drivers, 49 //! which typically have the `.efi` file extension. For instance, an UEFI 50 //! application could be an OS-specific loader, similar to _GRUB_ or _Limine_. 51 //! 52 //! Additionally, you can use this crate in non-UEFI images (such as a kernel 53 //! in ELF format) to perform tasks like parsing the UEFI memory map embedded in 54 //! the boot information provided by a bootloader. It also enables access to 55 //! UEFI runtime services from a non-UEFI image kernel. 56 //! 57 //! # Supported Compiler Versions and Architectures 58 //! 59 //! `uefi` works with stable Rust, but additional nightly-only features are 60 //! gated behind the `unstable` Cargo feature. Please find more information 61 //! about additional crate features below. 62 //! 63 //! `uefi` is compatible with all platforms that both the Rust compiler and 64 //! UEFI support, such as `i686`, `x86_64`, and `aarch64`. Please note that we 65 //! can't test all possible hardware/firmware/platform combinations in CI. 66 //! 67 //! ## MSRV 68 //! <!-- Keep in Sync with README! --> 69 //! 70 //! The minimum supported Rust version is currently 1.70. 71 //! Our policy is to support at least the past two stable releases. 72 //! 73 //! # API/User Documentation, Documentation Structure, and other Resources 74 //! 75 //! Down below, you find typical technical documentation of all types, modules, 76 //! and functions exported by `uefi`. 77 //! 78 //! For a TL;DR quick start with an example on how to create your own EFI 79 //! application, please check out [the UEFI application template][template]. The 80 //! [Rust UEFI Book] is a more beginner-friendly tutorial with How-Tos, and 81 //! overviews of some important UEFI concepts and the abstractions provided by 82 //! this library. 83 //! 84 //! For more details of UEFI itself, see the latest [UEFI Specification][spec]. 85 //! 86 //! # Library Structure & Tips 87 //! 88 //! The top-level module contains some of the most used types and macros, 89 //! including the [`Handle`] and [`Result`] types, the [`CStr16`] and 90 //! [`CString16`] types for working with UCS-2 strings, and the [`entry`] and 91 //! [`guid`] macros. 92 //! 93 //! ## UEFI Strings 94 //! 95 //! Rust string literals are UTF-8 encoded and thus, not compatible with most 96 //! UEFI interfaces. We provide [`CStr16`] and [`CString16`] for proper working 97 //! with UCS-2 strings, including various transformation functions from standard 98 //! Rust strings. You can use [`ctr16!`] to create UCS-2 string literals at 99 //! compile time. 100 //! 101 //! ## Tables 102 //! 103 //! Most UEFI functionality comes from the system, boot, and runtime 104 //! tables. These can be accessed via the [`system`], [`boot`], and [`runtime`] 105 //! modules. 106 //! 107 //! ## Protocols 108 //! 109 //! When boot services are active, most functionality is provided via UEFI 110 //! protocols. Protocols provide operations such as reading and writing files, 111 //! drawing to the screen, sending and receiving network requests, and much 112 //! more. The list of protocols that are actually available when running an 113 //! application depends on the device. For example, a PC with no network card 114 //! may not provide network protocols. 115 //! 116 //! See the [`boot`] documentation for details of how to open a 117 //! protocol, and see the [`proto`] module for protocol implementations. New 118 //! protocols can be defined with the [`unsafe_protocol`] macro. 119 //! 120 //! ## Optional Cargo crate features 121 //! 122 //! - `alloc`: Enable functionality requiring the [`alloc`] crate from 123 //! the Rust standard library. For example, methods that return a 124 //! `Vec` rather than filling a statically-sized array. This requires 125 //! a global allocator; you can use the `global_allocator` feature or 126 //! provide your own. This is independent of internal direct usages of the 127 //! UEFI boot service allocator which may happen anyway, where necessary. 128 //! - `global_allocator`: Set [`allocator::Allocator`] as the global Rust 129 //! allocator. This is a simple allocator that relies on the UEFI pool 130 //! allocator. You can choose to provide your own allocator instead of 131 //! using this feature, or no allocator at all if you don't need to 132 //! dynamically allocate any memory. 133 //! - `logger`: Logging implementation for the standard [`log`] crate 134 //! that prints output to the UEFI console. No buffering is done; this 135 //! is not a high-performance logger. 136 //! - `panic_handler`: Add a default panic handler that logs to `stdout`. 137 //! - `unstable`: Enable functionality that depends on [unstable 138 //! features] in the nightly compiler. 139 //! As example, in conjunction with the `alloc`-feature, this gate allows 140 //! the `allocator_api` on certain functions. 141 //! - `qemu`: Enable some code paths to adapt their execution when executed 142 //! in QEMU, such as using the special `qemu-exit` device when the panic 143 //! handler is called. 144 //! 145 //! Some of these features, such as the `logger` or `panic_handler` features, 146 //! only unfold their potential when you invoke `uefi::helpers::init` as soon 147 //! as possible in your application. 148 //! 149 //! # Discuss and Contribute 150 //! 151 //! For general discussions, feel free to join us in our [Zulip] and ask 152 //! your questions there. 153 //! 154 //! Further, you can submit bugs and also ask questions in our [issue tracker]. 155 //! Contributions in the form of a PR are also highly welcome. Check our 156 //! [contributing guide][contributing] for details. 157 //! 158 //! # Comparison to other Projects in the Ecosystem 159 //! 160 //! ## Rust `std` implementation 161 //! 162 //! There is an ongoing effort for a [`std` implementation][rustc-uefi-std] of 163 //! the Rust standard library, which allows you to write UEFI programs that look 164 //! very similar to normal Rust programs running on top of an OS. 165 //! 166 //! It is still under development. You can track the progress in the 167 //! corresponding [tracking issue][uefi-std-tr-issue]. 168 //! 169 //! Using the `std` implementation simplifies the overall process of producing 170 //! the binary. For example, our [`#[entry]`][entry-macro] macro won't be 171 //! required any longer. As the `std` implementation evolves over time, you'll 172 //! need fewer and fewer abstractions of this crate. For everything not covered 173 //! by the `std` implementation, you can obtain relevant structures to work with 174 //! our crate via: 175 //! - `std::os::uefi::env::boot_services()` 176 //! - `std::os::uefi::env::get_system_handle()` 177 //! - `std::os::uefi::env::get_system_table()` 178 //! 179 //! ## `r-efi` 180 //! 181 //! [`r-efi`] provides Raw UEFI bindings without high-level convenience similar 182 //! to our `uefi-raw` crate, which is part of this project, but more 183 //! feature-complete. It targets a lower-level than our `uefi` crate does. 184 //! 185 //! # License 186 //! <!-- Keep in Sync with README! --> 187 //! 188 //! The code in this repository is licensed under the Mozilla Public License 2. 189 //! This license allows you to use the crate in proprietary programs, but any 190 //! modifications to the files must be open-sourced. 191 //! 192 //! The full text of the license is available in the [license file][LICENSE]. 193 //! 194 //! # Terminology 195 //! 196 //! Both "EFI" and "UEFI" can be used interchangeably, such as "UEFI image" or 197 //! "EFI image". We prefer "UEFI" in our crate and its documentation. 198 //! 199 //! [LICENSE]: https://github.com/rust-osdev/uefi-rs/blob/main/uefi/LICENSE 200 //! [Rust UEFI Book]: https://rust-osdev.github.io/uefi-rs/HEAD/ 201 //! [UEFI]: https://uefi.org/ 202 //! [Zulip]: https://rust-osdev.zulipchat.com 203 //! [`GlobalAlloc`]: alloc::alloc::GlobalAlloc 204 //! [`ctr16!`]: crate::cstr16 205 //! [`entry-macro`]: uefi_macros::entry 206 //! [`r-efi`]: https://crates.io/crates/r-efi 207 //! [`unsafe_protocol`]: proto::unsafe_protocol 208 //! [contributing]: https://github.com/rust-osdev/uefi-rs/blob/main/CONTRIBUTING.md 209 //! [issue tracker]: https://github.com/rust-osdev/uefi-rs/issues 210 //! [rustc-uefi-std]: https://doc.rust-lang.org/nightly/rustc/platform-support/unknown-uefi.html 211 //! [spec]: https://uefi.org/specifications 212 //! [template]: https://github.com/rust-osdev/uefi-rs/tree/main/template 213 //! [uefi-std-tr-issue]: https://github.com/rust-lang/rust/issues/100499 214 //! [unstable features]: https://doc.rust-lang.org/unstable-book/ 215 216 #![cfg_attr(all(feature = "unstable", feature = "alloc"), feature(allocator_api))] 217 #![cfg_attr(docsrs, feature(doc_auto_cfg))] 218 #![no_std] 219 #![deny( 220 clippy::all, 221 clippy::missing_const_for_fn, 222 clippy::must_use_candidate, 223 clippy::ptr_as_ptr, 224 clippy::use_self, 225 missing_debug_implementations, 226 missing_docs, 227 unused 228 )] 229 230 #[cfg(feature = "alloc")] 231 extern crate alloc; 232 // allow referring to self as ::uefi for macros to work universally (from this crate and from others) 233 // see https://github.com/rust-lang/rust/issues/54647 234 extern crate self as uefi; 235 #[macro_use] 236 extern crate uefi_raw; 237 238 #[macro_use] 239 pub mod data_types; 240 pub mod allocator; 241 pub mod boot; 242 #[cfg(feature = "alloc")] 243 pub mod fs; 244 pub mod helpers; 245 pub mod mem; 246 pub mod prelude; 247 pub mod proto; 248 pub mod runtime; 249 pub mod system; 250 pub mod table; 251 252 pub(crate) mod polyfill; 253 254 mod macros; 255 mod result; 256 mod util; 257 258 #[cfg(feature = "alloc")] 259 pub use data_types::CString16; 260 pub use data_types::{CStr16, CStr8, Char16, Char8, Event, Guid, Handle, Identify}; 261 pub use result::{Error, Result, ResultExt, Status, StatusExt}; 262 /// Re-export ucs2_cstr so that it can be used in the implementation of the 263 /// cstr16 macro. It is hidden since it's not intended to be used directly. 264 #[doc(hidden)] 265 pub use ucs2::ucs2_cstr; 266 pub use uefi_macros::entry; 267 pub use uguid::guid; 268