From cd02b2f7cfc7176889757af8298eeb7be951f519 Mon Sep 17 00:00:00 2001 From: "Joe Richey joerichey@google.com" Date: Tue, 5 Feb 2019 21:50:01 -0800 Subject: [PATCH] Use x86_64-unknown-uefi target Rust now supports uefi as a build target: https://github.com/rust-lang/rust/pull/56769 This change mainly eliminates references to the custom JSON target file. It also requires that the entry point's name be changed to `efi_main`. Note that the "C" abi is now correct for EFI applications, but will still be incorrect when uefi-rs is brought in as an external dependancy for a different target. This means the entry point should always be `extern "C"` while the table of function pointers should be `extern "win64"`. --- BUILDING.md | 13 +++++-------- README.md | 10 ++++++---- uefi-test-runner/build.py | 2 +- uefi-test-runner/src/main.rs | 2 +- uefi-test-runner/x86_64-uefi.json | 26 -------------------------- 5 files changed, 13 insertions(+), 40 deletions(-) delete mode 100644 uefi-test-runner/x86_64-uefi.json diff --git a/BUILDING.md b/BUILDING.md index 445a9ddde..6753afc88 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -2,8 +2,8 @@ UEFI applications are simple COFF (Windows) executables, with the special `EFI_Application` subsystem, and some limitations (such as no dynamic linking). - -The `x86_64-uefi.json` file describes a custom target for building UEFI apps. +[Rust supports building UEFI applications](https://github.com/rust-lang/rust/pull/56769) +though the `x86_64-unknown-uefi` target. ## Prerequisites @@ -19,15 +19,12 @@ The following steps allow you to build a simple UEFI app. ```rust #[no_mangle] -pub extern "win64" fn uefi_start(handle: Handle, system_table: SystemTable) -> Status; +pub extern "C" fn efi_main(handle: Handle, system_table: SystemTable) -> Status; ``` -- Copy the `uefi-test-runner/x86_64-uefi.json` target file to your project's root. - You can customize it. - -- Build using `cargo xbuild --target x86_64-uefi`. +- Build using `cargo xbuild --target x86_64-unknown-uefi`. -- The `target` directory will contain a `x86_64-uefi` subdirectory, +- The `target` directory will contain a `x86_64-unknown-uefi` subdirectory, where you will find the `uefi_app.efi` file - a normal UEFI executable. - To run this on a real computer: diff --git a/README.md b/README.md index 013afee61..a400e6bc0 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,9 @@ OS loaders, hypervisors and other low-level applications. While it started out as x86-specific, it has been adopted on other platforms, such as ARM. -This crates makes it easy to write UEFI applications in Rust. +This crate makes it easy to both: + - Write UEFI applications in Rust (via the [`x86_64-unknown-uefi`][rustc-uefi] target) + - Call UEFI functions from an OS (usually built with a [custom target][rustc-custom]) The objective is to provide **safe** and **performant** wrappers for UEFI interfaces, and allow developers to write idiomatic Rust code. @@ -20,6 +22,8 @@ and has been tested _only_ with **64-bit** UEFI. [UEFI]: https://en.wikipedia.org/wiki/Unified_Extensible_Firmware_Interface [gm-blog]: https://medium.com/@gil0mendes/an-efi-app-a-bit-rusty-82c36b745f49 +[rustc-uefi]: https://github.com/rust-lang/rust/pull/56769 +[rustc-custom]: https://doc.rust-lang.org/rustc/targets/custom.html ![uefi-rs running in QEMU](https://imgur.com/SFPSVuO.png) @@ -49,7 +53,7 @@ This project contains multiple sub-crates: ## Building kernels which use UEFI -This crate makes it easy to start buildimg simple applications with UEFI. +This crate makes it easy to start building simple applications with UEFI. However, there are some limitations you should be aware of: - The global logger / allocator **can only be set once** per binary. @@ -92,8 +96,6 @@ An example UEFI app is built in the `uefi-test-runner` directory. Check out the testing [README.md](uefi-test-runner/README.md) for instructions on how to run the crate's tests. -This repo also contains a `x86_64-uefi.json` file, which is a custom Rust target for 64-bit UEFI applications. - ## Building UEFI programs For instructions on how to create your own UEFI apps, see the [BUILDING.md](BUILDING.md) file. diff --git a/uefi-test-runner/build.py b/uefi-test-runner/build.py index 613d3a668..421113ce6 100755 --- a/uefi-test-runner/build.py +++ b/uefi-test-runner/build.py @@ -23,7 +23,7 @@ # Run QEMU without showing GUI 'headless': False, # Target to build for. - 'target': 'x86_64-uefi', + 'target': 'x86_64-unknown-uefi', # Configuration to build. 'config': 'debug', # QEMU executable to use diff --git a/uefi-test-runner/src/main.rs b/uefi-test-runner/src/main.rs index 46a7237b4..c12150399 100644 --- a/uefi-test-runner/src/main.rs +++ b/uefi-test-runner/src/main.rs @@ -20,7 +20,7 @@ mod boot; mod proto; #[no_mangle] -pub extern "win64" fn uefi_start(image: uefi::Handle, st: SystemTable) -> Status { +pub extern "C" fn efi_main(image: uefi::Handle, st: SystemTable) -> Status { // Initialize utilities (logging, memory allocation...) uefi_services::init(&st).expect_success("Failed to initialize utilities"); diff --git a/uefi-test-runner/x86_64-uefi.json b/uefi-test-runner/x86_64-uefi.json deleted file mode 100644 index 8f88fc250..000000000 --- a/uefi-test-runner/x86_64-uefi.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "llvm-target": "x86_64-pc-windows-gnu", - "env": "gnu", - "target-family": "windows", - "target-endian": "little", - "target-pointer-width": "64", - "target-c-int-width": "32", - "os": "uefi", - "arch": "x86_64", - "data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128", - "linker": "rust-lld", - "linker-flavor": "lld-link", - "pre-link-args": { - "lld-link": [ - "/Subsystem:EFI_Application", - "/Entry:uefi_start" - ] - }, - "panic-strategy": "abort", - "default-hidden-visibility": true, - "executables": true, - "position-independent-executables": true, - "exe-suffix": ".efi", - "is-like-windows": true, - "emit-debug-gdb-scripts": false -}