40 使用快速模拟器(QEMU)
Yocto Project 将开源项目 Quick EMUlator(QEMU)的一种实现纳入开发工具集。 本章介绍 QEMU 的使用步骤,以及有助于开发的其他信息。
40 概述
在 Yocto Project 中,QEMU 是模拟器和虚拟机,可让使用 Yocto Project 构建的 完整镜像像普通任务一样运行在构建系统上。它可以在没有实际硬件的情况下, 运行和测试受支持架构的镜像及应用程序。Yocto Project 还使用 QEMU 对每次 发行的最终镜像执行自动化质量保证(QA)测试等工作。
备注
此实现与通用 QEMU 并不完全相同。
本节为 Yocto Project 中的 QEMU 实现提供简要参考。
通用 QEMU 的官方信息和文档见:
40 运行 QEMU
使用 QEMU 前,需要安装并初始化 QEMU,准备好对应产物,即镜像文件和根文件 系统。基本步骤如下:
安装 QEMU: Yocto Project 提供多种获取 QEMU 的方式,其中之一是安装 软件开发工具包(SDK)。安装方法见 Yocto Project 应用程序开发与可扩展 软件开发工具包(eSDK)手册的 “QEMU 模拟器” 一节。
设置环境: QEMU 环境设置方式取决于安装方法:
如果按 准备使用 Yocto Project 操作,可使用
bitbake-setup,或 手动加载环境设置脚本:$ cd bitbake-builds $ source layers/openembedded-core/oe-init-build-env
如果安装了交叉工具链,可运行工具链初始化脚本。例如,以下命令运行 默认
poky_sdk目录中的脚本:. poky_sdk/environment-setup-core2-64-poky-linux
确保产物就绪: 需要能够在 QEMU 中启动的预构建内核,以及适合目标 机器架构的根文件系统:
如果已为 QEMU 构建过镜像,例如
qemux86、qemuarm,产物已经 位于 Build Directory。如果尚未构建镜像,可以到 machines/qemu 下载与架构匹配且可在 QEMU 中运行的预构建镜像。
提取根文件系统的方法,见 Yocto Project 应用程序开发与可扩展软件开发 工具包(eSDK)手册的 “解压根文件系统” 一节。
运行 QEMU:
runqemu的基本语法如下:$ runqemu [option ] [...]
runqemu会根据命令行参数推断所需操作。例如,需要查找镜像时,默认 按时间戳选择最近构建的镜像。至少需要通过选项提供机器名称、虚拟机镜像 (*wic.vmdk)或内核镜像(*.bin)之一。以下示例进一步说明用法:
本例以 MACHINE="qemux86-64" 启动 QEMU。在标准 Build Directory 下,
runqemu自动找到bzImage-qemux86-64.bin和core-image-minimal-qemux86-64-20200218002850.rootfs.ext4,假定当前 构建生成的是core-image-minimal镜像:$ runqemu qemux86-64
备注
如果有多个同名镜像,QEMU 按时间戳选择最近构建的镜像。
以下命令与上例结果相同,但显式指定镜像及根文件系统类型:
$ runqemu qemux86-64 core-image-minimal ext4
本例使用临时根文件系统("snapshot"),不启用图形界面("nographic"), 因而直接在当前 Shell 中启动 QEMU:
$ runqemu qemux86-64 snapshot nographic
"snapshot" 模式下,退出 QEMU 后不会保留根文件系统的修改。
本例启动 Initramfs 镜像,并启用 QEMU 音频。此时
runqemu将内部变量FSTYPE设为cpio.gz。启用音频还需安装适当驱动, 详见 runqemu 命令行选项 的audio选项:$ runqemu qemux86-64 ramfs audio
本例信息不足,无法启动 QEMU。虽然提供了根文件系统类型,但还必须至少 提供 MACHINE、KERNEL 或 VM 选项之一:
$ runqemu ext4
本例启动虚拟机镜像(
.wic.vmdk文件)。runqemu从文件名判断 QEMU 架构(MACHINE)为 "qemux86-64",根文件系统类型为 "vmdk":$ runqemu /home/scott-lenovo/vm/core-image-minimal-qemux86-64.wic.vmdk
40 切换控制台
QEMU 启动或运行期间,可按 Ctrl+Alt+数字切换受支持的控制台。例如,如果 串口控制台已启用,Ctrl+Alt+3 可切换过去。主 QEMU 控制台因故障无法使用时, 这种切换能力很有帮助。
备注
通常,"2" 对应主控制台,"3" 对应串口控制台。
40 移除启动画面
QEMU 启动时可按 Alt+左方向键移除启动画面,查看后台正在发生的事情。
40 禁用鼠标捕获
默认 QEMU 集成会将鼠标指针限制在主窗口内,因为标准鼠标设备只提供相对输入, 不提供绝对坐标。此时需要按 "Ctrl+Alt" 释放指针。Yocto Project 的 QEMU 集成默认启用 wacom USB 触控板驱动,支持绝对坐标输入,因此鼠标可以自由 进出主窗口,不会被捕获,使用体验更好。
40 通过网络文件系统(NFS)服务器运行
可以通过 NFS 服务器运行 QEMU。当构建系统和模拟系统需要同时访问同一文件 系统时,这种方式很有用。它使用用户空间 NFS 服务器,因此不需要 root 权限。设置步骤如下。
提取根文件系统: 环境能够运行 QEMU 后,可以使用与
runqemu同在scripts目录中的runqemu-extract-sdk脚本。此脚本将根文件系统归档包提取到指定位置。以下示例提取到
test-nfs目录:runqemu-extract-sdk ./tmp/deploy/images/qemux86-64/core-image-sato-qemux86-64.tar.bz2 test-nfs
启动 QEMU: 提取完成后,正常运行
runqemu,额外指定文件系统位置。 此后修改./test-nfs中的文件,会实时反映到镜像中。以下示例使用qemux86镜像:runqemu qemux86-64 ./test-nfs
备注
如需启动、停止或重启 NFS 共享,可以使用以下命令:
启动 NFS 共享:
runqemu-export-rootfs start file-system-location
停止 NFS 共享:
runqemu-export-rootfs stop file-system-location
重启 NFS 共享:
runqemu-export-rootfs restart file-system-location
40 KVM 下的 QEMU CPU 兼容性
默认情况下,QEMU 构建面向 64 位 x86 Intel Core2 Duo 和 32 位 x86 Intel Pentium II 处理器。选择这些 CPU 类型,是因为其特性与许多常用 CPU 有广泛 兼容性。
即使兼容范围很广,这些 CPU 仍可能支持主机 CPU 不具备的特性。QEMU 软件
模拟时通常没有问题,但启用 KVM 后可能出错:针对某项 CPU 特性编译的软件,
在不支持该特性的 KVM CPU 上运行会崩溃。可以修改 Build Directory
的 deploy/image 目录中 qemuboot.conf 的 QB_CPU_KVM,覆盖 QEMU
运行时 CPU 设置。该值决定 runqemu 传给 QEMU 的 -cpu 选项。运行
qemu -cpu help 可查看支持的 CPU 类型。
40 QEMU 性能
模拟速度取决于目标与主机架构的组合。例如,在 Intel 32 位 x86 主机上运行
qemux86 镜像较快,因为架构一致;同一主机运行 qemuarm 则可能较慢,
但仍能准确模拟 ARM 特有的问题。
为加快速度,QEMU 镜像支持通过 distcc 调用模拟系统之外的交叉编译器。
如果由 runqemu 启动,且主机有 distccd,在 QEMU 中调用 distcc
即可自动使用构建系统提供的 BitBake 交叉编译工具链。可通过设置编译器变量
实现,例如 export CC="distcc"。如果使用合适的 SDK 镜像或存在适当的
独立工具链,也会自动使用该工具链。
备注
有几种方式连接 QEMU 中运行的系统:
QEMU 提供帧缓冲接口,可使用标准控制台。
无显示器的嵌入式设备通常有串口,可以配置镜像的操作系统,通过串口 运行控制台。连接使用标准 IP 网络。
部分 QEMU 镜像包含 SSH 服务器。
core-image-sato提供禁用 root 密码的 Dropbear SSH 服务器,core-image-full-cmdline使用 OpenSSH。 这些服务器支持标准ssh和scp命令。core-image-minimal则不包含 SSH 服务器。可以使用所提供的用户空间 NFS 服务器,通过主机上的本地根文件系统 副本启动 QEMU。先用
runqemu-extract-sdk提取根文件系统归档包, 再让runqemu指向提取目录,而非根文件系统镜像文件。详见 “通过网络文件系统(NFS)服务器运行” 一节。
40 QEMU 命令行语法
runqemu 的基本语法如下:
$ runqemu [option ] [...]
runqemu 根据命令行参数推断所需操作。例如,需要查找镜像时,默认按
时间戳选择最近构建的镜像。至少需要提供机器名称、虚拟机镜像(*wic.vmdk)
或内核镜像(*.bin)之一。
以下为 runqemu 的命令行帮助输出:
$ runqemu --help
Usage: you can run this script with any valid combination
of the following environment variables (in any order):
KERNEL - the kernel image file to use
ROOTFS - the rootfs image file or nfsroot directory to use
MACHINE - the machine name (optional, autodetected from KERNEL filename if unspecified)
Simplified QEMU command-line options can be passed with:
nographic - disable video console
serial - enable a serial console on /dev/ttyS0
slirp - enable user networking, no root privileges required
kvm - enable KVM when running x86/x86_64 (VT-capable CPU required)
kvm-vhost - enable KVM with vhost when running x86/x86_64 (VT-capable CPU required)
publicvnc - enable a VNC server open to all hosts
audio - enable audio
[*/]ovmf* - OVMF firmware file or base name for booting with UEFI
tcpserial=<port> - specify tcp serial port number
biosdir=<dir> - specify custom bios dir
biosfilename=<filename> - specify bios filename
qemuparams=<xyz> - specify custom parameters to QEMU
bootparams=<xyz> - specify custom kernel parameters during boot
help, -h, --help: print this text
Examples:
runqemu
runqemu qemuarm
runqemu tmp/deploy/images/qemuarm
runqemu tmp/deploy/images/qemux86/<qemuboot.conf>
runqemu qemux86-64 core-image-sato ext4
runqemu qemux86-64 wic-image-minimal wic
runqemu path/to/bzImage-qemux86.bin path/to/nfsrootdir/ serial
runqemu qemux86 iso/hddimg/wic.vmdk/wic.qcow2/wic.vdi/ramfs/cpio.gz...
runqemu qemux86 qemuparams="-m 256"
runqemu qemux86 bootparams="psplash=false"
runqemu path/to/<image>-<machine>.wic
runqemu path/to/<image>-<machine>.wic.vmdk
40 runqemu 命令行选项
命令行可用的 runqemu 选项如下:
备注
如果提供的选项组合无效或信息不足,runqemu 会给出相应错误消息,
帮助修正问题。
QEMUARCH:QEMU 机器架构,必须是 "qemuarm"、"qemuarm64"、"qemumips"、 "qemumips64"、"qemuppc"、"qemux86" 或 "qemux86-64"。
VM:虚拟机镜像,必须为
.wic.vmdk文件。启动该格式镜像时使用。ROOTFS:根文件系统,扩展名为 "ext2"、"ext3"、"ext4"、"jffs2"、 "nfs" 或 "btrfs"。使用 "nfs" 时必须明确指定根文件系统路径。
KERNEL:内核镜像,即
.bin文件。提供.bin时,runqemu将其识别为内核镜像。MACHINE:QEMU 机器架构,必须为 "qemux86"、"qemux86-64"、"qemuarm"、 "qemuarm64"、"qemumips"、"qemumips64" 或 "qemuppc"。MACHINE 与 QEMUARCH 基本相同。未提供 MACHINE 时,
runqemu尝试根据其他选项判断。ramfs:启动 Initramfs 镜像,即FSTYPE为cpio.gz。iso:启动 ISO 镜像,即FSTYPE为.iso。nographic:禁用视频控制台,将控制台设为 "ttys0"。登录服务器且不希望 禁用 X Window System(X11)向工作站或笔记本转发时,此选项很有用。serial:在/dev/ttyS0启用串口控制台。biosdir:指定 BIOS、VGA BIOS 和键盘映射的自定义目录。biosfilename:指定自定义 BIOS 名称。qemuparams=\"xyz\":指定自定义 QEMU 参数,可传入简单的 "kvm" 和 "serial" 以外的选项。bootparams=\"xyz\":指定自定义内核启动参数。audio:启用 QEMU 音频。MACHINE 必须为 "qemux86" 或 "qemux86-64", 且 Linux 来宾中安装snd_intel8x0或snd_ens1370驱动。slirp:启用 "slirp" 网络。这种网络方式不需要 root 权限,但易用性 和完整性不如默认方式。slirp默认将来宾 TCP 22 和 23 端口转发到主机 2222 和 2323 端口, 或下一个空闲端口。可通过环境变量QB_SLIRP_OPT,或 Build Directory 的deploy/image中qemuboot.conf设置 特定转发规则。例如:QB_SLIRP_OPT = "-netdev user,id=net0,hostfwd=tcp::8080-:80" QB_SLIRP_OPT = "-netdev user,id=net0,hostfwd=tcp::8080-:80,hostfwd=tcp::2222-:22"
第一个示例将模拟系统 TCP 80 端口转发到主机 8080 或下一个空闲端口, 可通过
http://<host ip>:8080/访问 QEMU 内的 HTTP 服务器。第二个示例还将来宾 TCP 22 端口转发到主机 2222 或下一个空闲端口, 可通过
ssh -P 2222 <user>@<host ip>SSH 登录模拟系统。请确保正确配置防火墙软件。
kvm:为 "qemux86" 或 "qemux86-64" 启用 KVM,必须满足:MACHINE 为 "qemux86" 或 "qemux86-64"。
构建主机已安装 KVM 模块,提供
/dev/kvm。构建主机上的
/dev/kvm可读写。
kvm-vhost:为 "qemux86" 或 "qemux86-64" 启用带 VHOST 支持的 KVM, 必须满足:满足上述
kvm选项条件。构建主机具有 virtio 网络设备
/dev/vhost-net。构建主机上的
/dev/vhost-net可读或可写,并启用了 slirp。
publicvnc:启用向所有主机开放的 VNC 服务器。