UEFI for ARM/ARM64 on QEMU

One really useful thing that happened at Linaro Connect last week was that Ard Biesheuvel managed to complete the port of UEFI to arm and aarch64 QEMU. This has been a component missing for us to enable what is really the standard development environment for most Linux devs. Ard has documented this on the Linaro wiki, but I wanted to (a) put this into an rss feed and (b) have a static set of instructions. Also, I've added the platforms to the uefi-tools platform configuration to make building a bit less tedious.

QEMU

Earlier this year, without the noisy announcement it deserved, we finally got AArch64 system support in QEMU. User mode emulation had been available for quite some time at that point, and had been really useful for the Linux distributions' bootstrapping efforts, but did not help the kernel and firmware developers.

Anyway, the UEFI port depends on some changes that only went in last week, so for now we still need to build a fresh upstream:

$ git clone git://git.qemu.org/qemu.git
$ cd qemu
$ ./configure --prefix=/usr/local --target-list=arm-softmmu,aarch64-softmmu
$ make -j9
$ sudo make install

UEFI

The required patches to EDK2 are already upstream, so the only requirement is that you have a working cross compiler. I am using a Linaro 4.8 gcc prebuilt one.

$ git clone git://git.linaro.org/uefi/uefi-tools.git
$ git clone https://github.com/tianocore/edk2.git
$ cd edk2
$ ../uefi-tools/uefi-build.sh -b DEBUG -b RELEASE qemu64

The generated firmware image will be found as Build/ArmVirtualizationQemu-AARCH64/{DEBUG,RELEASE}_GCC48/FV/QEMU_EFI.fd

To build the 32-bit variant:

$ ../uefi-tools/uefi-build.sh -b DEBUG -b RELEASE qemu

The generated firmware image will be found as Build/ArmVirtualizationQemu-ARM/{DEBUG,RELEASE}_GCC48/FV/QEMU_EFI.fd

Prebuilt binaries

So, due to yours truly messing up, this support was not included in Linaro's 2014.09 release (the source code contains the support, but the pre-built images are missing). However. I kicked off a build just after and produced a debug and a release version.

Setting up and running a system

You will want to generate data files to hold the emulated flash images for the UEFI firmware and UEFI's persistent environment variables:

$ dd if=/dev/zero bs=1M count=64 of=flash0.img
$ dd if=/dev/zero bs=1M count=64 of=flash1.img
$ dd if=Build/ArmVirtualizationQemu-AARCH64/DEBUG_GCC48/FV/QEMU_EFI.fd \
    bs=1M of=flash0.img conv=notrunc

And then launch the 64-bit model using:

$ qemu-system-aarch64 \
    -m 1024 \
    -cpu cortex-a57 \
    -M virt \
    -pflash flash0.img \
    -pflash flash1.img \
    -serial stdio

Or for the aarch32 variant:

$ qemu-system-arm \
    -m 1024 \
    -cpu cortex-a15 \
    -M virt \
    -pflash flash0.img \
    -pflash flash1.img \
    -serial stdio