Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/maulingmonkey/uefi-hello-world
Rust + UEFI experimentation
https://github.com/maulingmonkey/uefi-hello-world
boot rust uefi
Last synced: 17 days ago
JSON representation
Rust + UEFI experimentation
- Host: GitHub
- URL: https://github.com/maulingmonkey/uefi-hello-world
- Owner: MaulingMonkey
- License: other
- Created: 2021-07-12T10:01:35.000Z (over 3 years ago)
- Default Branch: master
- Last Pushed: 2021-07-30T19:28:01.000Z (over 3 years ago)
- Last Synced: 2024-11-22T08:47:03.576Z (3 months ago)
- Topics: boot, rust, uefi
- Language: Rust
- Homepage:
- Size: 38.1 KB
- Stars: 2
- Watchers: 3
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: Readme.md
- License: LICENSE-APACHE
Awesome Lists containing this project
README
# UEFI Hello World
Experimenting with Rust + UEFI
# Tested Versions
```
C:\>code --version
1.58.0
2d23c42a936db1c7b3b06f918cde29561cc47cd6
x64C:\>rustc +nightly --version
rustc 1.55.0-nightly (8b87e8539 2021-07-08)C:\>"C:\Program Files\qemu\qemu-system-x86_64" --version
QEMU emulator version 6.0.50 (v6.0.0-14198-gedb3abe0d1-dirty)
Copyright (c) 2003-2021 Fabrice Bellard and the QEMU Project developers
```See also pinned versions in:
* `rust-toolchain.toml`
* `Cargo.lock`# Downloads
* VS Code: https://code.visualstudio.com/
* Rustup: https://rustup.rs/
* QEMU: https://www.qemu.org/download/#windows (or specifically: https://qemu.weilnetz.de/w64/2021/qemu-w64-setup-20210706.exe )# Overview
## x86_64-pc-uefi-msvc.json
Rust generally has two targets to worry about at a time: the host environment (build scripts etc.) and the target environment (what you're trying to build.)
While much of this could be driven by simply by using `RUSTFLAGS` and the like, using a [custom target](https://doc.rust-lang.org/rustc/targets/custom.html)
lets us specify UEFI specific options separately, where they won't break our host environment.Initial basis for this file was:
```
rustc +nightly -Z unstable-options --print target-spec-json --target=x86_64-pc-windows-msvc
```Changed:
* The EXE suffix to match what the BIOS / system firmware looks for
* Specified an abort panic strategy instead of trying to handle all edge cases
* The OS (`cfg!(target_os)`? seems to avoid linking `_fltused`, which is some kind of marker symbol: )Left alone:
* `llvm-target` (not sure what the impact, if any, would be.)```diff
"env": "msvc",
- "exe-suffix": ".exe",
+ "exe-suffix": ".efi",
"executables": true,
"has-elf-tls": true,
"is-builtin": true,
"is-like-msvc": true,
"is-like-windows": true,
"linker-flavor": "msvc",
"linker-is-gnu": false,
"lld-flavor": "link",
"llvm-target": "x86_64-pc-windows-msvc",
+ "panic-strategy": "abort",
"max-atomic-width": 64,
"no-default-libraries": false,
- "os": "windows",
+ "os": "uefi",
"pre-link-args": {
```Added extra link args:
* `/ENTRY:efi_main` - we could've picked something else, but as UEFI's entry point takes UEFI-specific arguments, I'm not comfortable using the default names.
* `/Subsystem:EFI_Application` - MSVC has built in support for generating EFI style portable execuables.
[`/Subsystem`](https://docs.microsoft.com/en-us/cpp/build/reference/subsystem-specify-subsystem?view=msvc-160) also supports `BOOT_APPLICATION`, compatible with windows's boot loader?
* `/NXCOMPAT:NO` - Overriding rust's defaults, this disables [Data Execution Prevention (DEP)](https://docs.microsoft.com/en-us/windows/win32/Memory/data-execution-prevention), since UEFI doesn't support that (will link error if enabled.)```diff
+ "post-link-args": {
+ "lld-link": [
+ "/ENTRY:efi_main",
+ "/Subsystem:EFI_Application",
+ "/NXCOMPAT:NO"
+ ],
+ "msvc": [
+ "/ENTRY:efi_main",
+ "/Subsystem:EFI_Application",
+ "/NXCOMPAT:NO"
+ ]
+ },
```## xtask/...
[cargo xtask](https://github.com/matklad/cargo-xtask) style build logic.
Well, it would be, if I bothered to parse any command line arguments!
Since I only support `xtask b`, I just assume that's all you used.Main build logic. Creates a UEFI binary with:
```
cargo +nightly build -Z build-std=core --target=x86_64-pc-uefi-msvc.json --bin uefi-hello-world
```
Then wraps that in a FAT32 filesystem, and then wraps *that* in a disk image that uses GPT partitions to indicate it's a EFI System Partition.
`diskpart` or similar would be more straightforward, but host-OS-specific, so I've manually done things the hard way.## uefi-hello-world/...
Using [the `uefi` crate](https://lib.rs/crates/uefi) would be a lot more straightforward.
Instead, I've created hello world almost entirely from scratch.
I do use [the `wchar` crate](https://lib.rs/crates/wchar) because I'm too lazy to type `&['H' as wchar_t, 'e' as wchar_t, ...]`.## .cargo/config.toml
[cargo xtask](https://github.com/matklad/cargo-xtask) companion file
## .vscode/...
Setup build (`Ctrl`+`Shift`+`B`) & QEMU launch (`F5`) logic.
Actual sane debug environment not setup (PRs welcome!)## target/...
* `x86_64-pc-uefi-msvc/debug/uefi-hello-world.efi` - the generated UEFI binary
* `debug/uefi-hello-world.img` - the generated disk imageLicense
Licensed under either of
* Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
* MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)at your option.
Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
dual licensed as above, without any additional terms or conditions.