使用QEMU的系统模式进行模拟

使用QEMU的系统模式进行模拟

当 QEMU 运行在系统模式下时,需要为 QEMU 指定内核镜像、IDE硬盘镜像、内核参数。这样一来,使用 QEMU 模拟的虚拟机才能正常运行。Debian 官网提供了 QEMU 虚拟机各种平台架构的内核镜像、硬盘文件镜像文件的下载。

备注:Debian官网的链接目前还是挂掉的状态,还好有大佬备份下来了arm架构和mips架构的镜像,贴一个网盘链接

链接:https://pan.baidu.com/s/1me2w5d5Qt31Fyi5jS-TKJg?pwd=brkp
提取码:brkp

以 MIPS 小段架构为例,选择 mipsel 文件夹,按照镜像文件的相关说明(如下),我们根据实际需要选择对应的文件。这里我们使用 32 位的 MIPS 架构为例。

1
2
3
4
5
6
7
8
To use this image, you need to QEMU 1.1.0(or later).
Start QEMU with the following arguments for a 32-bit machine:
- qemu-system-mipsel -M malta -kernel vmlinux-2.6.32-5-4kc-malta -hda debian_squeeze_mipsel_standard.qcow2 -append "root=/dev/sda1 console=tty0"
- qemu-system-mipsel -M malta -kernel vmlinux-3.2.0-4-4kc-malta -hda debian_wheezy_mipsel_standard.qcow2 -append "root=/dev/sda1 console=tty0"

Start QEMU with the following arguments for a 64-bit machine:
- qemu-system-mips64el -M malta -kernel vmlinux-2.6.32-5-4kc-malta -hda debian_squeeze_mipsel_standard.qcow2 -append "root=/dev/sda1 console=tty0"
- qemu-system-mips64el -M malta -kernel vmlinux-3.2.0-4-4kc-malta -hda debian_wheezy_mipsel_standard.qcow2 -append "root=/dev/sda1 console=tty0"

可以看到,我们需要下载 vmlinux-3.2.0-4-4kc-malta 和 debian_wheezy_mipsel_standard.qcow2 这两个文件。把下载下来的两个文件放在同一个目录下。为了让 QEMU 虚拟机能够通信与主机进行网络通信,需要先配置虚拟网卡。这里需要用到tunctl工具,可以通过sudo apt install uml-utilities命令来安装该工具。

安装完tunctl工具之后,接下来配置虚拟网卡,使虚拟机与物理机进行通信,以 Ubuntu 20.04 为例,相关命令如下:

1
2
3
4
5
6
7
8
9
10
11
12
~$ sudo tunctl -t tap0 -u `whoami`
Set 'tap0' persistent and owned by uid 1000
~$ sudo ifconfig tap0 10.10.10.1/24
~$ ifconfig tap0
tap0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet 10.10.10.1 netmask 255.255.255.0 broadcast 10.10.10.255
ether 0a:e3:05:9a:5e:5b txqueuelen 1000 (以太网)
RX packets 8112 bytes 2112112 (2.1 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 12545 bytes 17409722 (17.4 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

配置完之后,执行qemu-system-mipsel命令,启动QEMU虚拟机镜像,并且设置与主机的网络通信。

1
~$ qemu-system-mipsel -M malta -kernel vmlinux-3.2.0-4-4kc-malta -hda debian_wheezy_mipsel_standard.qcow2 -append "root=/dev/sda1 console=tty0" -net nic -net tap,ifname=tap0

在启动 QEMU 虚拟机之后,会出现如下登录界面,账户和密码均是root(/user)

image-20230424202830119

登录后,需要配置 QEMU 虚拟机的网卡。其中网段的设置与之前 Ubuntu 中配置虚拟网卡时用的网段保持一致,然后将 QEMU 虚拟机的 IP 地址设置为 10.10.10.2/24 。设置完之后,对虚拟机进行测试,看能否与主机进行通信,如下图所示:

image-20230424203304111

接下来,在 Ubuntu 中,将从固件中提取出来的文件系统比如squashfs-root重新打包,并在当前文件夹下使用 Python2 内置的命令 python -m SimpleHTTPSever开启 Web 服务,以供虚拟机下载打包后的文件(即固件系统)。

image-20230424204139664

开启 HTTP 服务后,在 QEMU 虚拟机中执行wget命令下载并解压文件。

image-20230424204408913

在 QEMU 虚拟机中执行chroot命令,将当前 QEMU 虚拟机的根目录指定为 squsash-root 之后,QEMU 虚拟机系统读取的时新根目录下的目录和文件。也就是说,对固件的目录和文件执行 chroot 命令默认不会切换/dev/proc,因此在执行chroot命令来切换根目录之前,需要先挂在这两个目录。

image-20230424205132316

在 QEMU 虚拟机中执行 chroot squash-root sh命令,切换 squash-root 为根路径,同时执行busyboxsh命令,进入 shell 模式,启动 HTTP 服务或其他相关服务来模拟组件,如下图所示。

image-20230424205159264

注:其他架构的固件模拟过程类似,需要注意的是使用 QEMU 进行模拟时参数的设置,这个挖坑,有空了系统学习一下 qemu 命令一堆复杂的参数。