前两天看微信公众号时发现了一个嵌入式模拟器,感觉很不错,自己动手安装了一个,折腾了几天,下载一直是个问题,特此记录如下

模拟器大家应该都听说过,有的小伙伴打游戏也会安装模拟器,今天我们介绍的主角QMEU就是一个可以用在嵌入式的模拟器,如果你想学习嵌入式,但身边没有开发板,这时候你可以尝试使用它来模拟Linux内核的启动,当然它还可以模拟ARM、MIPS等各种CPU架构,本文主要介绍模拟ARM的启动流程

(一)环境介绍

        虚拟机:VMware

        Ubuntu 16.04LTS

(二)安装QEMU

我们常用的VMware和virtualBox只能在X86架构上,虚拟一台X86计算机,但是QEMU能用在X86架构下虚拟出ARM计算机。QEMU时一个支持跨平台的虚拟机,有两种模式:user mode和system mode,在system mode下能够模拟出整个计算机,可以在qemu上运行 操作系统,在user mode下,可以运行和当前平台指令集不同的可执行程序。例如可以用qemu在x86上运行ARM的可执行程序,但是两个平台必须是同一种操作系统,比如Linux。

由于本文介绍ARM版本,我们可以在Ubuntu里使用sudo apt install qemu-system-arm命令去安装,但是不太推荐此方法,Ubuntu里安装源更新比较慢,安装版本不确定,另外就是从官网(https://www.qemu.org/)下载源码包来安装,如果想了解更多,可以从阅读官网上相关信息。

(1)从官网下载好安装包,或者用我下载好的:qemu

wget https://download.qemu.org/qemu-5.1.0.tar.xz

怎么学嵌入式虚拟化技术 嵌入式 模拟_开发板

(2)执行下面的命令

$: tar -xvJf qemu-5.0.1.tar.xz 
$: cd qemu-5.0.1
$: ./configure
$: make & make install 

//如果报错要安装两个文件:apt-get install libglib2.0-dev
                        apt-get install libpixman-1-dev

怎么学嵌入式虚拟化技术 嵌入式 模拟_git_02

通过上面的安装了32位(qemu-system-arm)和64位(qemu-system-aarch64)的模拟器,使用help命令查看支持的开发板,这里面有很多我们的开发版选项,本文以vexpress-a9 (ARM Versatile Express for Cortex-A9) 为例进行讲解。

(三)编译操作系统

 (1)编译u-boot

      下载u-boot代码:

git clone https://gitlab.denx.de/u-boot/u-boot.git
//注意这个有时候会比较慢,找个合适的时间下载(比如早上),或者镜像上下载

下载完成后可以在u-boot的configs目录下查看配置文件,我们选择的vexpress-a9 配置文件是vexpress_ca9x4_defconfig,

make  vexpress_ca9x4_defconfig
make CROSS_COMPILE=arm-linux-gnueabihf- all

//make的时候可能出错,按照出错提示百度相关错误,可能由于没有相关命令支持,例如我安装时提示flex找不到,执行apt-get install flex在make就成功了
//需要交叉编译工具的可以在这里下载http://releases.linaro.org/components/toolchain/binaries/
注意:如果指定交叉编译器的路径一定要使用绝对路径

怎么学嵌入式虚拟化技术 嵌入式 模拟_git_03

 

(2)制作文件系统

以前都是使用busybox编译,然后手动创建跟文件目录,但是现在我们使用bulidroot可以很轻松容易的构建跟文件系统(这里感谢下文链接的作者提供了这么方便的工具)

buildroot下载

git clone git://git.buildroot.net/buildroot

 

上面下载的代码并不是真正下载跟文件系统,真正下载跟文件系统是在我们配置好后,编译时下载的。

  执行make menuconfig来配置选项:

怎么学嵌入式虚拟化技术 嵌入式 模拟_怎么学嵌入式虚拟化技术_04

然后在Target opions选择相应的目标平台,我们这里点进去选择arm(little-endian)即ARM架构小端模式

怎么学嵌入式虚拟化技术 嵌入式 模拟_怎么学嵌入式虚拟化技术_05

build options选项我这里不修改保持默认,有需要的可以自行修改

编译工具链toolchain选择外部,找到自己的编译工具链位置,具体参考我的配置情况

怎么学嵌入式虚拟化技术 嵌入式 模拟_开发板_06

上面的配置要注意内核头文件和编译工具链版本一样,不知道的可以在相应选项上按h查看帮助信息

选择对应的控制台信息:

怎么学嵌入式虚拟化技术 嵌入式 模拟_怎么学嵌入式虚拟化技术_07

为了减少跟文件系统镜像,这里在filesystem images里面选择如下,意思是使压缩文件系统(lz4),内核启动时解析文件系统。

怎么学嵌入式虚拟化技术 嵌入式 模拟_怎么学嵌入式虚拟化技术_08

其他配置先保持默认,有需要我们再修改

执行make savedefconfig命令,就会生成新的 defconfig 文件,然后执行make命令(执行make时会连接网络下载相关资源,注意网络畅通)

怎么学嵌入式虚拟化技术 嵌入式 模拟_文件系统_09

(3)编译kernel

  代码下载:

git clone https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git

  不推荐使用上面的方法,下载太慢了,可以在网上直接搜相关镜像下载,这里我使用正点原子提供的kernel作为演示,使用imx的配置文件imx_v7_defconfig

然后把上面buildroot编译的文件系统拷贝过来

cp /opt/buildroot/output/images/rootfs.cpio .
 make ARCH=arm  vexpress_defconfig
 make ARCH=arm  menuconfig

怎么学嵌入式虚拟化技术 嵌入式 模拟_git_10

怎么学嵌入式虚拟化技术 嵌入式 模拟_文件系统_11

make ARCH=arm CROSS_COMPILE=/交叉编译器路径/bin/arm-linux-gnueabihf-  -j8

注意:上面一定要指定架构为arm架构

(4)系统启动

下面我们模仿sd卡启动过程

制作sd卡镜像:

dd if=/dev/zero of=sd.img bs=4096 count=4096
mkfs.vfat sd.img

把编译好的 kernel zImage 和 dtb 文件拷贝到 sd.img 中

mount sd.img /mnt/ -o loop,rw
cp arch/arm/boot/zImage /mnt/
cp arch/arm/boot/dts/vexpress-v2p-ca9.dtb /mnt/
umount /mnt

启动qemu

qemu-system-arm -M vexpress-a9 -m 512M -kernel ../u-boot/u-boot -nographic  -sd sd.img

可以看到uboot启动了:

怎么学嵌入式虚拟化技术 嵌入式 模拟_开发板_12

但是没有找到内核,我们还需要下面的操作

查看内核执行地址相对内存的偏移地址:0x8000

怎么学嵌入式虚拟化技术 嵌入式 模拟_开发板_13

在 u-boot 命令行中输入bdinfo命令,可以查到这块开发板内存的起始地址:

怎么学嵌入式虚拟化技术 嵌入式 模拟_git_14

//读取内核文件到开发板内存中
fatload mmc 0:0 0x62008000 zImage
fatload mmc 0:0 0x64008000 vexpress-v2p-ca9.dtb

//启动内核
bootz 0x62008000 - 0x64008000

怎么学嵌入式虚拟化技术 嵌入式 模拟_文件系统_15

(四) 总结

  通过上面的操作我们完成了模拟内核启动的流程,有几个问题也折腾了好久说一下注意的几点:

(1)编译uboot、kernel时注意架构的选择

(2)在内核启动不成功,可能是sd.img没有制作成功

  当然qemu并不能完全替代开发板,更多的功能可以自己发掘哈哈~