Skip to the content.

QEMU ARM

1. Introdcution

QEMU for ARM 支持专为仿真和虚拟化目的而设计的特殊“虚拟”机器。 本文档介绍了如何在其下运行U-Boot。 支持 32 位 ARM 和 AArch64。

“virt”平台提供以下基本功能:

此外,许多可选外设可以添加到 PCI 总线上。

有关如何查看 QEMU 实际生成的设备树的信息,请参阅QEMU 中的设备树

2. Building U-Boot

像往常一样设置 CROSS_COMPILE 环境变量,然后运行:

make qemu_arm_defconfig
make
make qemu_arm64_defconfig
make

3. Running U-Boot

启动并运行 U-Boot 的最小 QEMU 命令行是:

qemu-system-arm -machine virt -nographic -bios u-boot.bin
qemu-system-aarch64 -machine virt -nographic -cpu cortex-a57 -bios u-boot.bin

请注意,由于某些奇怪的原因,需要明确告诉 qemu-system-aarch64 使用 64 位 CPU,否则它将以 32 位模式启动。 -ngraphic 参数确保输出出现在终端上。 使用 Ctrl-A X 退出。

可以添加额外的持久 U-Boot 环境支持,如下所示:

qemu-img create -f raw envstore.img 64M
-drive if=pflash,format=raw,index=1,file=envstore.img

可以使用以下命令行参数启用经测试可在 U-Boot 和 Linux 中工作的其他外设:

-serial stdio -device VGA
-drive if=none,file=disk.img,format=raw,id=mydisk \
-device ich9-ahci,id=ahci -device ide-drive,drive=mydisk,bus=ahci.0
-netdev user,id=net0 -device e1000,netdev=net0
-device usb-ehci,id=ehci
-device qemu-xhci,id=xhci -device usb-kbd,bus=xhci.0
-drive if=none,file=disk.img,id=mydisk -device nvme,drive=mydisk,serial=foo
-device virtio-rng-pci

这些已经在 QEMU 2.9.0 中进行了测试,但至少也应该在 2.5.0 中工作。

4. Booting distros

可以通过设置根磁盘来使用 qemu_arm64 安装和启动标准 Linux 发行版:

qemu-img create root.img 20G

然后使用安装程序进行安装。 例如,对于 Debian 12:

qemu-system-aarch64 \
  -machine virt -cpu cortex-a53 -m 4G -smp 4 \
  -bios u-boot.bin \
  -serial stdio -device VGA \
  -nic user,model=virtio-net-pci \
  -device virtio-rng-pci \
  -device qemu-xhci,id=xhci \
  -device usb-kbd -device usb-tablet \
  -drive if=virtio,file=debian-12.0.0-arm64-netinst.iso,format=raw,readonly=on,media=cdrom \
  -drive if=virtio,file=root.img,format=raw,media=disk

输出将是这样的:

U-Boot 2023.10-rc2-00075-gbe8fbe718e35 (Aug 11 2023 - 08:38:49 +0000)

DRAM:  4 GiB
Core:  51 devices, 14 uclasses, devicetree: board
Flash: 64 MiB
Loading Environment from Flash... *** Warning - bad CRC, using default environment

In:    serial,usbkbd
Out:   serial,vidconsole
Err:   serial,vidconsole
Bus xhci_pci: Register 8001040 NbrPorts 8
Starting the controller
USB XHCI 1.00
scanning bus xhci_pci for devices... 3 USB Device(s) found
Net:   eth0: virtio-net#32
Hit any key to stop autoboot:  0
Scanning for bootflows in all bootdevs
Seq  Method       State   Uclass    Part  Name                      Filename
---  -----------  ------  --------  ----  ------------------------  ----------------
Scanning global bootmeth 'efi_mgr':
Scanning bootdev 'fw-cfg@9020000.bootdev':
fatal: no kernel available
scanning bus for devices...
Scanning bootdev 'virtio-blk#34.bootdev':
  0  efi          ready   virtio       2  virtio-blk#34.bootdev.par efi/boot/bootaa64.efi
** Booting bootflow 'virtio-blk#34.bootdev.part_2' with efi
Using prior-stage device tree
Failed to load EFI variables
Error: writing contents
** Unable to write file ubootefi.var **
Failed to persist EFI variables
Missing TPMv2 device for EFI_TCG_PROTOCOL
Booting /efi\boot\bootaa64.efi
Error: writing contents
** Unable to write file ubootefi.var **
Failed to persist EFI variables
Welcome to GRUB!

标准启动会浏览各种可用设备并找到 virtio 磁盘,然后从第一个启动。 大约一秒钟后,grub 菜单就会出现,您可以正常完成安装程序流程。

安装完成后,您可以通过再次运行 QEMU 来启动已安装的系统,而无需与安装程序 CD 映像对应的驱动器参数。

5. Enabling TPMv2 support

为了模拟 TPM,可以使用 swtpm 包。 它可以从以下存储库构建:

https://github.com/stefenberger/swtpm.git

Swtpm 为 TPM 仿真提供了一个可供 QEMU 使用的套接字。

在第一个控制台中使用以下命令调用 swtpm:

swtpm socket --tpmstate dir=/tmp/mytpm1   \
--ctrl type=unixio,path=/tmp/mytpm1/swtpm-sock --log level=20

在第二个控制台中使用以下命令调用 qemu-system-aarch64:

-chardev socket,id=chrtpm,path=/tmp/mytpm1/swtpm-sock \
-tpmdev emulator,id=tpm0,chardev=chrtpm \
-device tpm-tis-device,tpmdev=tpm0

在 U-Boot 命令行上启用 TPM:

tpm autostart

6. Debug UART

ARM 虚拟板上的调试 UART 使用以下设置:

CONFIG_DEBUG_UART=y
CONFIG_DEBUG_UART_PL010=y
CONFIG_DEBUG_UART_BASE=0x9000000
CONFIG_DEBUG_UART_CLOCK=0