7个版本
0.3.1 | 2023年10月18日 |
---|---|
0.3.0 | 2023年10月6日 |
0.2.1 | 2019年11月13日 |
0.1.3 | 2018年12月3日 |
0.1.0 | 2018年3月14日 |
124在操作系统类别中
每月下载量 26次
500KB
9K SLoC
efi
Rust编写UEFI应用程序的框架。在UEFI平台上类似Rust标准库,支持诸如
- 控制台I/O
- 通过自定义分配器支持容器,如
Vec
和String
- 宏如
println!
、write!
、format!
等 - Rust I/O 原语作为
Read
和Write
特性和相关类型 - 类似于stdlib的UDP和TCP套接字
IpAddr
和其支持类型的实现- 域名解析,以便您可以使用主机名连接套接字
还提供用于UEFI特定功能的便捷API,例如
- 加载和启动映像
- DHCP
- PXE
- 设备路径
它使用 efi_ffi
包与UEFI平台进行接口交互。
限制
- 仍在开发中。API表面可能会随时更改。
- 目前仅支持
x64
架构。 - 仅测试与Rust nightly版本
nightly-2023-01-12
编译。可能无法与其他版本编译。您必须使用rust-toolchain
文件强制使用此版本(如下文所示)
编写UEFI应用程序
要使用此框架编写UEFI应用程序,请按照以下步骤操作
- 通过运行
cargo new my_efi_app
创建应用程序的新crate,其中my_efi_app
是应用程序的名称 - 在
Cargo.toml
中的[dependencies]
下添加efi = "0.3"
- 在crate的根目录下添加一个名为
rust-toolchain
的文件,其中包含文本nightly-2023-01-12
。这将确保crate总是使用nightly-2023-01-12版本构建。 - 在
my_efi_app/src/main.rs
中添加以下代码。代码中的注释解释了每个部分
#![no_std] // Indicates to the Rust compiler that the app does not depend on the standard library but is a 'standalone' application.
#![no_main] // Indicates that this application does not have a "main" function typically found in a Linux or Windows application (although it does have its own "main" function "efi_main" as declared below)
// Externs for efi and alloc crates (alloc crate is the one that contains definitions of String and Vec etc.)
#[macro_use] extern crate efi;
extern crate alloc;
// EFI entrypoint or main function. UEFI firmware will call this function to start the application.
// The signature and the name of this function must be exactly as below.
#[no_mangle]
pub extern "win64" fn efi_main(image_handle: efi::ffi::EFI_HANDLE, sys_table : *const efi::ffi::EFI_SYSTEM_TABLE) -> isize {
efi::init_env(image_handle, sys_table); // Call to init_env must be the first thing in efi_main. Without it things like println!() won't work
println!("Welcome to UEFI");
// Your business logic here
0
}
// A handler to respond to panics in the code. Required by the Rust compiler
#[panic_handler]
fn panic(_: &core::panic::PanicInfo) -> ! {
loop {}
}
构建
构建应用程序需要安装目标 x86_64-unknown-uefi
到您的机器上。要安装它
- 在crate的根目录下打开命令行(例如,本例中为
my_efi_app
文件夹) - 运行命令
rustup target add x86_64-unknown-uefi
必须在crate的根目录下执行此操作,因为这样目标将为我们上面指定的带有 root-toolchain
文件的Rust工具链安装。
目标安装完成后,使用以下命令构建应用程序 cargo build --target x86_64-unknown-uefi
。构建完成后,生成的EFI应用程序 my_efi_app.efi
将位于 target\x86_64-unknown-uefi\debug\
运行
按照以下步骤在qemu虚拟机中运行UEFI应用程序
- 下载并安装qemu
- 搜索
ovmf.fd
并下载该二进制文件(这是我们将运行应用程序的OVMF固件) - 通过以下命令行启动qemu:
<path where qemu is installed>/qemu-system-x86_64 -pflash <path where you downloaded ovmf.fd>/ovmf.fd -hda fat:rw:<path to your uefi application crate>/target/x86_64-unknown-uefi/debug
- Qemu将启动至
ovmf.fd
固件并启动EFI外壳 - 等待EFI外壳命令提示符出现。当它出现时,输入应用程序的名称
my_efi_app.efi
并按ENTER
- 应用程序将运行,并在qemu屏幕上打印 "Welcome to UEFI"
示例应用程序
有关示例应用程序,请参阅 examples/sample_efi_app.rs
。通过运行 cargo build --target x86_64-unknown-uefi --example sample_efi_app
来构建它。生成的二进制文件 sample_efi_app.efi
将位于 target/x86_64-unknown-uefi/debug/examples
应用程序在启动时执行DHCP以获取IP地址,然后向指定的服务器发送HTTP请求。因此,要运行它,您需要按照以下步骤操作
- 确保您的网络中运行着一个DHCP服务器,并且能够分配IP地址。
- 在您将要运行应用程序的机器上,安装一个您选择的TAP适配器,并记下其名称。
- 将TAP适配器连接到上面提到的DHCP服务器所在的同一局域网。如果它们不在同一个局域网中,应用程序将无法接收IP地址。
- 使用以下命令行运行qemu:
<qemu安装路径>/qemu-system-x86_64 -pflash <您下载ovmf的位置.fd>/ovmf.fd -hda fat:rw:<您的uefi应用程序crate的路径>/target/x86_64-unknown-uefi/debug/examples -net tap,ifname=<您的TAP适配器名称> -net nic
。末尾的两个-net
选项告诉qemu使用您之前安装的TAP适配器。请确保您在ifname=
之后指定的名称与您之前记录的TAP适配器名称一致。
应用程序将启动,执行DHCP,获取IP地址,提示您输入HTTP服务器的名称,然后对该服务器发起GET请求。
依赖项
~2MB
~43K SLoC