File tree 12 files changed +134
-0
lines changed
12 files changed +134
-0
lines changed Original file line number Diff line number Diff line change @@ -170,3 +170,16 @@ jobs:
170
170
run : |
171
171
rustup component add miri
172
172
cargo xtask miri
173
+ # Builds a Rust standard binary using the `std` impl for UEFI, rather than
174
+ # creating a `no_std` + `no_main` binary.
175
+ build_standard_uefi_binary :
176
+ name : Build Standard Binary (nightly)
177
+ runs-on : ubuntu-latest
178
+ steps :
179
+ - name : Checkout sources
180
+ uses : actions/checkout@v4
181
+ - name : Set toolchain
182
+ run : cp .github/workflows/nightly_toolchain.toml rust-toolchain.toml
183
+ - uses : Swatinem/rust-cache@v2
184
+ - name : Build
185
+ run : cargo +nightly build --target x86_64-unknown-uefi --verbose -p uefi-std-example
Original file line number Diff line number Diff line change @@ -5,6 +5,7 @@ members = [
5
5
" uefi" ,
6
6
" uefi-macros" ,
7
7
" uefi-raw" ,
8
+ " uefi-std-example" ,
8
9
" uefi-test-runner" ,
9
10
" xtask" ,
10
11
]
Original file line number Diff line number Diff line change @@ -77,6 +77,8 @@ This project contains multiple sub-crates:
77
77
Specification. Safe wrappers for these types are provided by the ` uefi `
78
78
crate. The raw types are suitable for implementing UEFI firmware.
79
79
80
+ - ` uefi-std-example ` : Example UEFI app but as Rust standard binary.
81
+
80
82
- ` uefi-test-runner ` : a UEFI application that runs unit / integration tests.
81
83
82
84
[ log ] : https://github.com/rust-lang-nursery/log
Original file line number Diff line number Diff line change 10
10
- [ Using Protocols] ( how_to/protocols.md )
11
11
- [ Drawing to the Screen] ( how_to/drawing.md )
12
12
- [ Building drivers] ( how_to/building_drivers.md )
13
+ - [ Combining Rust ` std ` with ` uefi ` ] ( how_to/rust-std.md )
13
14
- [ Concepts] ( concepts/introduction.md )
14
15
- [ Boot Stages] ( concepts/boot_stages.md )
15
16
- [ Tables] ( concepts/tables.md )
Original file line number Diff line number Diff line change
1
+ # Combining Rust ` std ` with ` uefi `
2
+
3
+ ## TL;DR
4
+
5
+ In Mid-2024, we recommend to stick to our normal guide. Use this document as
6
+ guide and outlook for the future of UEFI and Rust.
7
+
8
+ ## About
9
+
10
+ Programs created with the ` uefi ` crate are typically created with ` #![no_std] `
11
+ and ` #![no_main] ` . A ` #![no_std] ` crate can use the ` core ` and ` alloc ` parts of
12
+ Rust's standard library, but not ` std ` . A ` #![no_main] ` executable does not use
13
+ the standard main entry point, and must define its own entry point; ` uefi `
14
+ provides the ` #[entry] ` macro for this purpose.
15
+
16
+ Rust has added partial support for building UEFI executables without
17
+ ` #![no_std] ` and ` #![no_main] ` , thus, the standard way. Some functionality
18
+ requires a nightly toolchain, they are gated by the ` uefi_std ` feature (Rust
19
+ language feature, not ` uefi ` crate feature). Follow the
20
+ [ tracking issue] ( https://github.com/rust-lang/rust/issues/100499 ) for details.
21
+
22
+ ## Code Example
23
+
24
+ Please refer to [ ` <repo>/uefi-std-example ` ] ( /uefi-std-example/README.md ) to
25
+ see a specific example. The relevant ` main.rs ` looks as follows:
26
+
27
+ ``` rust
28
+ {{#include .. / .. / .. / uefi - std - example / src / main . rs}}
29
+ ```
Original file line number Diff line number Diff line change @@ -21,6 +21,7 @@ pkgs.mkShell {
21
21
rustToolchain
22
22
23
23
# Other
24
+ mdbook
24
25
yamlfmt
25
26
which # used by "cargo xtask fmt"
26
27
] ;
Original file line number Diff line number Diff line change
1
+ [package ]
2
+ name = " uefi-std-example"
3
+ version = " 0.1.0"
4
+ authors = [" The Rust OSDev team" ]
5
+ publish = false
6
+ edition = " 2021"
7
+
8
+ [dependencies ]
9
+ # Attention: Don't activate the panic_handler feature, as it will clash with
10
+ # the one coming from `std`.
11
+ uefi = { path = " ../uefi" , features = [" alloc" ], default-features = false }
Original file line number Diff line number Diff line change
1
+ # Minimal Rust App using ` std ` and ` uefi `
2
+
3
+ Minimal example of a "standard Rust application" that showcases how ` uefi ` can
4
+ be utilized and enhance the developers experience, when ` std ` is available.
5
+
6
+ For simplicity, this example is minimal and the documentation is focused on
7
+ ` x86_64-unknown-uefi ` . However, it works similar for other supported UEFI
8
+ platforms.
9
+
10
+ ## Build
11
+
12
+ Build the app using
13
+ ` $ cargo +nightly build --target x86_64-unknown-uefi ` . To build it from the root
14
+ directory (the Cargo workspace), append ` -p uefi-std-example ` .
15
+
16
+ ## Run
17
+
18
+ The resulting ` .efi ` file can be found in ` target/x86_64-unknown-uefi/<debug|release>/uefi-std-example.efi ` .
Original file line number Diff line number Diff line change
1
+ // Note: In Rust 1.82.0-nightly and before, the `uefi_std` feature is
2
+ // required for accessing `std::os::uefi::env::*`. The other default
3
+ // functionality doesn't need a nightly toolchain (with Rust 1.80 and later),
4
+ // but with that limited functionality you - currently - also can't integrate
5
+ // the `uefi` crate.
6
+ #![ feature( uefi_std) ]
7
+
8
+ use std:: os:: uefi as uefi_std;
9
+ use uefi:: runtime:: ResetType ;
10
+ use uefi:: { Handle , Status } ;
11
+
12
+ /// Performs the necessary setup code for the `uefi` crate.
13
+ fn setup_uefi_crate ( ) {
14
+ let st = uefi_std:: env:: system_table ( ) ;
15
+ let ih = uefi_std:: env:: image_handle ( ) ;
16
+
17
+ // Mandatory setup code for `uefi` crate.
18
+ unsafe {
19
+ uefi:: table:: set_system_table ( st. as_ptr ( ) . cast ( ) ) ;
20
+
21
+ let ih = Handle :: from_ptr ( ih. as_ptr ( ) . cast ( ) ) . unwrap ( ) ;
22
+ uefi:: boot:: set_image_handle ( ih) ;
23
+ }
24
+ }
25
+
26
+ fn main ( ) {
27
+ println ! ( "Hello World from uefi_std" ) ;
28
+ setup_uefi_crate ( ) ;
29
+ println ! ( "UEFI-Version is {}" , uefi:: system:: uefi_revision( ) ) ;
30
+ uefi:: runtime:: reset ( ResetType :: SHUTDOWN , Status :: SUCCESS , None ) ;
31
+ }
Original file line number Diff line number Diff line change 1
1
# uefi - [ Unreleased]
2
2
3
+ We added documentation to ` lib.rs ` and the [ uefi-rs book] about how
4
+ ` uefi ` compares to "standard Rust binaries" for UEFI (those using ` std ` ), and
5
+ how to integrate the ` uefi ` crate into them.
6
+
7
+ ## Added
8
+ - Added ` Handle::new `
3
9
4
10
# uefi - 0.31.0 (2024-08-21)
5
11
@@ -603,3 +609,6 @@ Rust 1.68 or higher.
603
609
truncated and could result in out-of-bounds reads.
604
610
- Fixed size check for file info types so that alignment padding is
605
611
taken into account. This fixes potential out-of-bounds writes.
612
+
613
+
614
+ [ uefi-rs book ] : https://rust-osdev.github.io/uefi-rs/HEAD
Original file line number Diff line number Diff line change @@ -13,6 +13,17 @@ use core::ptr::{self, NonNull};
13
13
pub struct Handle ( NonNull < c_void > ) ;
14
14
15
15
impl Handle {
16
+ /// Creates a new [`Handle`].
17
+ ///
18
+ /// # Safety
19
+ /// This function is unsafe because the caller must be sure that the pointer
20
+ /// is valid. Otherwise, further operations on the object might result in
21
+ /// undefined behaviour, even if the methods aren't marked as unsafe.
22
+ #[ must_use]
23
+ pub const unsafe fn new ( ptr : NonNull < c_void > ) -> Self {
24
+ Self ( ptr)
25
+ }
26
+
16
27
/// Creates a new [`Handle`] from a raw address. The address might
17
28
/// come from the Multiboot2 information structure or something similar.
18
29
///
You can’t perform that action at this time.
0 commit comments