7.31.QEMU virt Armv8-A

Trusted Firmware-A (TF-A) implements the EL3 firmware layer for QEMU virtArmv8-A. BL1 is used as the BootROM, supplied with the -bios argument.When QEMU starts all CPUs are released simultaneously, BL1 selects aprimary CPU to handle the boot and the secondaries are placed in a pollingloop to be released by normal world via PSCI.

BL2 edits the Flattened Device Tree, FDT, generated by QEMU at run-time toadd a node describing PSCI and also enable methods for the CPUs.

IfARM_LINUX_KERNEL_AS_BL33 is set to 1 then this FDT will be passed to BL33via register x0, as expected by a Linux kernel. This allows a Linux kernel imageto be booted directly as BL33 rather than using a bootloader.

An ARM64 defconfig v5.5 Linux kernel is known to boot, FDT doesn’t need to beprovided as it’s generated by QEMU.

Current limitations:

  • Only cold boot is supported

7.31.1.Getting non-TF images

QEMU_EFI.fd can be downloaded fromhttp://snapshots.linaro.org/components/kernel/leg-virt-tianocore-edk2-upstream/latest/QEMU-KERNEL-AARCH64/RELEASE_GCC5/QEMU_EFI.fd

or, can be built as follows:

gitclonehttps://github.com/tianocore/edk2.gitcdedk2gitsubmoduleupdate--initmake-CBaseToolssourceedksetup.shexportGCC5_AARCH64_PREFIX=aarch64-linux-gnu-build-aAARCH64-tGCC5-pArmVirtPkg/ArmVirtQemuKernel.dsc

Then, you will getBuild/ArmVirtQemuKernel-AARCH64/DEBUG_GCC5/FV/QEMU_EFI.fd

Please note you do not need to use GCC 5 in spite of the environment variableGCC5_AARCH64_PREFIX.

The rootfs can be built by using Buildroot as follows:

gitclonegit://git.buildroot.net/buildroot.gitcdbuildrootmakeqemu_aarch64_virt_defconfigutils/config-eBR2_TARGET_ROOTFS_CPIOutils/config-eBR2_TARGET_ROOTFS_CPIO_GZIPmakeolddefconfigmake

Then, you will getoutput/images/rootfs.cpio.gz.

7.31.2.Booting via semi-hosting option

Boot binaries, except BL1, are primarily loaded via semi-hosting so allbinaries has to reside in the same directory as QEMU is started from. Thisis conveniently achieved with symlinks the local names as:

  • bl2.bin -> BL2

  • bl31.bin -> BL31

  • bl33.bin -> BL33 (QEMU_EFI.fd)

  • Image -> linux/arch/arm64/boot/Image

To build:

makeCROSS_COMPILE=aarch64-none-elf-PLAT=qemu

To start (QEMU v5.0.0):

qemu-system-aarch64-nographic-machinevirt,secure=on-cpucortex-a57\-kernelImage\-append"console=ttyAMA0,38400 keep_bootcon"\-initrdrootfs.cpio.gz-smp2-m1024-biosbl1.bin\-dunimp-semihosting-configenable,target=native

7.31.3.Booting via flash based firmware

An alternate approach to deploy a full system stack on QEMU is to load thefirmware via a secure flash device. This involves concatenatingbl1.bin andfip.bin to create a boot ROM that is flashed onto secure FLASH0 with the-bios option.

For example, to test the following firmware stack:

  • BL32 -bl32.bin ->tee-header_v2.bin

  • BL32 Extra1 -bl32_extra1.bin ->tee-pager_v2.bin

  • BL32 Extra2 -bl32_extra2.bin ->tee-pageable_v2.bin

  • BL33 -bl33.bin ->QEMU_EFI.fd (EDK II)

  • Image -> linux/arch/arm64/boot/Image

  1. Compile TF-A

makeCROSS_COMPILE=aarch64-linux-gnu-PLAT=qemuBL32=bl32.bin\BL32_EXTRA1=bl32_extra1.binBL32_EXTRA2=bl32_extra2.bin\BL33=bl33.binBL32_RAM_LOCATION=tdramSPD=opteedallfip

Or, alternatively, to build with TBBR enabled, as well as, BL31 and BL32 encrypted withtest key:

makeCROSS_COMPILE=aarch64-linux-gnu-PLAT=qemuBL32=bl32.bin\BL32_EXTRA1=bl32_extra1.binBL32_EXTRA2=bl32_extra2.bin\BL33=bl33.binBL32_RAM_LOCATION=tdramSPD=opteedallfip\MBEDTLS_DIR=<path-to-mbedtls-repo>TRUSTED_BOARD_BOOT=1\GENERATE_COT=1DECRYPTION_SUPPORT=aes_gcmFW_ENC_STATUS=0\ENCRYPT_BL31=1ENCRYPT_BL32=1
  1. Concatenatebl1.bin andfip.bin to create the boot ROM

ddif=build/qemu/release/bl1.binof=flash.binbs=4096conv=notruncddif=build/qemu/release/fip.binof=flash.binseek=64bs=4096conv=notrunc
  1. Launch QEMU

qemu-system-aarch64-nographic-machinevirt,secure=on-cpucortex-a57-kernelImage\-append'console=ttyAMA0,38400 keep_bootcon'\-initrdrootfs.cpio.gz-smp2-m1024-biosflash.bin\-dunimp

The-bios option abstracts the loading of raw bare metal binaries into flashor ROM memory. QEMU loads the binary into the region corresponding tothe hardware’s entrypoint, from which the binary is executed upon a platform“reset”. In addition to this, it places the information about the kernelprovided with option-kernel, and the RamDisk provided with-initrd,into the firmware configurationfw_cfg. In this setup, EDK II is responsiblefor extracting and launching these fromfw_cfg.

Note

QEMU may be launched with or without ACPI (-acpi/-no-acpi). Ineither case, ensure that the kernel build options are aligned with theparameters passed to QEMU.

7.31.4.Running QEMU in OpenCI

Linaro’s continuous integration platform OpenCI supports running emulated testson QEMU. The tests are kicked off on Jenkins and deployed through the LinaroAutomation and Validation ArchitectureLAVA.

There are a set of Linux boot tests provided in OpenCI. They rely on prebuiltbinaries for UEFI, the kernel, root file system, as well as, any other TF-Adependencies, and are run as part of the OpenCI TF-Adaily job. To run themmanually, abuilder job may be triggered with the test configurationqemu-boot-tests.

You may see the following warning repeated several times in the boot logs:

pflash_write:Writetobufferemulationisflawed

Please ignore this as it is an unresolvedissue in QEMU, it is an internalQEMU warning that logs flawed use of “write to buffer”.

Note

For more information on how to trigger jobs in OpenCI, please refer toLinaro’s CI documentation, which explains how to trigger amanual job.