はじめに
前回の記事はこちら。
こちらの記事では、RISC-V上でLinuxを起動することを目標としていましたが、UEFIファームウェアはU-Bootを使用しました。他の選択肢として、UEFIのリファレンス実装であるEDK II というものがあります。EDK II はEFIアプリケーションやファームウェア開発のための開発環境です。前回の記事でも紹介したRed Hatの資料にもEDK IIを使用したブートフローが記載されています。そこで今回は、U-Bootの代わりにEDK IIを使用してLinuxをブートさせてみたいと思います。
前提として、前回の記事で紹介した方法でLinuxが起動できるとします。
EDK IIファームウェアのビルド
EDK IIはビルド方法が独自であり少々分かりづらいです。これはEDK IIが単なるファームウェアではなくUEFIアプリケーションも含む開発環境だからであると考えられます。とはいえ、 https://github.com/tianocore/edk2/tree/master/OvmfPkg/RiscVVirt に従ってコマンドを打てばビルドできます。
まずはEDK IIのリポジトリをクローンしてきます。
git clone --recurse-submodule https://github.com/tianocore/edk2.git
続いて、以下コマンドによりファームウェアをビルドします。
export WORKSPACE=`pwd`
export GCC_RISCV64_PREFIX=riscv64-unknown-linux-gnu-
export PACKAGES_PATH=$WORKSPACE/edk2
export EDK_TOOLS_PATH=$WORKSPACE/edk2/BaseTools
source edk2/edksetup.sh --reconfig
make -C edk2/BaseTools
source edk2/edksetup.sh BaseTools
build -a RISCV64 --buildtarget RELEASE -p OvmfPkg/RiscVVirt/RiscVVirtQemu.dsc -t GCC
EDK IIを使用しQEMUを起動
ビルド生成物はBuild/RiscVVirtQemu/RELEASE_GCCに入っています。使いやすいようにカレントディレクトリにコピーしてきます。
cp -v Build/RiscVVirtQemu/RELEASE_GCC/FV/RISCV_VIRT_* .
RISCV_VIRT_CODE.fdは書き換え不可能なコード領域、RISCV_VIRT_VARS.fdは書き換え可能な変数の領域です。
ビルド生成物は32MBにしないといけないらしいので、サイズを32MBにします。
truncate -s 32M RISCV_VIRT_CODE.fd
truncate -s 32M RISCV_VIRT_VARS.fd
以下コマンドによりQEMUを起動します。pflashというものに先程のビルド生成物を指定して起動するようです。詳しいことはわかりませんが、おそらくUEFIで使用される不揮発性メモリのエミュレートでしょうか。
qemu-system-riscv64 \
-machine virt,pflash0=pflash0,pflash1=pflash1,acpi=off -nographic \
-bios opensbi-1.7/build/platform/generic/firmware/fw_dynamic.bin \
-drive file=linux-rv64.img,format=raw,if=virtio \
-blockdev node-name=pflash0,driver=file,read-only=on,filename=RISCV_VIRT_CODE.fd \
-blockdev node-name=pflash1,driver=file,filename=RISCV_VIRT_VARS.fd \
-m 1G
成功すれば、UEFIのシェルが起動します。以下コマンドによりGRUBのEFIアプリケーションを起動します。
Shell> FS0:EFI\GRUB\grubriscv64.efi
私の環境ではなぜかGRUBの表示が崩れましたが、ともかくLinuxを起動することができました。ここで、EFIパーティションのルートにstartup.nshを置いておけば自動で起動するようになるらしいので、やってみます。QEMU上のLinuxで以下コマンドを実行します。
echo "FS0:EFI\GRUB\grubriscv64.efi" > /boot/efi/startup.nsh
これで次回以降起動時は自動でLinuxが起動するようになります。めでたし。