一、为什么需要ARM模拟系统
ARM平台的软件开发工作,可以划分为2类:
- 应用程序的开发
- 系统开发(内核、文件系统、驱动程序)
1、应用程序的开发
我们在开发嵌入式项目的时候,一般都是先在x86平台上把大部分的功能开发完成,然后再交叉编译,得到在ARM平台的可执行程序或者库文件。再通过scp指令或者NFS远程挂载的方式,把这些文件复制到ARM板子上之后执行。
一般而言,应用程序就是利用硬件产品的各种资源、外设,来完成特定的功能,比如:数据采集、控制外部设备、网络传输等等。主要的特征就是与外部的各种设备进行交互。
2、系统开发(BSP)
系统开发的最终目的是:为应用程序的执行准备一个基本的执行环境,内容包括:系统引导程序bootloader,内核kernel,文件系统rootfs,系统中所有设备的驱动程序。在实际的项目开发中,系统开发难度更大一些,一旦开发完成,对于一块板子来说基本上不会轻易变动,代码的使用生命周期更长。
以上这两种分类,主要是从开发工作的内容角度来进行划分的。可以看出:
- 应用程序开发:灵活性更大、需求变动会更多(产品经理或项目经理经常给你改需求)。
- 系统软件开发:需求更稳定、很多代码都是官方提供或者开源的,工作内容就是进行定制、裁剪。
对于系统软件开发来说,如果每次编译出一个bootloader、或者kernel,都上一个ARM开发板进行验证,的确比较麻烦。如果能有一个ARM模拟系统,直接在x86上进行模拟,工作效率就会提高很多。
二、Qemu是什么
Qemu是一个开源的托管虚拟机,通过纯软件来实现虚拟化模拟器,几乎可以模拟任何硬件设备。比如:Qemu可以模拟出一个ARM系统中的:CPU、内存、IO设备等,然后在这个模拟层之上,可以跑一台ARM虚拟机,这个ARM虚拟机认为自己在和硬件进行打交道,但实际上这些硬件都是Qemu模拟出来的。
正因为Qemu是纯软件实现的,所有的指令都要经过它的转换,所以性能非常低。所以在生产环境中,大多数的做法都是配合KVM来完成虚拟化工作,因为KVM是硬件辅助的虚拟化技术,主要负责比较繁琐的CPU和内存虚拟化,而Qemu则负责I/O虚拟化,两者合作各自发挥自身的优势,相得益彰。这部分不是重点,就不具体深入介绍了。
三、Qemu的两种模式
1、用户模式
利用动态代码翻译机制来执行不同主机架构的代码,例如:在x86平台上模拟执行ARM代码,也就是说:我们写一条ARM指令,传入整个模拟器中,模拟器会把整个指令翻译成x86平台的指令,然后在x86的CPU中执行。
2、系统模式
模拟整个电脑系统,利用其它VMM(Xen, KVM)来使用硬件提供的虚拟化支持,创建接近于主机性能的全功能虚拟机。
四、Qemu 能做什么
因为Qemu是使用纯软件模拟的,它的强项是模拟那些不涉及到外部的具体硬件设备的场景,比如:
-
想学习如何定制bootloader
-
想在Arm系统中进行文件系统的裁剪,学习文件系统的挂载过程
-
想体验一下如何配置、裁剪linux kernel; 想学习Linux系统中的设备树
五、使用Qemu虚拟机的几种选择
1、简单方式
直接下载别人编译好的映像文件(包含了内核,根文件系统),直接执行即可。
缺点是:别人编译好的也许不适合你的需求,没法定制。
2、复杂方式
自己下载内核代码、根文件系统代码(例如:busybox),然后进行编译。
优点是:可以按照自己的实际需求,对内核、根文件系统机型裁剪。
复杂模式中,又可以有2个选择:
- 内核代码、根文件系统代码全部自己手动编译,最后把这些编译结果手动组织在一个文件夹中,形成自己的根目录;
- 利用 buildroot 整个框架,只需要手动进行配置(比如:交叉编译器在本机上的位置、输出路径、系统的裁剪),然后就可以一键编译出一个完整的系统,可以直接烧写到机器!
以上这几种操作方式的选择,可以根据自己的实际需要来选择。如果对构建系统的整个流程已经非常熟悉了,就利用buildroot工具;如果是想更彻底的学习制作一个系统,那就手动一步一步的实际编译、操作一遍,多练几次,你就变成大牛了。