Rust:edk2 runtime service driver
最近在尝试将一个rust系统软件迁移为edk2 runtime service为os提供运行时服务,但大多数uefi资料都是基于c语言的,将rust项目修改为c也不现实,固有此文章。
rust语言也提供了uefi库:uefi-rs
第一篇资料可以查到库中的所有结构体和函数等,第二篇是构建rust uefi application的教程。
UEFI APPLICATION
首先 cargo new project 建立起项目框架,如下所示
project
├── build.rs
├── Cargo.lock
├── Cargo.toml
├── rust-toolchain.toml
└── src
└── main.rs
cargo add添加依赖到Cargo.toml
cargo add log
cargo add uefi --features logger,panic_handler
由于uefi阶段无法使用标准库,并且没有常规的主函数,因此main的写法如下所示
#![no_main]
#![no_std]
use log::info;
use uefi::prelude::*;
#[entry]
fn main() -> Status {
// your initialized code
uefi::helpers::init().unwrap();
info!("Hello world!");
boot::stall(10_000_000);
Status::SUCCESS
}
新版本的 uefi-rs API 与旧版本不同,老版的写法为
fn main(image_handle: Handle, mut system_table: SystemTable<Boot>) -> Status { }
新版中,原先作为参数传递的 image_handle 和 system_table 现在以uefi::boot::image_handler() 和uefi::table::system_table_raw()或uefi_raw::table::system 的形式获取。
Build
向rust-toolchain.toml添加:
[toolchain]
targets = ["aarch64-unknown-uefi", "i686-unknown-uefi", "x86_64-unknown-uefi"]
根据架构类型运行编译命令
cargo build --target aarch64-unknown-uefi
产生的文件位于target/aarch64-unknown-uefi/debug/project.efi
Run in VM(Ubuntu)
安装依赖
sudo apt-get install qemu ovmf
拷贝ovmf文件到项目中
cp /usr/share/OVMF/OVMF_CODE.fd .
cp /usr/share/OVMF/OVMF_VARS.fd .
创建一个包含可执行文件的目录结构以模仿 UEFI 系统分区
mkdir -p esp/efi/boot
cp target/aarch64-unknown-uefi/debug/project.efi esp/efi/boot/bootaa64.efi
最后的项目结构如图所示

运行命令通过qemu启动
qemu-system-x86_64 -enable-kvm \
-drive if=pflash,format=raw,readonly=on,file=OVMF_CODE.fd \
-drive if=pflash,format=raw,readonly=on,file=OVMF_VARS.fd \
-drive format=raw,file=fat:rw:esp
runtime service driver
uefi image分为以下三种
- Application
- Boot service driver
- Runtime driver
编译默认为Application,可以通过build.rs指明,如现在需要将项目编译为runtime driver image:
// In build.rs
fn main() {
let target = std::env::var("TARGET").unwrap();
if target.ends_with("-unknown-uefi") {
println!("cargo::rustc-link-arg=/subsystem:efi_runtime_driver");
}
}
因项目需求改变,本文章不再更新
更多推荐



所有评论(0)