构建QEMU使用的嵌入式Linux系统

0. 声明
基于QEMU虚拟vexpress-a9
1. 准备工作
需要安装
交叉编译工具链,本人使用gcc-linaro-7.2.1-2017.11-rc1-x86_64_arm-linux-gnueabi
QEMU
安装后需要配置好环境变量。
需要获取
U-Boot源码
Linux Kernel源码
Busybox源码
2. U-Boot源码编译
2.1 源码修改
有一个问题,和构建环境有关。就是说,你在MenuConfig里配置了BOOT_ARGUMENT后无法成功设置bootargs环境变量。
打开文件 {U-Boot_Dir}/include/configs/vexpress_common.h:152
把bootargs设置为应该设置的参数(具体启动参数的内容同下文)。
2.2 配置并编译U-Boot
进入U-Boot源码目录,在终端中输入
进行vexpress-a9的默认配置
在配置结束后输入
进入menuconfig,在之中找到Boot options,并进入
选中Enable a default value of bootcmd并设置bootcmd为
上述代码为U-Boot三行命令,以分号分割,分别加载了zImage内核镜像到内存,加载设备树到内存,并且从内存引导启动zImage。
并且设置boot argument为
配置完后保存退出。
配置完后进行U-Boot的编译。在终端中输入
其中-j8指明了多核。可以提升编译速度。
编译完成后将会在U-Boot目录出现U-Boot文件。
3. Linux 内核编译
进入Linux内核源码目录。在Shell中执行
之后进入menuconfig进行进一步的配置。
按需配置并退出,在这里Leo酱没有做什么修改。
接下来进行编译。
编译完成后会在arch/arm/boot目录中生成zImage,在arch/arm/boot/dtb目录中找到设备树文件vexpress-v2p-ca9.dtb
4 构建文件系统
4.1 创建空白磁盘镜像并分区
使用
创建一个512M的空白磁盘镜像 sd.img,并对其进行分区
在fdisk命令行中,输入n新建分区,新建分区时会依次要求输入分区类型(主磁盘分区或是拓展分区MS-DOS分区表),选择主分区,然后要求输入分区号,这些都使用默认值即可。
接下来要求你输入起始扇区与结束扇区,起始扇区可以紧接上一个扇区,使用默认值。结束扇区可以使用诸如+32M的方式指定大小。分区结束后输入w写入更改,Leo酱创建了一个32M的boot分区,剩下的空间创建为根目录的分区。
4.2 使用回环设备挂载img并格式化虚拟磁盘
使用kpartx,输入
如果成功,会提示诸如

接下来可以针对每一个分区,进行格式化。
将第一个分区格式化为FAT,第二个分区格式化为EXT4
其中第二行的-L选项指定了卷标,不是必须
接下来可以新建两个目录挂载这两个分区,在此Leo酱新建了boot和rootfs目录分别挂载第一个分区和第二个分区。创建好挂载点后进行挂载。
将zImage内核镜像和设备树文件复制到第一个分区的根目录中。(注意root权限)
在第二个分区需要构建文件系统,可以使用buildroot或者使用busybox自己构建。这里演示如何使用busybox构建一个简单可用的文件系统.
4.3 编译Busybox
进入busybox的源码目录,在Shell中输入
进入menuconfig,在菜单中选择busybox包含的功能,配置完毕后保存退出。在此Leo酱没有做任何修改。
配置后进行编译
编译之后会在源码目录中生成busybox
4.4 制作文件系统
进入挂载后的rootfs目录,创建如下目录
我们先构建最小的可以运行的Linux,因此并不搬移任何运行库。
将busybox放入bin目录并做链接。
在这一步可以链接更多的Linux工具,取决于busybox中所启用的功能。在此不一一列出。
进入etc目录,创建文件inittab,写入如下内容
第一行指明开机执行rcS,第二行指明启动后按下Enter键进入sh
创建开机启动脚本/etc/init.d/rcS并写入
创建/etc/fstab文件并写入
创建/etc/profile,用于开机后设置环境变量,写入
此时,已经搭建出一个可以支持系统使用的文件系统了。
将目录卸载,并卸载磁盘镜像。
5 使用QEMU模拟系统运行
在Shell中输入
并执行。即可启动QEMU,如果成功,将会看到如下结果

按下Enter,进入Shell。

说明运行成功,可以在此虚拟机上测试ARM Linux应用程序,其实更主要的作用是可以进行Linux系统的学习。学习用。
需要注意的是,加了-nographic选项的命令行是无法按Ctrl+C退出的,想要退出QEMU返回Shell,可以先按Ctrl+A再按X,即可退出,就和minicom一样。