[QEMU][Linux] boot upstream Linux from TFA/EDK2 on QEMU

boot upstream Linux from U-boot on QEMU では QEMU で U-Boot を立ち上げ、そこから Linux kernel を立ち上げました。ここでは、Trusted Firmware-A (TF-A) と EDK II (便宜上EDK2) を起動し、そこから Linux kernel を立ち上げてみます。

TF-A と EDK II と Linux kernel の位置付け

TF-A はブートして最初に動作する Firmware で、一部は Secure World (デジタル署名されたプログラムのみ動作する領域)で動作します。

このようなプログラムは普通にボード上でプログラムを開発したり使用したりする分にはあまり効果を見る機会はないですが、商品やシステムの中で著作権や決済など安全性を担保する仕組みを支えています。

いくつかの BL (bootloader) からなり、BL1⇒BL2⇒BL31 と実行され、最後に Normal World(一般プログラム動作領域) で起動する BL33 が次に起動するプログラムとなります。(BL32 には Secure World プログラムが入ります)

かなり説明が怪しいので詳細は以下の SlideShare を参照ください。

 

EDK2 は先の記事の通り OS bootloader であり Hardware 初期化を担う Firmware で`すが、Shell と様々な Module を備えていて、それ自身で実行環境を実現しています。TF-A から見ると EDK2 は BL33 のプログラムになります。

Linux kernel は EDK2 から起動パラメータなどを受け取って起動します。

ビルド

まず EDK2 をビルドします。前回と異なるのはターゲットを "ArmVirtQemuKernel.dsc" にしています。これは EDK2 自体を TF-A の BL33 プログラムとして扱えるようにするためです。

git clone https://github.com/tianocore/edk2
git checkout -b stable
git reset --hard edk2-stable202002
cd edk2
make -C BaseTools
. edksetup.sh
export GCC5_AARCH64_PREFIX=aarch64-linux-gnu-
build -a AARCH64 -t GCC5 -p ArmVirtPkg/ArmVirtQemuKernel.dsc
cd -

EDK2 のビルドで Build/ArmVirtQemuKernel-AARCH64/DEBUG_GCC5/FV/QEMU_EFI.fd が生成されます。

次に TF-A をビルドします。BL33 として EDK2 の生成物 QEMU_EFI.fd を指定します。encrypt 機能などは省略しています。

git clone https://github.com/ARM-software/arm-trusted-firmware
cd arm-trusted-firmware
make PLAT=qemu realclean
make PLAT=qemu CROSS_COMPILE=aarch64-linux-gnu- \
    BL33=../edk2/Build/ArmVirtQemuKernel-AARCH64/DEBUG_GCC5/FV/QEMU_EFI.fd \
    all fip
cd -

TF-A のビルドで、build/qemu/release/{bl1.bin, fip.bin} が生成されます。fip.bin は "Firmware Image Package" の形式で、bl2.bin, bl31.bin 及び BL33 である QEMU_EFI.bin を含んでいます。

生成された bl1.bin と fip.bin を flash image (flash.bin) に変換します。こちらは TF-A の qemu.rst を参考にしています。

dd if=arm-trusted-firmware/build/qemu/release/bl1.bin \
   of=flash.bin bs=4096 conv=notrunc
dd if=arm-trusted-firmware/build/qemu/release/fip.bin \
   of=flash.bin bs=4096 conv=notrunc seek=64

Linux kernel をビルドします。virt モデルでは devicetree は指定しなくてもよいので、ここではビルドには含んでいません。

git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
cd linux
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- defconfig
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- Image

QEMU にて実行します。rootfs イメージは rootfs.cpio.gz として別途用意しています。TF-A を動かすため、"secure=on" の指定が必要です。

qemu-system-aarch64 -M virt,secure=on \
    -cpu cortex-a53 -m 1024 \
    -nographic \
    -bios flash.bin \
    -kernel Image \
    -initrd rootfs.cpio.gz

 参考


コメント

タイトルとURLをコピーしました