2.1.2 QEMU

简介

qemu(https://qemu.org)是开源的纯软件实现的虚拟化模拟器,几乎可以模拟任何硬件设备。当作为模拟器时的 qemu,可以在一种架构(如 x86 PC)下运行另一种架构(如 ARM)下的操作系统和程序,通过使用动态转换,它可以获得非常好的性能。作为虚拟机时,qemu 可以使用其他虚拟机管理程序(如 KVM)来使用 CPU 扩展进行虚拟化,通过在主机 CPU 上直接执行客户机代码来获得接近于宿主机的性能。

有时我们会遇到不同于 x86 或 x64 架构的可执行文件,而我们恰好没有调试运行环境的 ARM 和 MIPS 环境来说,使用 qemu 加载这类二进制文件是不错的选择。与其他的虚拟化软件(如 VMware)不同,qemu 不提供管理虚拟机的 GUI(运行虚拟机时出现的窗口除外),也不提供创建具有已保存设置的持久虚拟机的方法。因此,我们可以选择创建自定义脚本以启动虚拟机,这样就可以保存相应的参数,避免每次启动时手动指定所有运行参数。

安装

使用包管理器安装十分方便,在 Ubuntu 系统中只需要如下命令即可:

$ sudo apt install qemu

如果想要编译安装,则首先需要安装一些依赖文件,然后从官网下载源码,使用如下命令进行编译:

$ sudo apt install libcap-dev libpixman-1-dev libncurses5-dev libasound2-dev libasound2 libglib2.0-dev u-boot-tools flex

$ tar -xf qemu-3.1.0.tar.xz
$ mkdir qemu-3.1.0.build
$ cd qemu-3.1.0.build
$ ./../qemu-3.1.0/configure --target-list=arm-softmmu,aarch64-softmmu,mips-softmmu,mipsel-softmmu,i386-softmmu,x86_64-softmmu,arm-linux-user,aarch64-linux-user,i386-linux-user,x86_64-linux-user,mips-linux-user,mipsel-linux-user --audio-drv-list=alsa --enable-virtfs
$ make -j2 && sudo make install

模拟 Armhf 环境

首先介绍一下 armhf 架构。出于低功耗、封装限制等种种原因,以前的一些 ARM 处理器没有独立的硬件浮点运算单元,需要手写软件来实现浮点运算。随着技术发展,现在高端的 ARM 处理器基本都具备了硬件执行浮点操作的能力。这样,新旧两种架构之间的差异,就产生了两个不同的嵌入式应用程序二进制接口(EABI)——软浮点(soft float, sf)和矢量浮点(vector float point, vfp),但是软浮点和硬浮点(hard float, hf)之间有向前兼容却没有向后兼容的能力,即软浮点的二进制接口仍然可以用于当前的高端 ARM 处理器。

在 ARM 体系架构内核中,有些有浮点运算单元(floating point unit, fpu),而有些没有。对于没有 fpu 内核,是不能使用 armel 和 armhf 的。在有 fpu 的情况下,就可以通过 gcc 的选项 -mfloat-abi 来指定使用哪种,有如下三种值:

  • soft:不用 fpu 计算;

  • armel:(arm eabi little endian)也即 softfp,用 fpu 计算,但是传参数用普通寄存器传,这样中断的时候,只需要保存普通寄存器,中断负荷小,但是参数需要转换成浮点的再计算;

  • armhf:(arm hard float)也即 hard,用 fpu 计算,传参数用 fpu 中的浮点寄存器传,省去了转换性能最好,但是中断负荷高;

  • arm64:64 位的 arm 默认就是 hard float 的,因此不需要 hf 的后缀。

想要交叉编译 arm 架构的可执行文件,我们首先需要安装交叉编译工具链:

工具链安装完成之后,就可以使用如下命令进行 armhf 架构的交叉编译了:

为了简便,我们可以选择使用 Debian 社区已经制作好的 qemu 镜像,选择 armhf 目录下载文件即可,地址为 https://people.debian.org/~aurel32/qemu。该系统镜像基于 Debian Wheezy 发行版制作而成,大小为 25Gb,内存使用 -m 参数控制为 128Mb 至 1024Mb,root 用户口令为 root,普通用户的用户名和口令均为 user。接下来启动虚拟机,如下所示:

至此,基于 qemu 的 armhf 架构的运行与调试环境就搭建完成了。

模拟 MIPS 环境

MIPS 架构也是一种精简指令集的处理器架构,由于其低功耗高性能的设计,同ARM架构类似,也在嵌入式系统中有着广泛的应用。接下来我们使用 qemu 模拟 MIPS 环境,在此之前,需要安装 MIPS 架构的交叉编译工具链:

想要使用 qemu 运行 MIPS 架构的二进制可执行文件十分简单,使用如下的交叉编译命令编译后,输入以下命令就可以执行了:

如果我们想要使用 qemu 模拟执行 MIPS 架构的可执行文件,并调试该可执行文件的话,可以使用如下命令启动 qemu-mips:

-g 后的 port 参数指的是使用 gdb 远程连接的端口,之后的 binary_mips 指的是 MIPS 架构的可执行文件。接着,我们需要新开一个终端窗口并开启 gdb-multiarch 调试器,载入我们想要调试的文件,设置远程端口即可:

要想调试其他架构的可执行文件,可以使用 gef 开发者已经编译好的 gdb 和 gdbserver(https://github.com/hugsy/gdb-static),也可以使用如下命令编译符合该可执行文件架构的 gdb 或 gdbserver(此处以 mips 架构为例):

至此,MIPS 运行及调试环境就准备完成了。

参考资料

Last updated