使用 QEMU 进行系统仿真

来源:互联网 发布:windows同步时间超时 编辑:程序博客网 时间:2024/05/18 11:11

本文所介绍的一种有趣的虚拟化应用程序 QEMU 并非目前的热门技术。QEMU 应用程序适用于各种设置。可用于来宾操作系统的虚拟化,或作为完整的机器仿真器使用,运行使用主机 CPU 或其他 CPU 架构的操作系统。


虚拟化简介
我们首先简要介绍一下虚拟化,阐述 QEMU 的搭建背景。
本文中介绍的虚拟化实际上指的是平台虚拟化。在物理硬件上,控制程序可能是主机操作系统或管理程序(见图 1)。在某些情况下,主机操作系统就是管理程序。来宾操作系统位于管理程序中。在某些情况下,来宾操作系统与控制程序使用相同的 CPU,而在另外一些情况下,则可能不同(比如 PowerPC 来宾操作系统在 x86 硬件上运行)。

图 1. 平台虚拟化的基本架构

您可以通过多种方法实现虚拟化,但是最常见的有三种。第一种称为本地虚拟化(或全虚拟化)。在这种虚拟化中,管理程序实现基本的隔离元素,将物理硬件与来宾操作系统相分离。这种技术首次出现于 1966 年 IBM® CP-40 虚拟机/虚拟内存操作系统中,另外 VMware ESX Server 也使用了此技术。
另一种流行的虚拟化技术称为半虚拟化。在半虚拟化中,控制程序实现了管理程序的应用程序接口(API),它将由来宾操作系统使用。Xen 和 Linux Kernel-based Virtual Machine (KVM) 都使用了半虚拟化技术。
第三种有用的技术称为仿真。仿真,顾名思义,通过模拟完整的硬件环境来虚拟化来宾平台。仿真可通过多种方法实现,即使在同一个解决方案中也是如此。通过仿真实现虚拟化的技术有 QEMU 和 Bochs。
QEMU 架构
我们首先了解一下 QEMU 如何实现仿真。本节将介绍 QEMU 的两种操作模式,以及 QEMU 动态翻译程序的一些有趣特点。
QEMU 基本操作
QEMU 支持两种操作模式:用户模式仿真和系统模式仿真。用户模式仿真 允许一个 CPU 构建的进程在另一个 CPU 上执行(执行主机 CPU 指令的动态翻译并相应地转换 Linux 系统调用)。系统模式仿真 允许对整个系统进行仿真,包括处理器和配套的外围设备。
在 x86 主机系统上仿真 x86 代码时,使用 QEMU 加速器 可以实现近似本地的性能。这让我们能够直接在主机 CPU 上执行仿真代码(在 Linux 上通过 kernel 模块执行)。
但是从技术角度看,QEMU 的有趣之处在于其快速、可移植的动态翻译程序。动态翻译程序 允许在运行时将用于目标(来宾)CPU 的指令转换为用于主机 CPU,从而实现仿真。这可以通过一种强制方法实现(将指令从一个 CPU 映射到另一个 CPU),但是情况并非总是这样简单,在某些情况下,根据所翻译的架构,可能需要使用多个指令或行为更改。
QEMU 实现动态翻译的方法是,首先将目标指令转换为微操作。这些微操作是一些编译成对象的 C 代码。然后构建核心翻译程序。它将目标指令映射到微操作以进行动态翻译。这不仅可产生高效率,而且还可以移植。
QEMU 的动态翻译程序还缓存了翻译后的代码块,使翻译程序的内存开销最小化。当初次使用目标代码块时,翻译该块并将其存储为翻译后的代码块。 QEMU 将最近使用的翻译后的代码块缓存在一个 16 MB 的块中。 QEMU 甚至可以通过在缓存中将翻译后的代码块变为无效来支持代码的自我修改。
要了解 QEMU 及其动态翻译程序的更多内部细节,请参阅QEMU教程的文章。
受支持的外围设备
将 QEMU 作为 PC 系统仿真器使用可提供各种外围设备。需要的标准外围设备包括硬件 Video Graphics Array (VGA) 仿真器、PS/2 鼠标和键盘、集成开发环境(IDE)硬盘和 CD-ROM 接口,以及软盘仿真。另外,QEMU 包括对 NE2000 Peripheral Controller Interconnect (PCI) 网络适配器、串行端口、大量的声卡和 PCI Universal Host Controller Interface (UHCI) Universal Serial Bus (USB) 控制器(带虚拟 USB 集线器)的仿真。Processor symmetric multiprocessing (SMP) 支持也得到了对 255 个 CPU 的支持。
除了仿真标准 PC 或 ISA PC(不带 PCI 总线)外,QEMU 还可以仿真其他非 PC 硬件,如 ARM Versatile 基线板(使用 926E)和 Malta million instructions per second (MIPS) 板。对于各种其他平台,包括 Power Macintosh G3 (Blue & White) 和 Sun-4u 平台,都能正常工作。
构建和安装 QEMU
构建和安装 QEMU 与使用标准的 GNU 工具一样简单。下载并打开 QEMU 发行版之后,configure、make,然后 make install,任务就完成了(见清单 1)。

清单 1. 构建 QEMU 仿真器

$ wget http://fabrice.bellard.free.fr/qemu/qemu-0.9.0.tar.gz
$ tar xfvz qemu-0.9.0.tar.gz
$ cd qemu-0.9.0
$ ./configure
$ make
$ make install
$

此过程不仅可以为当前的目标架构创建可执行的 qemu 映像,而且可以为其他架构(包括 ARM、MIPS、PowerPC、68k 和 SPARC)创建一组映像。 这样,您就可以引导为不同目标架构构建的 Linux 内核。
如果主机操作系统和来宾操作系统运行于相同的处理器架构之上,那么您可以使用 QEMU 加速器(KQEMU)实现近似本地的性能。KQEMU 是一个驱动程序(Linux 的内核模块),允许用户模式的代码和内核代码直接在主机 CPU 上执行。构建 QEMU 加速器与构建 QEMU 本身相同(见清单 2)。

清单 2. 构建 QEMU 加速器

$ http://fabrice.bellard.free.fr/qemu/kqemu-1.3.0pre11.tar.gz
$ tar xvfz kqemu-1.3.0pre11.tar.gz
$ cd kqemu-1.3.0pre11
$ ./configure
$ make
$ make install

您可以在很多操作系统,包括 Microsoft® Windows®、FreeBSD® 和 Linux 上编译和安装 KQEMU。构建 QEMU 加速器之后,使用以下命令在 Linux 中安装该加速器:
$ insmod kqemu.ko
$

使用 QEMU
现在考察一下使用 QEMU 虚拟化另一台带典型的桌面 GNU/Linux 环境的机器的情况。仿真另一台机器与处理新计算机类似。 第一步是安装操作系统。新计算机必须要有安装操作系统的空间,因此需要一个硬盘。
QEMU 提供了一条特殊的命令创建硬盘,此命令称为 qemu-img。此工具可以创建各种格式的映像,但最佳的格式(对于 qemu)称为 qcow(或 qemu 写时复制)。这种格式的优点在于磁盘映像的大小与表示映像的物理文件的大小不同。换言之,该格式允许实现更紧凑的磁盘映像。例如,一个空的 4GB 磁盘映像只需要 16KB 的空间。
对于 qemu-img,您需要提供操作类型(create 创建新磁盘映像)、格式(qcow 用于 qemu 映像格式)、大小和磁盘映像的名称。本例中仿真的机器用于一个在 Flash 中使用的微型 Linux 发行版。因此,将 128MB 的磁盘映像创建为:
$ qemu-img create -f qcow disk.img 128M
Formating 'disk.img', fmt=qcow, size=131072 kB
$

注意,如果您计划安装通用操作系统,如 Windows、Linux 或 FreeBSD,则需要更大的磁盘空间。此操作的结果是仿真时出现一个 disk.img 文件,其形式是一个 128MB 的磁盘。
现在已经创建好硬盘,可以在上面安装新操作系统。出于演示的目的,我将使用一个较小的 Linux 发行版 cfLinux。cfLinux 的标准用法是作为基于 Linux 的小型嵌入式系统使用,此系统应适用网关、无线入口点、防火墙或路由器。您可以使用 wget 下载 ISO 格式的发行版:
wget ftp://ftp.cflinux.fu/pub/cflinux/iso/cflinux-1.0.iso

ISO 映像是常见的 CD-ROM 格式(在其他地方称为 ISO 9660 文件系统)。
现在,您已经仿真了硬盘(disk.img)和 CD-ROM,您可以在上面安装操作系统。下一步是在硬盘上安装操作系统。简单地使用 qemu 即可完成此任务:
$ qemu -hda disk.img -cdrom /root/cflinux-1.0.iso -boot d
$

使用 qemu 时,您使用 hda 选项指定硬盘映像,使用 cdrom 选项指定 cdrom(ISO 映像所在的文件)。boot 选项指定从 CD-ROM 引导。参数 d 指定从 CD-ROM 引导,其中 a 指定从软盘引导,c 指定从硬盘引导(默认),而 n 指定从网络引导。发出此命令后,出现一个表示已仿真机器的新 QEMU 窗口(见图 2)。

图 2. 准备使用 QEMU 将 cfLinux 安装到仿真磁盘上

遵循安装指令,按照 CD-ROM 安装完成在仿真硬盘上的 ISO 安装。安装程序要求您重新启动。此时,您可以终止仿真(在 qemu 窗口中按 Ctrl-C)。您可以使用以下命令引导最新安装的操作系统:
$ qemu -hda disk.img
$


此命令只是说明使用 disk.img 映像文件表示的硬盘仿真标准 PC(默认选项)。Linux 映像从仿真硬盘开始引导,导致出现 QEMU 窗口,如图 3 所示。

图 3. 从仿真硬盘引导最新安装的 cfLinux

这再简单不过了。实际上,您可以按照同样的顺序安装和引导任何种类的操作系统(Linux 产品发行版、Windows 或其他)。
其他仿真器
虽然 QEMU 是一种极好的仿真环境,但是其他环境也值得研究一下。 Wine 是 Windows API 的一个开源实现,允许您在没有 Windows 操作系统的情况下运行 Windows 程序。但是如 Wine 缩略词所表示的那样,Wine 不是仿真器。相反,Wine 实现了一组 API,这些 API 允许执行 x86 架构的应用程序。因此,运行在 Wine 上的应用程序可以很好地执行。
与 QEMU 类似的仿真器是 Bochs。Bochs 是一种机器仿真器,它不仅可以仿真 Intel® 的 i386™、i486™、Pentium®、Pentium Pro 和 Advanced Micro Devices 的 AMD64 CPU,还可以仿真常见 PC 外围设备,如磁盘、内存、显示器和网络设备。Bochs 已被用于仿真 Linux、DOS 和 Windows 95/98/XP/2000/NT® 操作系统。
将 QEMU 作为机器仿真器使用让您能够试验各种操作系统,因为您可能没有多余的机器直接进行试验。ReactOS 就是一个这样的例子,它是一个开源的 Windows XP 兼容的操作系统(其仿真如图 4 所示)。ReactOS 的目标是与 Windows XP 实现二进制兼容,因此您可以直接在 ReactOS 上运行针对 Windows XP 构建的应用程序。

图 4. 为 ReactOS 仿真标准 PC