UEFIといえばパソコンのBIOSに変わるファームウェアが真っ先に思い浮かびますが、最近ではHiKey boardなどARM64(AARCH64)の乗ったボードのファームウェアにもUEFIが使われ始めています。
UEFIを採用したボード上で動作するUEFIアプリケーションや、UEFIから起動するOSなどを作るために、開発中は何度も再起動やプログラムの転送等を行う必要があるでしょう。 しかし、この作業を実機の上で行うと手間がかかりますし、接続できるデバッガを持っていない場合はデバッグも不便です。
そこで今回は、QEMUを用いてARM64のUEFIアプリケーション開発等をエミュレータ上で行えるようにする方法について調べ、ここに記します。
実行環境
マシン | ThinkPad x201 |
CPU | Intel® Core™ i5 CPU M560 @ 2.67GHz |
RAM | 8GB |
OS | Arch Linux x86_64 |
手順
ARM64向けUEFI(以降、ARM64 UEFI)をQEMUで動かす方法は、ビルド済みイメージを用いる方法と、ソースからビルドを行う方法の2種類があります。
ビルド済みイメージを用いる方法は、以下のようなことを望む方におすすめです。
ソースからビルドを行う方法は、以下のようなことを望む方におすすめです。
- ソースからビルドする方法を知りたい方
ソースからビルドすればUEFIのファームウェア自体をデバッグすることも可能かもしれませんが、やったことがないのでわかりません。
手順(共通ルート)
ARM64向けのQEMUをインストールする
sudo pacman -S qemu-arch-extra
手順(ビルド済みイメージを使う方法)
UEFI(ARM64)のQEMU向け仮想マシンイメージを持ってくる
通常、QEMUで動作するUEFIイメージは、EDK2などを用いて自分でビルドを行う必要がありますが、ビルド済みイメージも配布されています。
x86用のビルド済みイメージであればPacmanからすぐにインストールできますが、ARM64向けのイメージはパッケージが用意されていません。 なので、ビルド済みイメージを以下のようにしてダウンロードします。
wget http://snapshots.linaro.org/components/kernel/leg-virt-tianocore-edk2-upstream/latest/QEMU-AARCH64/RELEASE_GCC5/QEMU_EFI.fd
手順(ソースからビルドを行う方法)
ビルドに必要な環境をインストールします。
sudo pacman -S aarch64-linux-gnu-binutils \ aarch64-linux-gnu-gcc \ aarch64-linux-gnu-gdb \ aarch64-linux-gnu-glibc \ aarch64-linux-gnu-linux-api-headers \ iasl
edk2をクローンします。
git clone https://github.com/tianocore/edk2
BaseToolsをビルドします。
cd edk2 make -C BaseTools
環境設定をします。
source edksetup.sh export GCC49_AARCH64_PREFIX=aarch64-linux-gnu-
build -a AARCH64 -t GCC49 -p ArmVirtPkg/ArmVirtQemu.dsc
ビルドが完了するとDoneといわれます。
ビルドしたQEMU用のイメージは、Build/ArmVirtQemu-AARCH64/DEBUG_GCC49/FV/QEMU_EFI.fd
にあります。
手順(再び共通ルート)
QEMUでARM64 UEFIを起動する
ダウンロード、またはビルドした QEMU_EFI.fd のあるディレクトリで以下のコマンドを実行することで、QEMU上でARM64 UEFIを起動することができます。
終了する際は、別窓で開くQEMUコンソールにq
と打ち込んでエンターを押すと終了できます。
qemu-system-aarch64 -m 512 -cpu cortex-a57 -M virt -bios QEMU_EFI.fd -serial stdio
グラフィックが必要ない方は以下のコマンドを実行します。
終了する際は、起動したシェルの上で Ctrl + a, x
の順に入力すると終了できます。
qemu-system-aarch64 -m 512 -cpu cortex-a57 -M virt -bios QEMU_EFI.fd -nographic
起動時間は、私のマシン(初代Core i5@M540 2.67GHz)ではUEFIシェルが出てくるまでに1~2分ほどかかりました。
最近の性能の良いマシンだと、もう少し起動が速いかもしれません(性能の良いマシンがほしい……)
以上です。
参考情報
EDK2を用いてARM64向けのUEFIファームウェアをビルドする方法やQEMUで起動する方法などについて書かれています。
UEFIアプリケーションをGDBでデバッグする方法が書かれています。
ここで紹介されている方法は以下の手順でデバッグを行います。
- UEFIアプリにアプリケーションのロードされた場所(ImageBase)を表示させる
- 停止させる
- デバッガを仮想マシンに接続する
- デバッガへImageBaseアドレスを用いてシンボル情報を適切な位置に読み込ませる
- 手順2.で停止させたところからデバッグを開始する
UEFIアプリが読み込まれるアドレスが不明のため、このようなことを行う必要があります。
すごく面倒なので何か自動化したいですが……何か良い方法はないものか……