Bin Meng | c586ff0 | 2019-07-18 00:34:15 -0700 | [diff] [blame] | 1 | .. SPDX-License-Identifier: GPL-2.0+ |
| 2 | .. Copyright (C) 2017, Tuomas Tynkkynen <tuomas.tynkkynen@iki.fi> |
Tuomas Tynkkynen | d5587fa | 2017-10-09 19:42:41 +0300 | [diff] [blame] | 3 | |
Bin Meng | c586ff0 | 2019-07-18 00:34:15 -0700 | [diff] [blame] | 4 | QEMU ARM |
| 5 | ======== |
Tuomas Tynkkynen | d5587fa | 2017-10-09 19:42:41 +0300 | [diff] [blame] | 6 | |
| 7 | QEMU for ARM supports a special 'virt' machine designed for emulation and |
| 8 | virtualization purposes. This document describes how to run U-Boot under it. |
Tuomas Tynkkynen | e7ba41c | 2018-01-11 16:11:24 +0200 | [diff] [blame] | 9 | Both 32-bit ARM and AArch64 are supported. |
Tuomas Tynkkynen | d5587fa | 2017-10-09 19:42:41 +0300 | [diff] [blame] | 10 | |
| 11 | The 'virt' platform provides the following as the basic functionality: |
| 12 | |
| 13 | - A freely configurable amount of CPU cores |
| 14 | - U-Boot loaded and executing in the emulated flash at address 0x0 |
| 15 | - A generated device tree blob placed at the start of RAM |
| 16 | - A freely configurable amount of RAM, described by the DTB |
| 17 | - A PL011 serial port, discoverable via the DTB |
Tuomas Tynkkynen | e7ba41c | 2018-01-11 16:11:24 +0200 | [diff] [blame] | 18 | - An ARMv7/ARMv8 architected timer |
Tuomas Tynkkynen | d5587fa | 2017-10-09 19:42:41 +0300 | [diff] [blame] | 19 | - PSCI for rebooting the system |
| 20 | - A generic ECAM-based PCI host controller, discoverable via the DTB |
| 21 | |
| 22 | Additionally, a number of optional peripherals can be added to the PCI bus. |
| 23 | |
Simon Glass | c3c1614 | 2021-12-16 20:59:09 -0700 | [diff] [blame] | 24 | See :doc:`../../develop/devicetree/dt_qemu` for information on how to see |
| 25 | the devicetree actually generated by QEMU. |
| 26 | |
Tuomas Tynkkynen | d5587fa | 2017-10-09 19:42:41 +0300 | [diff] [blame] | 27 | Building U-Boot |
| 28 | --------------- |
Tuomas Tynkkynen | e7ba41c | 2018-01-11 16:11:24 +0200 | [diff] [blame] | 29 | Set the CROSS_COMPILE environment variable as usual, and run: |
Tuomas Tynkkynen | d5587fa | 2017-10-09 19:42:41 +0300 | [diff] [blame] | 30 | |
Bin Meng | c586ff0 | 2019-07-18 00:34:15 -0700 | [diff] [blame] | 31 | - For ARM:: |
| 32 | |
Tuomas Tynkkynen | d5587fa | 2017-10-09 19:42:41 +0300 | [diff] [blame] | 33 | make qemu_arm_defconfig |
| 34 | make |
| 35 | |
Bin Meng | c586ff0 | 2019-07-18 00:34:15 -0700 | [diff] [blame] | 36 | - For AArch64:: |
| 37 | |
Tuomas Tynkkynen | e7ba41c | 2018-01-11 16:11:24 +0200 | [diff] [blame] | 38 | make qemu_arm64_defconfig |
| 39 | make |
| 40 | |
Tuomas Tynkkynen | d5587fa | 2017-10-09 19:42:41 +0300 | [diff] [blame] | 41 | Running U-Boot |
| 42 | -------------- |
| 43 | The minimal QEMU command line to get U-Boot up and running is: |
| 44 | |
Bin Meng | c586ff0 | 2019-07-18 00:34:15 -0700 | [diff] [blame] | 45 | - For ARM:: |
| 46 | |
Simon Glass | 6d7636c | 2021-12-16 20:59:08 -0700 | [diff] [blame] | 47 | qemu-system-arm -machine virt -nographic -bios u-boot.bin |
Tuomas Tynkkynen | d5587fa | 2017-10-09 19:42:41 +0300 | [diff] [blame] | 48 | |
Bin Meng | c586ff0 | 2019-07-18 00:34:15 -0700 | [diff] [blame] | 49 | - For AArch64:: |
| 50 | |
Simon Glass | 6d7636c | 2021-12-16 20:59:08 -0700 | [diff] [blame] | 51 | qemu-system-aarch64 -machine virt -nographic -cpu cortex-a57 -bios u-boot.bin |
Tuomas Tynkkynen | e7ba41c | 2018-01-11 16:11:24 +0200 | [diff] [blame] | 52 | |
Tuomas Tynkkynen | 9792be7 | 2018-05-14 18:47:52 +0300 | [diff] [blame] | 53 | Note that for some odd reason qemu-system-aarch64 needs to be explicitly |
Simon Glass | 6d7636c | 2021-12-16 20:59:08 -0700 | [diff] [blame] | 54 | told to use a 64-bit CPU or it will boot in 32-bit mode. The -nographic argument |
| 55 | ensures that output appears on the terminal. Use Ctrl-A X to quit. |
Tuomas Tynkkynen | d5587fa | 2017-10-09 19:42:41 +0300 | [diff] [blame] | 56 | |
Michal Simek | 1be82af | 2023-05-17 09:17:16 +0200 | [diff] [blame] | 57 | Additional persistent U-Boot environment support can be added as follows: |
Bin Meng | c586ff0 | 2019-07-18 00:34:15 -0700 | [diff] [blame] | 58 | |
| 59 | - Create envstore.img using qemu-img:: |
| 60 | |
Sumit Garg | 03fb095 | 2018-11-26 16:50:17 +0530 | [diff] [blame] | 61 | qemu-img create -f raw envstore.img 64M |
Bin Meng | c586ff0 | 2019-07-18 00:34:15 -0700 | [diff] [blame] | 62 | |
| 63 | - Add a pflash drive parameter to the command line:: |
| 64 | |
Sumit Garg | 03fb095 | 2018-11-26 16:50:17 +0530 | [diff] [blame] | 65 | -drive if=pflash,format=raw,index=1,file=envstore.img |
| 66 | |
Tuomas Tynkkynen | d5587fa | 2017-10-09 19:42:41 +0300 | [diff] [blame] | 67 | Additional peripherals that have been tested to work in both U-Boot and Linux |
| 68 | can be enabled with the following command line parameters: |
| 69 | |
Alper Nebi Yasak | 4d6641d | 2023-08-14 20:39:41 +0300 | [diff] [blame] | 70 | - To add a video console, remove "-nographic" and add e.g.:: |
| 71 | |
| 72 | -serial stdio -device VGA |
| 73 | |
Bin Meng | c586ff0 | 2019-07-18 00:34:15 -0700 | [diff] [blame] | 74 | - To add a Serial ATA disk via an Intel ICH9 AHCI controller, pass e.g.:: |
| 75 | |
Heinrich Schuchardt | 9d24653 | 2021-11-28 11:50:58 +0100 | [diff] [blame] | 76 | -drive if=none,file=disk.img,format=raw,id=mydisk \ |
| 77 | -device ich9-ahci,id=ahci -device ide-drive,drive=mydisk,bus=ahci.0 |
Bin Meng | c586ff0 | 2019-07-18 00:34:15 -0700 | [diff] [blame] | 78 | |
| 79 | - To add an Intel E1000 network adapter, pass e.g.:: |
| 80 | |
Tuomas Tynkkynen | d5587fa | 2017-10-09 19:42:41 +0300 | [diff] [blame] | 81 | -netdev user,id=net0 -device e1000,netdev=net0 |
Bin Meng | c586ff0 | 2019-07-18 00:34:15 -0700 | [diff] [blame] | 82 | |
| 83 | - To add an EHCI-compliant USB host controller, pass e.g.:: |
| 84 | |
Tuomas Tynkkynen | d5587fa | 2017-10-09 19:42:41 +0300 | [diff] [blame] | 85 | -device usb-ehci,id=ehci |
Bin Meng | c586ff0 | 2019-07-18 00:34:15 -0700 | [diff] [blame] | 86 | |
Alper Nebi Yasak | 05e2fa7 | 2023-08-14 20:39:43 +0300 | [diff] [blame] | 87 | - To add a USB keyboard attached to an emulated xHCI controller, pass e.g.:: |
| 88 | |
| 89 | -device qemu-xhci,id=xhci -device usb-kbd,bus=xhci.0 |
| 90 | |
Heinrich Schuchardt | 9d24653 | 2021-11-28 11:50:58 +0100 | [diff] [blame] | 91 | - To add an NVMe disk, pass e.g.:: |
Bin Meng | c586ff0 | 2019-07-18 00:34:15 -0700 | [diff] [blame] | 92 | |
Tuomas Tynkkynen | d5587fa | 2017-10-09 19:42:41 +0300 | [diff] [blame] | 93 | -drive if=none,file=disk.img,id=mydisk -device nvme,drive=mydisk,serial=foo |
| 94 | |
Heinrich Schuchardt | 9d24653 | 2021-11-28 11:50:58 +0100 | [diff] [blame] | 95 | - To add a random number generator, pass e.g.:: |
| 96 | |
| 97 | -device virtio-rng-pci |
| 98 | |
Tuomas Tynkkynen | d5587fa | 2017-10-09 19:42:41 +0300 | [diff] [blame] | 99 | These have been tested in QEMU 2.9.0 but should work in at least 2.5.0 as well. |
Heinrich Schuchardt | c6963fb8 | 2020-09-16 00:17:55 +0200 | [diff] [blame] | 100 | |
Alper Nebi Yasak | 8def269 | 2023-08-14 20:39:44 +0300 | [diff] [blame^] | 101 | Booting distros |
| 102 | --------------- |
| 103 | |
| 104 | It is possible to install and boot a standard Linux distribution using |
| 105 | qemu_arm64 by setting up a root disk:: |
| 106 | |
| 107 | qemu-img create root.img 20G |
| 108 | |
| 109 | then using the installer to install. For example, with Debian 12:: |
| 110 | |
| 111 | qemu-system-aarch64 \ |
| 112 | -machine virt -cpu cortex-a53 -m 4G -smp 4 \ |
| 113 | -bios u-boot.bin \ |
| 114 | -serial stdio -device VGA \ |
| 115 | -nic user,model=virtio-net-pci \ |
| 116 | -device virtio-rng-pci \ |
| 117 | -device qemu-xhci,id=xhci \ |
| 118 | -device usb-kbd -device usb-tablet \ |
| 119 | -drive if=virtio,file=debian-12.0.0-arm64-netinst.iso,format=raw,readonly=on,media=cdrom \ |
| 120 | -drive if=virtio,file=root.img,format=raw,media=disk |
| 121 | |
| 122 | The output will be something like this:: |
| 123 | |
| 124 | U-Boot 2023.10-rc2-00075-gbe8fbe718e35 (Aug 11 2023 - 08:38:49 +0000) |
| 125 | |
| 126 | DRAM: 4 GiB |
| 127 | Core: 51 devices, 14 uclasses, devicetree: board |
| 128 | Flash: 64 MiB |
| 129 | Loading Environment from Flash... *** Warning - bad CRC, using default environment |
| 130 | |
| 131 | In: serial,usbkbd |
| 132 | Out: serial,vidconsole |
| 133 | Err: serial,vidconsole |
| 134 | Bus xhci_pci: Register 8001040 NbrPorts 8 |
| 135 | Starting the controller |
| 136 | USB XHCI 1.00 |
| 137 | scanning bus xhci_pci for devices... 3 USB Device(s) found |
| 138 | Net: eth0: virtio-net#32 |
| 139 | Hit any key to stop autoboot: 0 |
| 140 | Scanning for bootflows in all bootdevs |
| 141 | Seq Method State Uclass Part Name Filename |
| 142 | --- ----------- ------ -------- ---- ------------------------ ---------------- |
| 143 | Scanning global bootmeth 'efi_mgr': |
| 144 | Scanning bootdev 'fw-cfg@9020000.bootdev': |
| 145 | fatal: no kernel available |
| 146 | scanning bus for devices... |
| 147 | Scanning bootdev 'virtio-blk#34.bootdev': |
| 148 | 0 efi ready virtio 2 virtio-blk#34.bootdev.par efi/boot/bootaa64.efi |
| 149 | ** Booting bootflow 'virtio-blk#34.bootdev.part_2' with efi |
| 150 | Using prior-stage device tree |
| 151 | Failed to load EFI variables |
| 152 | Error: writing contents |
| 153 | ** Unable to write file ubootefi.var ** |
| 154 | Failed to persist EFI variables |
| 155 | Missing TPMv2 device for EFI_TCG_PROTOCOL |
| 156 | Booting /efi\boot\bootaa64.efi |
| 157 | Error: writing contents |
| 158 | ** Unable to write file ubootefi.var ** |
| 159 | Failed to persist EFI variables |
| 160 | Welcome to GRUB! |
| 161 | |
| 162 | Standard boot looks through various available devices and finds the virtio |
| 163 | disks, then boots from the first one. After a second or so the grub menu appears |
| 164 | and you can work through the installer flow normally. |
| 165 | |
| 166 | After the installation, you can boot into the installed system by running QEMU |
| 167 | again without the drive argument corresponding to the installer CD image. |
| 168 | |
Ilias Apalodimas | be2868f | 2021-11-09 09:02:21 +0200 | [diff] [blame] | 169 | Enabling TPMv2 support |
| 170 | ---------------------- |
| 171 | |
| 172 | To emulate a TPM the swtpm package may be used. It can be built from the |
| 173 | following repositories: |
| 174 | |
| 175 | https://github.com/stefanberger/swtpm.git |
| 176 | |
| 177 | Swtpm provides a socket for the TPM emulation which can be consumed by QEMU. |
| 178 | |
| 179 | In a first console invoke swtpm with:: |
| 180 | |
| 181 | swtpm socket --tpmstate dir=/tmp/mytpm1 \ |
| 182 | --ctrl type=unixio,path=/tmp/mytpm1/swtpm-sock --log level=20 |
| 183 | |
| 184 | In a second console invoke qemu-system-aarch64 with:: |
| 185 | |
| 186 | -chardev socket,id=chrtpm,path=/tmp/mytpm1/swtpm-sock \ |
| 187 | -tpmdev emulator,id=tpm0,chardev=chrtpm \ |
| 188 | -device tpm-tis-device,tpmdev=tpm0 |
| 189 | |
| 190 | Enable the TPM on U-Boot's command line with:: |
| 191 | |
| 192 | tpm2 startup TPM2_SU_CLEAR |
| 193 | |
Heinrich Schuchardt | c6963fb8 | 2020-09-16 00:17:55 +0200 | [diff] [blame] | 194 | Debug UART |
| 195 | ---------- |
| 196 | |
| 197 | The debug UART on the ARM virt board uses these settings:: |
| 198 | |
| 199 | CONFIG_DEBUG_UART=y |
| 200 | CONFIG_DEBUG_UART_PL010=y |
| 201 | CONFIG_DEBUG_UART_BASE=0x9000000 |
| 202 | CONFIG_DEBUG_UART_CLOCK=0 |