本文基于 Debian 发行版,如果使用其他发行版可能需要自行补齐依赖。
为了支持 x86-64、AArch64 和 RISC-V,我们需要这些架构对应的 QEMU 模拟器和在 Rust 中添加差异处理的代码。
首先需要构建 QEMU。
-
安装编译 QEMU 的构建依赖
$ sudo apt install autoconf automake autotools-dev curl wget libmpc-dev libmpfr-dev libgmp-dev \ gawk build-essential bison flex texinfo gperf libtool patchutils bc \ zlib1g-dev libexpat-dev pkg-config libglib2.0-dev libpixman-1-dev libsdl2-dev libslirp-dev \ git tmux python3 python3-pip ninja-build
-
下载最新版本的 QEMU 源码
$ wget https://download.qemu.org/qemu-9.0.0.tar.xz $ tar xvJf qemu-9.0.0.tar.xz $ cd qemu-9.0.0
-
编译
# 建议把 --enable-sdl 图形接口支持和 --enable-slirp 网卡支持打开 $ ./configure --target-list=x86_64-softmmu,x86_64-linux-user, \ riscv64-softmmu,riscv64-linux-user, \ aarch64-softmmu,aarch64-linux-user \ --enable-sdl --enable-slirp $ make -j$(nproc)
-
配置环境变量
# 记得替换 {path} 为你的路径 $ export PATH=$PATH:/{path}/qemu-9.0.0/build
-
安装 Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
-
安装 Rust 工具链
$ rustup default nightly # UEFI 的构建目标 $ rustup target add x86_64-unknown-uefi $ rustup target add aarch64-unknown-uefi # 内核目标架构的构建目标 $ rustup target add x86_64-unknown-none $ rustup target add aarch64-unknown-none $ rustup target add riscv64gc-unknown-none-elf $ cargo install cargo-binutils $ rustup component add llvm-tools-preview
-
使用如下指令构建 x86 版本的内核模块。
$ cargo build --bin canicula-kernel --target x86_64-unknown-none
-
首先编译 x86-64 的 EFI 文件。
$ cargo build --bin canicula-efi --target x86_64-unknown-uefi $ cp target/x86_64-unknown-uefi/debug/canicula-efi.efi esp/efi/boot/bootx64.efi
-
启动 QEMU 虚拟机:
$ sudo apt install ovmf $ qemu-system-x86_64 -enable-kvm \ -drive if=pflash,format=raw,readonly=on,file=/usr/share/OVMF/OVMF_CODE.fd \ -drive if=pflash,format=raw,readonly=on,file=/usr/share/OVMF/OVMF_VARS.fd \ -drive format=raw,file=fat:rw:esp
如果出现 qemu-system-x86_64: failed to initialize kvm: Permission denied
问题可以尝试 sudo chmod 666 /dev/kvm
。
在 RISC-V 架构中,我们使用 RustSBI 直接加载内核文件。
-
将 ELF 格式转换为二进制格式。
$ rust-objcopy \ --binary-architecture=riscv64 target/riscv64gc-unknown-none-elf/release/kernel \ --strip-all -O binary target/riscv64gc-unknown-none-elf/release/kernel.bin
-
下载 适合 QEMU 使用的 rustsbi 二进制文件。
解压获得
rustsbi-qemu.bin
文件,它将作为 QEMU 的 BIOS 文件,使用 QEMU 启动内核。$ qemu-system-riscv64 \ -machine virt \ -nographic \ -bios rustsbi-qemu.bin \ -device loader,file=target/riscv64gc-unknown-none-elf/release/kernel.bin,addr=0x80200000