最近在尝试将一个rust系统软件迁移为edk2 runtime service为os提供运行时服务,但大多数uefi资料都是基于c语言的,将rust项目修改为c也不现实,固有此文章。

rust语言也提供了uefi库:uefi-rs

指导手册有如下的一些资料:uefiuefi-int

第一篇资料可以查到库中的所有结构体和函数等,第二篇是构建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");
    }
}

因项目需求改变,本文章不再更新

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐