diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index f6c69ec63..5b9e51c75 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -48,6 +48,12 @@ jobs: components: rust-src # TODO: cache Rust binaries + - name: Build template + uses: actions-rs/cargo@v1 + with: + command: build + args: --target x86_64-unknown-uefi --manifest-path template/Cargo.toml + - name: Build run: ./build.py build working-directory: ./uefi-test-runner diff --git a/BUILDING.md b/BUILDING.md index 9e7482764..93236ff07 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -5,30 +5,25 @@ UEFI applications are simple COFF (Windows) executables, with the special [Rust supports building UEFI applications](https://github.com/rust-lang/rust/pull/56769) though the `x86_64-unknown-uefi` target. -## Steps +## Template -The following steps allow you to build a simple UEFI app. +The [template](template) subdirectory contains a minimal example of a UEFI +application. Copy it to a new directory to get started. -- Create a new `#![no_std]` binary, add `#![no_main]` to use a custom entry point, - and make sure you have an entry point function which matches the one below: - ```rust - #![feature(abi_efiapi)] - use uefi::prelude::*; +- [template/.cargo/config](template/.cargo/config) file sets some `build-std` options. +- [template/Cargo.toml](template/Cargo.toml) shows the necessary + dependencies. Note that when creating your project the + [`uefi`](https://crates.io/crates/uefi) and + [`uefi-services`](https://crates.io/crates/uefi-services) dependencies should + be changed to the latest releases on [crates.io](https://crates.io). +- [template/src/main.rs](template/src/main.rs) has a minimal entry point that + initializes services and exits successfully. - extern crate rlibc; - - #[entry] - fn main(handle: Handle, mut system_table: SystemTable) -> Status; - ``` - Note that Rust EFI target requires the entry function to be exported with an `efi_main` symbol, - the `#[entry]` macro takes care of that, so the function name is irrelevant. - - You will also want to add a dependency to the [`rlibc`](https://docs.rs/rlibc/) crate and - explicitly link it with `extern crate rlibc;` line to avoid linking errors. +## Building and running - Build using a `nightly` version of the compiler and activate the [`build-std`](https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#build-std) - Cargo feature: `cargo build -Z build-std --target x86_64-unknown-uefi`. + Cargo feature: `cargo +nightly build -Z build-std --target x86_64-unknown-uefi`. - The `target` directory will contain a `x86_64-unknown-uefi` subdirectory, where you will find the `uefi_app.efi` file - a normal UEFI executable. @@ -40,6 +35,5 @@ The following steps allow you to build a simple UEFI app. - To run this in QEMU: - You will need a recent version of QEMU as well as OVMF to provide UEFI support - - Check the `build.py` script for an idea of what arguments to pass to QEMU - -You can use the `uefi-test-runner` directory as sample code for building a simple UEFI app. + - Check the [`build.py`](uefi-test-runner/build.py) script for an idea of + what arguments to pass to QEMU diff --git a/Cargo.toml b/Cargo.toml index b2cac8f73..2a08e4860 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,6 +38,7 @@ uefi-macros = "0.3.2" [workspace] members = [ + "template", "uefi-macros", "uefi-services", "uefi-test-runner", diff --git a/template/.cargo/config b/template/.cargo/config new file mode 100644 index 000000000..4be91559e --- /dev/null +++ b/template/.cargo/config @@ -0,0 +1,2 @@ +[unstable] +build-std = ["core", "compiler_builtins", "alloc"] diff --git a/template/Cargo.toml b/template/Cargo.toml new file mode 100644 index 000000000..774a18497 --- /dev/null +++ b/template/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "uefi_app" +version = "0.1.0" +edition = "2018" + +[dependencies] +rlibc = "1.0.0" + +# In a real application, change these to point to the latest release +# on crates.io. +uefi = { path = "..", features = ["exts"] } +uefi-services = { path = "../uefi-services" } diff --git a/template/src/main.rs b/template/src/main.rs new file mode 100644 index 000000000..721fc0342 --- /dev/null +++ b/template/src/main.rs @@ -0,0 +1,15 @@ +#![no_main] +#![no_std] +#![feature(abi_efiapi)] + +extern crate rlibc; + +use uefi::prelude::*; +use uefi::ResultExt; + +#[entry] +fn main(_handle: Handle, mut system_table: SystemTable) -> Status { + uefi_services::init(&mut system_table).unwrap_success(); + + Status::SUCCESS +}