QEMU 用户空间模拟器
支持的操作系统
用户空间模拟支持以下操作系统:
Linux,称为 qemu-linux-user。
BSD,称为 qemu-bsd-user。
功能
QEMU 用户空间模拟具有以下主要功能。
系统调用转换
系统调用是用户空间与内核之间的主要接口。 通常,各内核版本提供相同的系统调用,因此 QEMU 包含通用的系统调用转换器。 它负责调整字节序、32/64 位参数大小,再调用等效的宿主系统调用。
QEMU 也可以用类似方式调整设备专用的 ioctl() 调用。
POSIX 信号处理
QEMU 可以将宿主发出的所有信号(例如 SIGALRM)转发给正在运行的程序,
也能根据虚拟 CPU 异常生成信号,例如程序执行除零操作时生成 SIGFPE。
QEMU 依赖宿主内核模拟大多数信号相关系统调用,例如信号掩码。 在 Linux 上,QEMU 同时支持普通信号和实时信号。
线程
在 Linux 上,QEMU 可以模拟 clone 系统调用,
为每个被模拟线程创建真实的宿主线程,并为其分配独立的虚拟 CPU。
但 QEMU 依赖系统 libc 代为调用 clone,因此只接受 libc 所用的标志。
具体而言,不支持影响命名空间的标志,例如容器运行时使用的标志。
不过,QEMU 用户态进程本身仍可以在容器内运行。
QEMU 尽力正确模拟原子操作,但宿主与客户机内存模型的差异, 仍可能影响对内存模型作出假设的软件。
QEMU 在设计上允许最终模拟自身。虽然实际用途不大, 但这是展示模拟器能力的一项重要测试。
Linux 用户空间模拟器
命令行选项
qemu-i386 [-h] [-d] [-L path] [-s size] [-cpu model] [-g endpoint] [-B offset] [-R size] program [arguments...]
-h打印帮助。
-L path设置 x86 ELF 解释器路径前缀,默认为 /usr/local/qemu-i386。
-s size设置 x86 栈大小,单位为字节,默认为 524288。
-cpu model选择 CPU 型号;使用 -cpu help 查看列表及额外特性的选择方式。
-E var=value将环境变量 var 设为 value。
-U var从环境中删除 var。
-B offset将客户机地址偏移指定字节数。当客户机应用需要的地址区域已被宿主保留时, 此选项很有用。目前仅部分宿主支持。
-R size预分配指定大小的客户机虚拟地址空间,单位为字节。 指定大小时可以使用 "G"、"M" 和 "k" 后缀。
调试选项:
-d item1,...启用指定项目的日志,使用 '-d help' 查看日志项目列表。
-g endpoint在端口(例如
1234)或 Unix socket(例如/tmp/qemu.sock)上等待 GDB 连接。如果 Unix socket 路径包含一个
%d占位符,例如/tmp/qemu-%d.sock, 它会替换为模拟器的 PID。 通过QEMU_GDB环境变量向多进程应用传递此选项时,这很有用。如果端点地址后加上
,suspend=n,例如1234,suspend=n, 被模拟程序会立即启动,无需等待连接;之后仍可随时连接。-one-insn-per-tb每个翻译块只执行一条客户机指令。 这会显著降低模拟速度,但在分析
-d选项生成的日志等场景下可能有用。
环境变量:
- QEMU_STRACE
类似 strace,打印系统调用及其参数。 真正的 strace 无法工作,因为用户空间模拟器尚未实现 ptrace。 此功能目前仍不完整。没有专用参数格式的系统调用一律打印六个参数的信息; 许多标志类参数没有解码器,只显示数字。
其他二进制程序
用户态(Alpha)
qemu-alpha:待补充。
用户态(Arm)
qemu-armeb:待补充。qemu-arm还支持 Arm "Angel" 半主机 ELF 二进制程序, 对应 arm-elf 和 arm-eabi 的 Newlib/GDB 配置实现, 以及 arm-uclinux 的 bFLT 格式程序。
用户态(ColdFire)
用户态(M68K)
qemu-m68k可以运行使用 BDM(m5xxx-ram-hosted.ld)或 m68k-sim(sim.ld)系统调用接口的半主机程序,以及 coldfire uClinux bFLT 程序。
二进制格式会自动检测。
用户态(i386)
qemu-i386:待补充。qemu-x86_64:待补充。
用户态(Microblaze)
qemu-microblaze:待补充。
用户态(MIPS)
qemu-mips执行 32 位大端 MIPS 程序(MIPS O32 ABI)。qemu-mipsel执行 32 位小端 MIPS 程序(MIPS O32 ABI)。qemu-mips64执行 64 位大端 MIPS 程序(MIPS N64 ABI)。qemu-mips64el执行 64 位小端 MIPS 程序(MIPS N64 ABI)。qemu-mipsn32执行 32 位大端 MIPS 程序(MIPS N32 ABI)。qemu-mipsn32el执行 32 位小端 MIPS 程序(MIPS N32 ABI)。
用户态(PowerPC)
qemu-ppc64:待补充。qemu-ppc:待补充。
用户态(SH4)
qemu-sh4eb:待补充。qemu-sh4:待补充。
用户态(SPARC)
qemu-sparc可以执行 Sparc32 程序(Sparc32 CPU,32 位 ABI)。qemu-sparc32plus可以执行 Sparc32 和 SPARC32PLUS 程序 (Sparc64 CPU,32 位 ABI)。qemu-sparc64可以执行部分 Sparc64 程序(Sparc64 CPU,64 位 ABI), 以及 SPARC32PLUS 程序(Sparc64 CPU,32 位 ABI)。
BSD 用户空间模拟器
BSD 支持状态
在 Sparc64 宿主上模拟 Sparc64 目标:部分简单程序可以运行。
快速入门
要启动 BSD 进程,QEMU 需要进程的可执行文件,以及它使用的全部目标动态库。
在 Sparc64 上,可以直接使用本机库尝试启动进程::
qemu-sparc64 /bin/ls
命令行选项
qemu-sparc64 [-h] [-d] [-L path] [-s size] [-bsd type] program [arguments...]
-h打印帮助。
-L path设置库的根路径,默认为 /。
-s size设置栈大小,单位为字节,默认为 524288。
-ignore-environment以空环境启动。如果不使用此选项,初始环境是调用者环境的副本。
-E var=value将环境变量 var 设为 value。
-U var从环境中删除 var。
-bsd type设置被模拟的 BSD 操作系统类型。 有效值为 FreeBSD、NetBSD 和 OpenBSD,默认 OpenBSD。
调试选项:
-d item1,...启用指定项目的日志,使用 '-d help' 查看日志项目列表。
-one-insn-per-tb每个翻译块只执行一条客户机指令。 这会显著降低模拟速度,但在分析
-d日志等场景下可能有用。