Paul Beesley | f3653a6 | 2019-05-22 11:22:44 +0100 | [diff] [blame] | 1 | QEMU virt Armv8-A |
| 2 | ================= |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 3 | |
Dan Handley | 610e7e1 | 2018-03-01 18:44:00 +0000 | [diff] [blame] | 4 | Trusted Firmware-A (TF-A) implements the EL3 firmware layer for QEMU virt |
| 5 | Armv8-A. BL1 is used as the BootROM, supplied with the -bios argument. |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 6 | When QEMU starts all CPUs are released simultaneously, BL1 selects a |
| 7 | primary CPU to handle the boot and the secondaries are placed in a polling |
| 8 | loop to be released by normal world via PSCI. |
| 9 | |
| 10 | BL2 edits the Flattened Device Tree, FDT, generated by QEMU at run-time to |
| 11 | add a node describing PSCI and also enable methods for the CPUs. |
| 12 | |
Andrew Walbran | 9c4d069 | 2020-01-15 14:11:31 +0000 | [diff] [blame] | 13 | If ``ARM_LINUX_KERNEL_AS_BL33`` is set to 1 then this FDT will be passed to BL33 |
| 14 | via register x0, as expected by a Linux kernel. This allows a Linux kernel image |
| 15 | to be booted directly as BL33 rather than using a bootloader. |
| 16 | |
Masahiro Yamada | 894a38d | 2019-12-26 13:26:49 +0900 | [diff] [blame] | 17 | An ARM64 defconfig v5.5 Linux kernel is known to boot, FDT doesn't need to be |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 18 | provided as it's generated by QEMU. |
| 19 | |
| 20 | Current limitations: |
| 21 | |
| 22 | - Only cold boot is supported |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 23 | |
Masahiro Yamada | c88f22a | 2020-07-04 16:12:55 +0900 | [diff] [blame] | 24 | Getting non-TF images |
| 25 | --------------------- |
| 26 | |
| 27 | ``QEMU_EFI.fd`` can be downloaded from |
Masahiro Yamada | 894a38d | 2019-12-26 13:26:49 +0900 | [diff] [blame] | 28 | http://snapshots.linaro.org/components/kernel/leg-virt-tianocore-edk2-upstream/latest/QEMU-KERNEL-AARCH64/RELEASE_GCC5/QEMU_EFI.fd |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 29 | |
Masahiro Yamada | c88f22a | 2020-07-04 16:12:55 +0900 | [diff] [blame] | 30 | or, can be built as follows: |
| 31 | |
| 32 | .. code:: shell |
| 33 | |
| 34 | git clone https://github.com/tianocore/edk2.git |
| 35 | cd edk2 |
| 36 | git submodule update --init |
| 37 | make -C BaseTools |
| 38 | source edksetup.sh |
| 39 | export GCC5_AARCH64_PREFIX=aarch64-linux-gnu- |
| 40 | build -a AARCH64 -t GCC5 -p ArmVirtPkg/ArmVirtQemuKernel.dsc |
| 41 | |
| 42 | ```` |
| 43 | |
| 44 | Then, you will get ``Build/ArmVirtQemuKernel-AARCH64/DEBUG_GCC5/FV/QEMU_EFI.fd`` |
| 45 | |
| 46 | Please note you do not need to use GCC 5 in spite of the environment variable |
Harrison Mutai | ac31bfd | 2023-02-06 17:54:54 +0000 | [diff] [blame] | 47 | ``GCC5_AARCH64_PREFIX``. |
Masahiro Yamada | c88f22a | 2020-07-04 16:12:55 +0900 | [diff] [blame] | 48 | |
| 49 | The rootfs can be built by using Buildroot as follows: |
| 50 | |
| 51 | .. code:: shell |
| 52 | |
| 53 | git clone git://git.buildroot.net/buildroot.git |
| 54 | cd buildroot |
| 55 | make qemu_aarch64_virt_defconfig |
| 56 | utils/config -e BR2_TARGET_ROOTFS_CPIO |
| 57 | utils/config -e BR2_TARGET_ROOTFS_CPIO_GZIP |
| 58 | make olddefconfig |
| 59 | make |
| 60 | |
| 61 | Then, you will get ``output/images/rootfs.cpio.gz``. |
| 62 | |
Sumit Garg | 8aeb879 | 2019-11-15 20:16:58 +0530 | [diff] [blame] | 63 | Booting via semi-hosting option |
| 64 | ------------------------------- |
| 65 | |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 66 | Boot binaries, except BL1, are primarily loaded via semi-hosting so all |
| 67 | binaries has to reside in the same directory as QEMU is started from. This |
| 68 | is conveniently achieved with symlinks the local names as: |
| 69 | |
| 70 | - ``bl2.bin`` -> BL2 |
| 71 | - ``bl31.bin`` -> BL31 |
| 72 | - ``bl33.bin`` -> BL33 (``QEMU_EFI.fd``) |
Masahiro Yamada | 894a38d | 2019-12-26 13:26:49 +0900 | [diff] [blame] | 73 | - ``Image`` -> linux/arch/arm64/boot/Image |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 74 | |
| 75 | To build: |
| 76 | |
Paul Beesley | 493e349 | 2019-03-13 15:11:04 +0000 | [diff] [blame] | 77 | .. code:: shell |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 78 | |
Paul Beesley | f3653a6 | 2019-05-22 11:22:44 +0100 | [diff] [blame] | 79 | make CROSS_COMPILE=aarch64-none-elf- PLAT=qemu |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 80 | |
Masahiro Yamada | 79ecdd2 | 2020-07-04 17:15:44 +0900 | [diff] [blame] | 81 | To start (QEMU v5.0.0): |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 82 | |
Paul Beesley | 493e349 | 2019-03-13 15:11:04 +0000 | [diff] [blame] | 83 | .. code:: shell |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 84 | |
| 85 | qemu-system-aarch64 -nographic -machine virt,secure=on -cpu cortex-a57 \ |
| 86 | -kernel Image \ |
Masahiro Yamada | 1eae724 | 2020-07-04 17:10:25 +0900 | [diff] [blame] | 87 | -append "console=ttyAMA0,38400 keep_bootcon" \ |
Masahiro Yamada | c88f22a | 2020-07-04 16:12:55 +0900 | [diff] [blame] | 88 | -initrd rootfs.cpio.gz -smp 2 -m 1024 -bios bl1.bin \ |
Douglas Raillard | d7c21b7 | 2017-06-28 15:23:03 +0100 | [diff] [blame] | 89 | -d unimp -semihosting-config enable,target=native |
Sumit Garg | 8aeb879 | 2019-11-15 20:16:58 +0530 | [diff] [blame] | 90 | |
Harrison Mutai | ac31bfd | 2023-02-06 17:54:54 +0000 | [diff] [blame] | 91 | Booting via flash based firmware |
| 92 | -------------------------------- |
Sumit Garg | 8aeb879 | 2019-11-15 20:16:58 +0530 | [diff] [blame] | 93 | |
Harrison Mutai | ac31bfd | 2023-02-06 17:54:54 +0000 | [diff] [blame] | 94 | An alternate approach to deploy a full system stack on QEMU is to load the |
| 95 | firmware via a secure flash device. This involves concatenating ``bl1.bin`` and |
| 96 | ``fip.bin`` to create a boot ROM that is flashed onto secure FLASH0 with the |
| 97 | ``-bios`` option. |
Sumit Garg | 8aeb879 | 2019-11-15 20:16:58 +0530 | [diff] [blame] | 98 | |
Harrison Mutai | ac31bfd | 2023-02-06 17:54:54 +0000 | [diff] [blame] | 99 | For example, to test the following firmware stack: |
| 100 | |
| 101 | |
| 102 | - BL32 - ``bl32.bin`` -> ``tee-header_v2.bin`` |
| 103 | - BL32 Extra1 - ``bl32_extra1.bin`` -> ``tee-pager_v2.bin`` |
| 104 | - BL32 Extra2 - ``bl32_extra2.bin`` -> ``tee-pageable_v2.bin`` |
| 105 | - BL33 - ``bl33.bin`` -> ``QEMU_EFI.fd`` (EDK II) |
Sumit Garg | 8aeb879 | 2019-11-15 20:16:58 +0530 | [diff] [blame] | 106 | - ``Image`` -> linux/arch/arm64/boot/Image |
| 107 | |
Sumit Garg | 8aeb879 | 2019-11-15 20:16:58 +0530 | [diff] [blame] | 108 | |
Harrison Mutai | ac31bfd | 2023-02-06 17:54:54 +0000 | [diff] [blame] | 109 | 1. Compile TF-A |
Sumit Garg | 8aeb879 | 2019-11-15 20:16:58 +0530 | [diff] [blame] | 110 | |
Harrison Mutai | ac31bfd | 2023-02-06 17:54:54 +0000 | [diff] [blame] | 111 | .. code:: shell |
Sumit Garg | 8aeb879 | 2019-11-15 20:16:58 +0530 | [diff] [blame] | 112 | |
Harrison Mutai | ac31bfd | 2023-02-06 17:54:54 +0000 | [diff] [blame] | 113 | make CROSS_COMPILE=aarch64-linux-gnu- PLAT=qemu BL32=bl32.bin \ |
| 114 | BL32_EXTRA1=bl32_extra1.bin BL32_EXTRA2=bl32_extra2.bin \ |
| 115 | BL33=bl33.bin BL32_RAM_LOCATION=tdram SPD=opteed all fip |
Sumit Garg | 8aeb879 | 2019-11-15 20:16:58 +0530 | [diff] [blame] | 116 | |
Harrison Mutai | ac31bfd | 2023-02-06 17:54:54 +0000 | [diff] [blame] | 117 | Or, alternatively, to build with TBBR enabled, as well as, BL31 and BL32 encrypted with |
| 118 | test key: |
Sumit Garg | 8aeb879 | 2019-11-15 20:16:58 +0530 | [diff] [blame] | 119 | |
Harrison Mutai | ac31bfd | 2023-02-06 17:54:54 +0000 | [diff] [blame] | 120 | .. code:: shell |
Sumit Garg | 8aeb879 | 2019-11-15 20:16:58 +0530 | [diff] [blame] | 121 | |
Harrison Mutai | ac31bfd | 2023-02-06 17:54:54 +0000 | [diff] [blame] | 122 | make CROSS_COMPILE=aarch64-linux-gnu- PLAT=qemu BL32=bl32.bin \ |
| 123 | BL32_EXTRA1=bl32_extra1.bin BL32_EXTRA2=bl32_extra2.bin \ |
| 124 | BL33=bl33.bin BL32_RAM_LOCATION=tdram SPD=opteed all fip \ |
| 125 | MBEDTLS_DIR=<path-to-mbedtls-repo> TRUSTED_BOARD_BOOT=1 \ |
| 126 | GENERATE_COT=1 DECRYPTION_SUPPORT=aes_gcm FW_ENC_STATUS=0 \ |
| 127 | ENCRYPT_BL31=1 ENCRYPT_BL32=1 |
Sumit Garg | 8aeb879 | 2019-11-15 20:16:58 +0530 | [diff] [blame] | 128 | |
Harrison Mutai | ac31bfd | 2023-02-06 17:54:54 +0000 | [diff] [blame] | 129 | 2. Concatenate ``bl1.bin`` and ``fip.bin`` to create the boot ROM |
Sumit Garg | 8aeb879 | 2019-11-15 20:16:58 +0530 | [diff] [blame] | 130 | |
Harrison Mutai | ac31bfd | 2023-02-06 17:54:54 +0000 | [diff] [blame] | 131 | .. code:: shell |
Sumit Garg | 8aeb879 | 2019-11-15 20:16:58 +0530 | [diff] [blame] | 132 | |
Harrison Mutai | ac31bfd | 2023-02-06 17:54:54 +0000 | [diff] [blame] | 133 | dd if=build/qemu/release/bl1.bin of=flash.bin bs=4096 conv=notrunc |
| 134 | dd if=build/qemu/release/fip.bin of=flash.bin seek=64 bs=4096 conv=notrunc |
Sumit Garg | 8aeb879 | 2019-11-15 20:16:58 +0530 | [diff] [blame] | 135 | |
Harrison Mutai | ac31bfd | 2023-02-06 17:54:54 +0000 | [diff] [blame] | 136 | 3. Launch QEMU |
Sumit Garg | 8aeb879 | 2019-11-15 20:16:58 +0530 | [diff] [blame] | 137 | |
Harrison Mutai | ac31bfd | 2023-02-06 17:54:54 +0000 | [diff] [blame] | 138 | .. code:: shell |
| 139 | |
| 140 | qemu-system-aarch64 -nographic -machine virt,secure=on |
| 141 | -cpu cortex-a57 -kernel Image \ |
| 142 | -append 'console=ttyAMA0,38400 keep_bootcon' \ |
| 143 | -initrd rootfs.cpio.gz -smp 2 -m 1024 -bios flash.bin \ |
| 144 | -d unimp |
| 145 | |
| 146 | The ``-bios`` option abstracts the loading of raw bare metal binaries into flash |
| 147 | or ROM memory. QEMU loads the binary into the region corresponding to |
| 148 | the hardware's entrypoint, from which the binary is executed upon a platform |
| 149 | "reset". In addition to this, it places the information about the kernel |
| 150 | provided with option ``-kernel``, and the RamDisk provided with ``-initrd``, |
| 151 | into the firmware configuration ``fw_cfg``. In this setup, EDK II is responsible |
| 152 | for extracting and launching these from ``fw_cfg``. |
| 153 | |
| 154 | .. note:: |
| 155 | QEMU may be launched with or without ACPI (``-acpi``/``-no-acpi``). In |
| 156 | either case, ensure that the kernel build options are aligned with the |
| 157 | parameters passed to QEMU. |
Harrison Mutai | 6c23150 | 2022-11-15 18:28:18 +0000 | [diff] [blame] | 158 | |
| 159 | Running QEMU in OpenCI |
| 160 | ----------------------- |
| 161 | |
| 162 | Linaro's continuous integration platform OpenCI supports running emulated tests |
| 163 | on QEMU. The tests are kicked off on Jenkins and deployed through the Linaro |
| 164 | Automation and Validation Architecture `LAVA`_. |
| 165 | |
| 166 | There are a set of Linux boot tests provided in OpenCI. They rely on prebuilt |
| 167 | `binaries`_ for UEFI, the kernel, root file system, as well as, any other TF-A |
| 168 | dependencies, and are run as part of the OpenCI TF-A `daily job`_. To run them |
| 169 | manually, a `builder`_ job may be triggered with the test configuration |
| 170 | ``qemu-boot-tests``. |
| 171 | |
| 172 | |
| 173 | You may see the following warning repeated several times in the boot logs: |
| 174 | |
| 175 | .. code:: shell |
| 176 | |
| 177 | pflash_write: Write to buffer emulation is flawed |
| 178 | |
| 179 | Please ignore this as it is an unresolved `issue in QEMU`_, it is an internal |
| 180 | QEMU warning that logs flawed use of "write to buffer". |
| 181 | |
| 182 | .. note:: |
| 183 | For more information on how to trigger jobs in OpenCI, please refer to |
| 184 | Linaro's CI documentation, which explains how to trigger a `manual job`_. |
| 185 | |
| 186 | .. _binaries: https://downloads.trustedfirmware.org/tf-a/linux_boot/ |
| 187 | .. _daily job: https://ci.trustedfirmware.org/view/TF-A/job/tf-a-main/ |
| 188 | .. _builder: https://ci.trustedfirmware.org/view/TF-A/job/tf-a-builder/ |
| 189 | .. _LAVA: https://tf.validation.linaro.org/ |
| 190 | .. _manual job: https://tf-ci-users-guide.readthedocs.io/en/latest/#manual-job-trigger |
| 191 | .. _issue in QEMU: https://git.qemu.org/?p=qemu.git;a=blob;f=hw/block/pflash_cfi01.c;h=0cbc2fb4cbf62c9a033b8dd89012374ff74ed610;hb=refs/heads/master#l500 |