i.MX8MM处理器采用了先进的14LPCFinFET工艺,提供更快的速度和更高的电源效率;四核Cortex-A53,单核Cortex-M4,多达五个内核 ,主频高达1.8GHz,2G DDR4内存、8G EMMC存储。千兆工业级以太网、MIPI-DSI、USB HOST、WIFI/BT、4G模块、CAN、RS485等接口一应俱全。H264、VP8视频硬编码,H.264、H.265、VP8、VP9视频硬解码,并提供相关历程,支持8路PDM接口、5路SAI接口、2路Speaker。系统支持Android9.0(支持获取root限)Linux4.14.78+Qt5.10.1、Yocto、Ubuntu20、Debian9系统。适用于智能充电桩,物联网,工业控制,医疗,智能交通等,可用于任何通用工业和物联网应用、
【公众号】迅为电子
【粉丝群】258811263
第五篇 文件系统构建篇
配套资料在网盘资料的“iTOP-i.MX8MM开发板\02-i.MX8MM开发板网盘资料汇总(不含光盘内容)\嵌入式Linux开发指南(iTOP-i.MX8MM)手册配套资料\4.文件系统构建配套资料\4 Buildroot文件系统构建配套资料”路径下。
编译环境 :Ubuntu 16.04
文件系统通常要包含很多第三方软件,比如 busybox,udhcpc,tftp,apache,sqlite,PHP,iptable,DNS 等,为了避免繁杂的移植工作。buildroot 应运而生。这一章节我们来学习通过 Buildroot 构建文件系统。
第七十四章 buildroot构建文件系统
74.1 buildroot 简介
Buildroot 是一组 Makefile 和 Patch 文件,用来简化和自动化为嵌入式系统建造一个完整和可引导的 Linux 环境的过程,特别是在使用交叉编译来允许在单一的基于 Linux 的开发系统上为多个目标平台进行建 造的时候。Buildroot 可以自动建造所需要的交叉编译工具链,创建根文件系统,编译一个 Linux 内核映像, 并为目标嵌入式系统生成引导装载器,它还可以进行这些独立步骤的任何组合。例如可以独立的使用已经安 装好的交叉编译工具链,而只用 Buildroot 创建根文件系统。 Buildroot 主要意图用于小型或嵌入式系统,它们基于各种计算机体系结构和指令集之上,包括 x86、 ARM、MIPS 和 PowerPC。不仅支持大量的架构及其变体,Buildroot 还随带了针对一些现成的嵌入式开发板 的缺省配置,比如 Cubieboard 页面存档备份,存于互联网档案馆、Raspberry Pi 等。一些第三方项目和产 品使用 Buildroot 作为其建造系统的基础,包括创建了嵌入式操作系统的 OpenWrt 计划,和 Google Fiber 宽带服务所用的用户驻地设备的固件。 支持多个 C 标准库作为工具链的一部分,包括 GNU C 函数库、uClibc 和 musl,当然还有属于各种预配 置的开发环境的 C 标准库,比如 Linaro 所提供的库。Buildroot 的建造配置系统内部使用了 Kconfig,它 提供了一些特征,比如菜单驱动界面,依赖性处理,上下文有关帮助;Kconfig 也被 Linux 内核用于自身的 源代码层面配置。Buildroot 围绕大量自动下载的软件包而进行组织,这包含了各种用户空间应用、系统实用工具和函数库的源代码。作为最终结果的根文件系统映像,可以使用各种文件系统建造,包括 cramfs、 JFFS2、romfs、SquashFS 和 UBIFS。 Buildroot 是自由及开放源代码软件,由 Peter Korsgaard 维护并在 GNU 通用公共许可证(GPL)版本 2 及以后版本下发行。这个项目开始于 2001 年,最初意图用作 uClibc 的测试台。每三个月提供新的发行。
74.2 buildroot 编译环境
通过查看官方手册可知构建系统需要的工具有如下图所示,这些工具需要我们在 ubuntu虚拟机上安装。官方手册地址:https://buildroot.org/downloads/manual/manual.html#requirement
我们需要安装这些编译必须工具,不然编译过程,会出错。我们可以使用以下命令来安装这些工具,安装过程如下图:
apt install -y sed make binutils build-essential gcc g++ patch gzip bzip2 perl tar cpio unzip rsync file bc wget
由于作者已经安装过了,所以不会出现安装提示,读者第一次安装按提示进行。如果需要使用1.6节以后的第三方工具包,请使用下述命令安装所有可选软件包。这一步的目的是防止编译时报错。
apt install -y wget python libncurses5 bzr cvs git mercurial rsync subversion libelf-dev
安装完编译所需的软件包后,就可以开始编译构建 buildroot了。
74.3 设置交叉编译器
我们将网盘资料“iTOP-i.MX8MM开发板\02-i.MX8MM开发板网盘资料汇总(不含光盘内容)\嵌入式Linux开发指南(iTOP-i.MX8MM)手册配套资料\4.文件系统构建配套资料\4 Buildroot文件系统构建配套资料\2_编译脚本和交叉编译器”目录下的编译器gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu.tar压缩包拷贝到Ubuntu的usr/local/目录下,如下图所示:
然后输入以下命令解压:
tar -vxf gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu.tar
解压完毕,我们进入交叉编译器的目录,如下图所示,注意,这里要记住编译器的路径/usr/local/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu ,后面会用到的。
74.4 使用提供的配置文件进行编译(推荐)
为了大家方便使用,我们提供了配置好以下章节配置功能的源码和配置文件.config,大家可以直接使用。对应配套的资料在网盘资料“iTOP-i.MX8MM开发板\02-i.MX8MM开发板网盘资料汇总(不含光盘内容)\嵌入式Linux开发指南(iTOP-i.MX8MM)手册配套资料\4.文件系统构建配套资料\4 Buildroot文件系统构建配套资料\9_配置好功能的buildroot源码及烧写镜像”路径下。
使用方法:
用户使用配置好的buildroot源码拷贝到ubuntu,解压后执行 “make menuconfig ”可以在此基础上进行配置文件系统。然后再执行 “make” 就能生成文件系统压缩包镜像,放在output目录中。使用配置好的buildroot源码就可以跳过下面的章节,直接烧写测试。
74.5从零开始编译buildroot
我们可以选择上一小节提供的配置好的源码进行配置文件系统,也可以根据以下章节在buildroot官方源码的基础上从0开始配置。接下来我们就开始学习怎样一步一步配置buildroot。
74.5.1 获取Buildroot
请使用浏览器打开 buildroot 官方下载页面 https://buildroot.org/download.html ,打开后,选择长期支持发布版 我这里目前是 2021.05 版本,为了保证下述操作一致,我们统一都使用同一个版本。
点击buildroot-2021.05.tar.bz2 进行下载。下载好之后使用samba 上传到ubuntu虚拟机。在用户目录下新建文件夹buildroot。将buildroot-2021.05.tar.bz2拷贝到该目录,如下图所示:
我们下载的版本为长期支持版buildroot-2021.05,这里有.gz和.bz2 两种压缩格式,这里我就使用右侧的.bz2 压缩格式的源码,选中以后下载即可。
在我们的资料中“iTOP-i.MX8MM开发板\02-i.MX8MM开发板网盘资料汇总(不含光盘内容)\嵌入式Linux开发指南(iTOP-i.MX8MM)手册配套资料\4.文件系统构建配套资料\4 Buildroot文件系统构建配套资料\1_Buildroot文件系统”会提供这个压缩包,如下图所示:
74.5.2 配置及编译Buildroot
首先我们切换到root用户,使用命令“mkdir buildroot”创建该文件夹,本章节所有步骤均在此文件夹下进行。如下图所示:
然后我们通过SSH软件将刚才下载的“buildroot-2021.05.tar.bz2”传到ubuntu环境下刚才创建的文件夹。
接着我们使用命令“cd buildroot/”进入该文件夹。如下图所示:
然后使用命令“tar xvf buildroot-2021.05.tar.bz2”解压。如下图所示:
- 然后使用命令“cd buildroot-2021.05”进入源码目录。如下图所示:
- Buildroot支持图形化配置。我们使用命令“make menuconfig”,配置buildroot。如下图所示:
首先回车选择 Target options 选项,如下图所示:
74.5.2.1 配置 Target options
首先配置 Target options 选项,目标选项。包括处理器体系结构、二进制文件格式、架构系列、浮点运算。对应到我这里使用的IMX8MM,它的CPU架构是cortex-A53架构需要配置的项目和其对应的内容如下:
Target options
-> Target Architecture = AArch64 (little endian) (小端模式)
-> Target Binary Format = ELF (二进制格式是ELF)
-> Target Architecture Variant = cortex-A53 (CPU是a53)
-> Floating point strategy =FP-ARMv8 (浮点处理采用FP-ARMv8 )
74.5.2.2 配置 Toolchain
此配置项用于配置交叉编译工具链,也就是交叉编译器,这里设置为buildroot自带的交叉编译器即可。make menuconfig的配置如下图所示:
Toolchain type (External toolchain) ---> *** Toolchain External Options *** Toolchain (Custom toolchain) ---> Toolchain origin (Pre-installed toolchain) ---> (/usr/local/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu) Toolchain path (aarch64-linux-gnu) Toolchain prefix External toolchain gcc version (7.x) ---> External toolchain kernel headers series (4.14.x) ---> External toolchain C library (glibc/eglibc) ---> [*] Toolchain has SSP support? [*] Toolchain has SSP strong support? [*] Toolchain has RPC support? [*] Toolchain has C++ support? [ ] Toolchain has D support? [ ] Toolchain has Fortran support? [ ] Toolchain has OpenMP support? [ ] Copy gdb server to the Target *** Host GDB Options *** [ ] Build cross gdb for the host *** Toolchain Generic Options *** [ ] Copy gconv libraries () Extra toolchain libraries to be copied to target [*] Enable MMU support () Target Optimizations () Target linker options [ ] Register toolchain within Eclipse Buildroot plug-in
主要注意以下几处:
Toolchain type是工具链类型,这里有buildroot自带的和外部我们自己添加两种选择,我们选择External toolchain,自己添加。
GCC compiler Version (gcc 7.x)选用 GCC版本7.X
C library (glibc) c库选择带glibc的(glibc/eglibc)
74.5.2.3 配置 System configuration
然后使用方向键选择exit回到“buildroot-2021.05 Configuration”界面。方向键向下,回车进入“System configuration”选项,如下图所示:
配置系统信息,如下。
主要注意以下几处。
System hostname系统名
System banner系统欢迎语,这两处自行定义
Init system 中选择 systemV
/dev management 中选择Dynamic using devtmpfs + eudev ,即使用devtmpfs + eudev动态加载设备节点的方式。
Path to the permission tables中选择设备节点的配置表,这里我们一定要选择system/device_table_dev.txt,否则后面在dev目录下将不会生成各种设备节点。当然我们也可以手动的配置该文件,添加必要的节点或删除不需要的节点。
Enable root login with password密码登录root
Root password添加密码
如下图所示:
选择Run a getty (login prompt) after boot,配置如下。
--- Run a getty (login prompt) after boot
(/dev/ttymxc1) TTY port
Baudrate (115200) --->
(vt100) TERM environment variable
() other options to pass to getty
TTY port修改为“/dev/ttymxc1”
Baudrate波特率选择115200
如下图所示:
74.5.2.4 配置 Filesystem images
然后方向键选择exit回到“buildroot-2021.05 Configuration”界面。方向键向下,回车进入“Filesystem images”选项,如下图所示:
然后配置镜像格式,如下。
[ ] axfs root filesystem
[ ] btrfs root filesystem
[ ] cloop root filesystem for the target device
[ ] cpio the root filesystem (for use as an initial RAM filesystem)
[ ] cramfs root filesystem
[ ] ext2/3/4 root filesystem
[ ] f2fs root filesystem
*** initramfs needs a Linux kernel to be built ***
[ ] jffs2 root filesystem
[ ] romfs root filesystem
[ ] squashfs root filesystem
[*] tar the root filesystem
Compression method (bzip2) --->
() other random options to pass to tar
[ ] ubi image containing an ubifs root filesystem
[ ] ubifs root filesystem
[ ] yaffs2 root filesystem
选择这里选项会生成不同格式的镜像文件,我们需要保证一下两个选项配置上:
tar the root filesystem打开文件系统
Compression method(bzip2)压缩为bz2格式
如下图所示:
74.5.2.5 禁止编译 Linux 内核和 uboot
由于从网上下载内核源码和uboot然后编译他们比较耗费时间,而且新下载的内核源码,与uboot没有我们开发板的配置信息,所以需要禁用它们。
禁止 Linux 内核的编译,配置如下:
> Kernel
-> [ ] Linux Kernel //不要选择编译 Linux Kernel 选项!
接着禁止编译 Uboot,配置如下:
-> Bootloaders
-> [ ] U-Boot //不要选择编译 U-Boot 选项!
74.5.2.6 配置 Target packages
此选项用于配置要选择的第三方库或软件、比如 alsa-utils、iperf 等工具,但是现在我们先不选择第三方库,先编译一下最基本的根文件系统,如果没有问题的话再重新配置选择第三方库和软件。否则编译出问题的时候都不知道怎么找问题。
接下来重要的一步检查自己的交叉编译,默认支持的内核版本。输入命令:
vi ./aarch64-linux-gnu/libc/usr/include/linux/version.h
打开version.h文件,LINUX_VERSION_CODE为267277,此值为10进制,转换为16进制为4140D,对应的linux内核版本为4.1.x,在此要把该值改为与buildroot中配置的一致,即为4.14.x,转换为16进制为40E4E,对应的十进制为265806。(如果Linux_VERSION_CODE与内核版本不一致,会导致编译报错)。修改为如下图所示:
74.5.2.6 保存配置文件
然后方向键选择exit回到“buildroot-2021.05 Configuration”界面。方向键选择Save,ok保存,exit退出,如下图所示:
74.5.3 编译文件系统
接着我们使用命令“make”编译buildroot,期间他会自行下载一些软件源码,请保证网络可用。如下图所示:
最后编译完成,如图所示:
我们使用命令“ls /home/topeet/buildroot/buildroot-2021.05/output/images/”即可看到编译出来的文件系统。
74.5.4 修改编译脚本
在上一章节,我们已经编译成功buildroot系统,我们需要把编译好的文件系统编译成镜像,然后再烧写镜像。然后在linux源码目录下,新建一个buildroot文件夹,在文件夹中拷贝好上面编译好的压缩包rootfs.tar.bz2,拷贝完毕如下图所示:
然后我们输入以下命令,解压文件系统,如下所示:
解压完如下图所示,然后删除rootfs.tar.bz2。
然后将网盘资料“iTOP-i.MX8MM开发板\02-i.MX8MM开发板网盘资料汇总(不含光盘内容)\嵌入式Linux开发指南(iTOP-i.MX8MM)手册配套资料\4.文件系统构建配套资料\4 Buildroot文件系统构建配套资料\2_编译脚本和交叉编译器”目录下的build.sh编译脚本替换原来linux源码中的编译脚本。
最后输入以下命令编译buildroot系统,如下图所示:
74.5.5 最简文件系统测试
buildroot这个文件系统所需的uboot、内核、设备树均使用之前编译的,我们将编译出来的镜像拷贝到烧写工具内。
将开发板拨码切换成烧写模式,上电烧写,等待烧写完成。上电启动。
输入用户名“root”与密码“topeet”即可进入系统,如下图所示:
74.5.5.1 测试有线网连接
开发板板载了一路千兆以太网接口,首先我们连接网线的一端到 ETHERNET接口,网线另一端连接到路由器,然后开发板上电启动,然后通过调试串口登录到开发板上,如下图所示:
我们输入以下命令将eth0打开,如下图所示:
ifconfig eth0 up
输入以下命令查看网卡信息:
ifconfig
使用DHCP来进行有线网络的配置,如下图所示:
udhcpc -i eth0
然后我们在串口终端输入“ifconfig”命令查看网卡的信息,如下图所示:
然后我们在串口终端输入“ping www.baidu.com”ping 下腾讯的网址,可以看到联网成功,运行结果如下图所示:
74.5.5.2 测试U盘连接
我们在平时测试程序或者传输数据时经常会用到 U 盘,开发板其实和电脑相同,U 盘插入电脑后需要挂载 U 盘,在拔掉 U 盘前需要先卸载。 首先启动开发板,我们将 U 盘插入 USB 口,可以看到开发板打印信息提示。如下图:
然后使用命令“fdisk -l”,我们可以看到,U 盘设备为/dev/sda4,在插入 U 盘是也可以看到这一信息。如下图所示:
接着使用命令“mount /dev/sda4 /mnt/”将 U 盘挂载到“/mnt/”,使用命令“df -Th”命令可以查看挂载的目录,然后使用命令“ls /mnt/” 即可查看 U 盘内容,如下图所示:
挂载之后我们就可以对 U 盘进行其他操作,在使用完毕之后要安全卸载 U 盘,使用命令“umount /dev/sda4”,如下图所示:
74.5.5.3 创建自启动文件
busybox 根文件系统是在/etc/init.d/rcS 里面添加自启动相关命令的,但是 buildroot 构建的根文件系统中是直接在/etc/init.d/rcS 中添加自启动命令,默认情况下 buildroot 构建的根文件系统中 rcS 文件内容如图所示,我们打开/etc/init.d/rcS 文件。
上图中可以看出,rcS 默认会在/etc/init.d 目录下查找所有以‘S’开头的脚本,然后依次执行这些脚本。所以我们可以自己创建一个以‘S’开头的自启动脚本文件,比如我创建一个名为 Sautorun 的自启动文件,命令如下:
cd /etc/init.d/ //进入/etc/init.d 目录
touch Sautorun //使用 touch 命令创建Sautorun脚本
chmod 777 Sautorun //给Sautorun脚本可执行权限
然后在Sautorun脚本里面输入要执行的命令,比如要在根目录创建helloworld文件夹,然后在helloworld文件夹里面创建test文件,那么Shello脚本内容如图所示:
#!/bin/sh
cd /
mkdir helloworld
cd helloworld
touch test
开发板重新上电,文件创建成功,如下图所示:
74.5.5.4 显示主机名
现在我们构建的文件系统,发现输入命令的时候命令行前面一直都是“#”,如果我们进入到某个目录的话前面并不会显示当前目录路径。如下图所示:
但是我们如果想要显示当前所在的路径呢,接下来我们来演示一下。
打开根目录下/etc/profile文件,如下图所示:
如上图所示,PS1 用于设置命令提示符格式,格式如下所示:
PS1 = ‘命令列表’
命令列表参数可以选以下:
\!:显示该命令的历史记录编号。
\#:显示当前命令的命令编号。
\$:显示$符作为提示符,如果用户是 root 的话,则显示#号。
\\:显示反斜杠。
\d:显示当前日期。
\h:显示主机名。
\n:打印新行。
\nnn:显示 nnn 的八进制值。
\s:显示当前运行的 shell 的名字。
\t:显示当前时间。
\u:显示当前用户的用户名。
\W:显示当前工作目录的名字。
\w:显示当前工作目录的路径
我们可以直接修改第二行PS1的值,但是不建议大家这么做,因为后面如果修改了buildroot系统,profile文件就会被覆盖。
我们在/etc/profile.d 目录下新建一个名为“topeetprofile.sh”的 shell 脚本文件,并且给予此文件可执行权限,命令如下:
cd /etc/profile.d
touch topeetprofile.sh
chmod 777 topeetprofile.sh
然后在topeetprofile.sh内容中写下如下内容:
#!/bin/sh
PS1='[\u@\h]:\w$ '
export PS1
这里设置 PS1 环境变量,\u:显示当前用户的用户名,\h:显示主机名,\w:显示当前工作目录的路径。
重启开发板,启动后如下所示:
74.5.5.5 优化系统
进过上面的步骤,相信大家已经用buildroot工具成功制作出最简单的文件系统了,而且我们还学会了创建自启动文件和显示主机名,但是我们后面还会在buildroot中添加功能,rootfs.tar.bz2是变化的,我们总不能每编译一次再修改文件,这样大大降低了效率,为了简化步骤,我们提供了打包脚本pack.sh
脚本内容分如下所示:
我们来解释一下脚本的意思。pack.sh是放在linux源码根目录下的。如下图所示:
脚本意思是首先进入源码根目录下的buildroot文件夹,然后删除里面的文件,然后将buildroot制作的文件系统压缩包拷贝到buildroot文件夹,最后解压缩,删除压缩包。最终,buildroot文件夹的内容如下所示:
然后我们在linux源码的根目录,建立一个over_rootfs文件夹,这个文件夹是放置自己配置好的文件,每次编译完,我们可以用这个文件夹的内容去覆盖解压缩后的文件系统。注意放置文件的路径要一模一样。
如下图所示:
pack.sh脚本的最后俩行,是编译文件系统buildroot。这个脚本大家也可以根据自己的需求自定义。
提供好的pack.sh和over_rootfs在网盘资料“iTOP-i.MX8MM开发板\02-i.MX8MM开发板网盘资料汇总(不含光盘内容)\嵌入式Linux开发指南(iTOP-i.MX8MM)手册配套资料\4.文件系统构建配套资料\4 Buildroot文件系统构建配套资料\3_优化脚本和文件”目录下。