LV05-04-根文件系统-02-Buildroot-03-Buildroot构建rootfs
本文主要是根文件系统——Buildroot构建rootfs的相关笔记,若笔记中有错误或者不合适的地方,欢迎批评指正😃。
点击查看使用工具及版本
PC端开发环境 Windows Windows11 Ubuntu Ubuntu20.04.2的64位版本 VMware® Workstation 17 Pro 17.6.0 build-24238078 终端软件 MobaXterm(Professional Edition v23.0 Build 5042 (license)) Win32DiskImager Win32DiskImager v1.0 Linux开发板环境 Linux开发板 正点原子 i.MX6ULL Linux 阿尔法开发板 uboot NXP官方提供的uboot,使用的uboot版本为U-Boot 2019.04 linux内核 linux-4.19.71(NXP官方提供)
点击查看本文参考资料
分类 网址 说明 官方网站 https://www.arm.com/ ARM官方网站,在这里我们可以找到Cotex-Mx以及ARMVx的一些文档 https://www.nxp.com.cn/ NXP官方网站 https://www.nxpic.org.cn/NXP 官方社区 https://u-boot.readthedocs.io/en/latest/u-boot官网 https://www.kernel.org/linux内核官网
点击查看相关文件下载
分类 网址 说明 NXP https://github.com/nxp-imx NXP imx开发资源GitHub组织,里边会有u-boot和linux内核的仓库 nxp-imx/linux-imx/releases/tag/v4.19.71 NXP linux内核仓库tags中的v4.19.71 nxp-imx/uboot-imx/releases/tag/rel_imx_4.19.35_1.1.0 NXP u-boot仓库tags中的rel_imx_4.19.35_1.1.0 I.MX6ULL i.MX 6ULL Applications Processors for Industrial Products I.MX6ULL 芯片手册(datasheet,可以在线查看) i.MX 6ULL Applications ProcessorReference Manual I.MX6ULL 参考手册(下载后才能查看,需要登录NXP官网) Source Code https://elixir.bootlin.com/linux/latest/source linux kernel源码 https://elixir.bootlin.com/u-boot/latest/source uboot源码
一、文件系统我们回顾一下文件系统的概念:
我们先来看一下Linux是如何存储数据的。一般情况下,字符设备以串行方式存储和获取数据,串口是最典型的字符设备;而块设备会一次存取或者获取大小相同的一块区域内的数据。例如,一个硬 盘控制器可以向物理存储介质上指定可寻址地址,一次传送或接收512字节的数据,文件系统正是建立在块设备之上的。
文件系统是存在于一个物理设备的逻辑分区之上的。分区就是对一个物理介质(磁盘、闪存)的逻辑划分,该物理介质上的数据在给定分区类型上按照特定的规则进行组织,物理设备可以只有一个独立分区包含所有可用空间,也可以被划分为多个分区以满足特定需要,就好比我们电脑的磁盘,划分为多个分区以用于不同的需求。
简单了解了文件系统的概念,那么接下来我们就动手制作一个文件系统。
二、buildroot构建根文件系统文件系统通常要包含很多第三方软件,比如busybox,tslib,qt,vim,交叉编译工具等,为了避免繁杂的移植工作,buildroot应运而生。用户可以直接通过make menuconfig配置自己需要的功能,把不需要的功能去掉,再执行make指令编译,buildroot就会自动从指定的服务器上下载源码包,自动编译,自动搭建成我们所需要的嵌入式根文件系统。
buildroot的文件系统(rootfs)构建流程有一个框架,有些部分是buildroot本身就集成的,但还是有些细节需要自己来实现,我们需要按照格式写脚本,提供必要的构建细节,并且配置整个系统,总之,rootfs是Buildroot中最为复杂的部分。
一般来说,buildroot构建文件系统的运作过程如下:
(1)buildroot将system/skeleton/目录下的内容拷贝到output/target目录下下作为rootfs的模板。
(2)将output/staging/目录下的工具链中动态库拷贝到output/target/对应的目录下。
(3)分别编译每一个应用的package,并将生成的动态库和bin文件install到output/target/对应的目录下。
(4)将package/initscripts/目录下的系统启动脚本install到output/target/对应的目录下。
(5)构建fakeroot环境,在fakeroot环境下修改output/target/中对应的目录文件权限,制作dev节点,并根据用户的配置制作出rootfs 镜像。
fakeroot是一个主机上使用的软件包,它会被buildroot下载编译,用于为构建rootfs提供一个虚拟的root权限环境,只有在root权限下,才能把output/target/中的目录和文件变成root用户,并创建dev节点。有了fakeroot环境,系统构建者无需获取主机的root权限, 也能在fakeroot下把文件改为root用户,并制作root方式。
三、buildroot配置1. 打开配置界面buildroot 和 uboot、 Linux kernel 一样也支持图形化配置,输入如下命令即可打开图形化配置界:
12make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfigmake menuconfig # 好像也可以这样用,因为这里只是配置,后边编译的话会自动使用交叉编译工具链
然后就会打开图形配置界面,如下所示:
2. 配置buildboot2.1 配置 Target options 首先配置 Target options 选项,需要配置的项目和其对应的内容如下(“=”号后面是配置项要选择的内容 ):
1234567Target options -> Target Architecture = ARM (little endian) -> Target Architecture Variant = cortex-A7 -> Target ABI = EABIhf -> Floating point strategy = NEON/VFPv4 -> ARM instruction set = ARM -> Target Binary Format = ELF
如下所示:
123456789101112131415161718 /home/sumu/7Linux/buildroot-2023.05.1/.config - Buildroot 2023.05.1 Configuratio→ Target options ───────────────────────────────────────────────────────────── ┌──────────────────────────── Target options ─────────────────────────────┐ │ Arrow keys navigate the menu.
2.2 配置 Toolchain 此配置项用于配置交叉编译工具链,也就是交叉编译器,这里设置为我们自己所使用的交叉编译器即可。 buildroot 其实是可以自动下载交叉编译器的,但是都是从国外服务器下载的,鉴于国内的网络环境,强烈建议设置成自己所使用的交叉编译器。需要配置的项目和其对应的内容如下:
12345678910111213Toolchain -> Toolchain type = External toolchain -> Toolchain = Custom toolchain # 用户自己的交叉编译器 -> Toolchain origin = Pre-installed toolchain # 预装的编译器 -> Toolchain path =/home/hk/2software/gcc-linaro-4.9.4 -> Toolchain prefix = $(ARCH)-linux-gnueabihf # 前缀 -> External toolchain gcc version = 4.9.x -> External toolchain kernel headers series = 4.1.x -> External toolchain C library = glibc/eglibc -> [*] Toolchain has SSP support? (NEW) # 选中 -> [*] Toolchain has RPC support? (NEW) # 选中 -> [*] Toolchain has C++ support? # 选中 -> [*] Enable MMU support (NEW) # 选中
Toolchain 下几个比较重要的选项需要说明一下,如下所示:
Toolchain:设置为 Custom toolchain,表示使用用户自己的交叉编译器。
Toolchain origin:设置为 Pre-installed toolchain,表示使用预装的交叉编译器。
Toolchain path:设置自己安装的交叉编译器绝对路径! buildroot 要用到。
Toolchain prefix:设置交叉编译器前缀,要根据自己实际所使用的交叉编译器来设置,比如我们使用的是 arm-linux-gnueabihf-gcc,因此前缀就是$(ARCH)-linux-gnueabihf,其中 ARCH我们前面已经设置为了 arm。
配置完后图形界面如下所示:
123456789101112131415161718192021222324252627282930313233343536 /home/sumu/7Linux/buildroot-2023.05.1/.config - Buildroot 2023.05.1 Configuratio→ Toolchain ────────────────────────────────────────────────────────────────── ┌─────────────────────────────── Toolchain ───────────────────────────────┐ │ Arrow keys navigate the menu.
需要注意一下我后来升级了交叉编译工具链版本和内核版本,这里界面菜单中的东西就跟着改了一下。
2.3 配置 System configuration此选项用于设置一些系统配置,比如开发板名字、欢迎语、用户名、密码等。需要配置的项目和其对应的内容如下:
1234567System configuration -> System hostname = alpha_imx6ull # 平台名字,自行设置 -> System banner = Welcome to alpha i.mx6ull # 欢迎语 -> Init system = BusyBox # 使用 busybox -> /dev management = Dynamic using devtmpfs + mdev # 使用 mdev -> [*] Enable root login with password (NEW) # 使能登录密码 -> Root password = 123456 # 登录密码为 123456
在 System configuration 选项中可以配置平台名字,登录密码等信息。如下所示:
123456789101112131415161718192021222324252627282930313233343536373839 /home/sumu/7Linux/buildroot-2023.05.1/.config - Buildroot 2023.05.1 Configuratio→ System configuration ─────────────────────────────────────────────────────── ┌───────────────────────── System configuration ──────────────────────────┐ │ Arrow keys navigate the menu.
2.4 配置 Filesystem images 此选项配置我们最终制作的根文件系统为什么格式的,配置如下:
1234-> Filesystem images -> [*] ext2/3/4 root filesystem # 如果是 EMMC 或 SD 卡的话就用 ext3/ext4 -> ext2/3/4 variant = ext4 # 选择 ext4 格式 -> [*] ubi image containing an ubifs root filesystem # 如果使用 NAND 的话就用 ubifs
对于 I.MX6U 来说此选项不用配置,因为我们是通过 Mfgtool 工具将根文件系统烧写到开发板上的 EMMC/SD 卡中,烧写的时候需要自己对根文件系统进行打包。
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950 /home/sumu/7Linux/buildroot-2023.05.1/.config - Buildroot 2023.05.1 Configuratio→ Filesystem images ────────────────────────────────────────────────────────── ┌─────────────────────────── Filesystem images ───────────────────────────┐ │ Arrow keys navigate the menu.
2.5 禁止编译 Linux 内核和 uboot buildroot 不仅仅能构建根文件系统,也可以编译 linux 内核和 uboot。当配置 buildroot,使能 linux 内核和 uboot 以后 buildroot 就会自动下载最新的 linux 内核和 uboot 源码并编译。但是我们一般都不会使用 buildroot 下载的 linux 内核和 uboot,因为 buildroot 下载的 linux 和 uboot官方源码,里面会缺少很多驱动文件,而且最新的 linux 内核和 uboot 会对编译器版本号有要求,可能导致编译失败。因此我们需要配置 buildroot,关闭 linux 内核和 uboot 的编译,只使用buildroot 来构建根文件系统, 首先是禁止 Linux 内核的编译, 配置如下:
1234-> Kernel -> [ ] Linux Kernel # 不要选择编译 Linux Kernel 选项!-> Bootloaders -> [ ] U-Boot # 不要选择编译 U-Boot 选项!
Kernel
12345678910111213141516 /home/sumu/7Linux/buildroot-2023.05.1/.config - Buildroot 2023.05.1 Configuratio→ Kernel ───────────────────────────────────────────────────────────────────── ┌──────────────────────────────── Kernel ─────────────────────────────────┐ │ Arrow keys navigate the menu.
Bootloaders
1234567891011121314151617181920212223 /home/sumu/7Linux/buildroot-2023.05.1/.config - Buildroot 2023.05.1 Configuratio→ Bootloaders ──────────────────────────────────────────────────────────────── ┌────────────────────────────── Bootloaders ──────────────────────────────┐ │ Arrow keys navigate the menu.
2.6 配置 Target packages 此选项用于配置要选择的第三方库或软件、比如 alsa-utils、 ffmpeg、 iperf 等工具,但是现在我们先不选择第三方库,防止编译不下去!先编译一下最基本的根文件系统,如果没有问题的话再重新配置选择第三方库和软件。一次性配置太多的花,编译出问题的时候都不知道怎么找问题。
3. 编译 buildroot配置完成以后就可以编译 buildroot 了,编译完成以后 buildroot 就会生成编译出来的根文件系统压缩包,我们可以直接使用。输入如下命令开始编译:
1sudo make # 注意,一定要加 sudo,而且不能通过-jx 来指定多核编译!!!
buildroot 编译的时候会先从网上下载所需的软件源码,有些软件源码可能下载不下来,这个时候就需要我们自行处理,这个后边再说。buildroot 编译过程会很耗时,可能需要几个小时,这个时候耐心等待!buildroot 因为要从网上下载源码,因此可能存在有些源码无法下载或下载很慢的情况。
3.1 下载出错怎么办?如下所示:
比如说这个,就会下载失败,出现下载失败或者下载很慢怎么办?我们可以根据下载链接,自己科学上网一下,下载好放到buildroot源码目录的dl目录下,dl 文件夹专用用于存放下载下来的源码。 就比如上边的这个,我们可以点击这个链接:
1http://sources.buildroot.net/e2fsprogs/e2fsprogs-1.46.5.tar.xz
直接下载好压缩包,将它放到dl目录下:
然后我们再重新执行make命令就可以了。
3.2 kernel headers报错
我的解决办法就是修改配置:
12Toolchain -> External toolchain kernel headers series = 4.0.x
修改这里的External toolchain kernel headers series版本,改成了4.0.x。
3.3 新版本的一个问题之前下载了一个2024.8-rc3的版本,执行make命令:
1sudo make
需要加sudo,否则报错:
然后还会有这样一个报错:
说是要这样解决:
12echo "export set FORCE_UNSAFE_CONFIGURE=1" >> /etc/profilesource /etc/profile
但是还是有问题,没解决掉,后来换回这个版本了:
1https://buildroot.org/downloads/buildroot-2023.05.1.tar.gz
3.4 编译成功不出意外的话应该是可以编译成功的,没有什么特别的提示信息,只要不报错即可。
3.4 根文件系统测试编译结束后,会在buildroot源码目录的output目录中生成根文件系统:
可以看出,编译出来了多种格式的 rootfs,比如 ext2、 ext4、 ubi 等。其中rootfs.tar 就是打包好的根文件系统,我们就使用 rootfs.tar 进行测试。在 nfs 目录下新建一个名为 buildrootfs 的文件夹 ,然后将rootfs.tar 拷贝到 buildrootfs 目录下并解压,命令如下:
12345mkdir -p ~/4nfs/buildrootcp ~/7Linux/buildroot-2023.05.1/output/images/rootfs.tar ~/4nfs/buildrootcd ~/4nfs/buildroottar -xf rootfs.tarrm rootfs.tar
然后修改uboot的bootargs参数:
12=> setenv bootargs 'console=ttymxc0,115200 root=/dev/nfs nfsroot=192.168.10.101:/home/sumu/4nfs/buildroot,proto=tcp rw ip=192.168.10.102:192.168.10.101:192.168.10.1:255.255.255.0::eth0:off init=/linuxrc'=> saveenv
然后重启就可以啦,要是制作没问题的话,是可以挂载成功的。首先要进入到/lib/modules 目录,但是默认没有,因此需要我们自行创建此目录。 buildroot 构建的根文件系统启动以后会输出我们前面设置的欢迎语“Welcome to alphai.mx6ull”。然后需要输入用户名和密码,用户名是“root”,密码就是我们前面配置 buildroot 的时候设置的 “123456” 。输入用户名和密码以后就可以进入系统中:
可以看出的 buildroot 构建的根文件系统运行基本没有问题,但是这个根文件系统是最简单的,我们并没有在 buildroot 里面配置任何第三方的库和软件,接下来我们就配置 buildroot,使能一些常见的第三方软件。
四、buildroot下的busybox1. busybox 配置 buildroot 在构建根文件系统的时候也是要用到 busybox 的,既然用到了 busybox 那么就涉及到 busybox 的配置。 buildroot 会自动下载 busybox 压缩包, buildroot 下载的源码压缩包都存放在/dl 目录下,在 dl 目录下就有一个叫做“busybox”的文件夹,此目录下保存着 busybox 压缩包 :
可以看出, buildroot 下载的 busybox 版本为 1.36.1。要想编译 busybox,必须对图中的压缩包进行解压缩, buildroot 将所有解压缩后的软件保存在buildroot源码目录的 output/build 中,我们可以在找到 output/build/busybox-1.36.1 这个文件夹,此文件夹就是解压后的 busybox 源码,文件内容如下:
如果想要修改 busybox 源码的话就直接在图中找到相应的文件,然后修改即可。我们现在是要配置 buildroot 下的 busybox,因此肯定要打开 busybox 的配置界面,在 buildroot下打开 busybox 的配置界面输入如下命令:
12cd ~/7Linux/buildroot-2023.05.1sudo make busybox-menuconfig
然后就会打开busybox的配置界面:
想要怎么配置直接参考前边的busybox构建根文件系统的笔记即可。
2. 中文支持用buildroot编译出来的根文件系统也是不支持中文的,但是由于它其实使用的是busybox,所以我们可以直接根据前边的busybox构建根文件系统的笔记来修改busybox的源码,使其支持中文,这个可以看后面busybox相关的笔记。
3. 编译busybox配置好以后就可以重新编译 buildroot 下的 busybox,进入到 buildroot 源码目录下,输入如下命令查看当前 buildroot 所有配置了的目标软件包,也就是 packages:
1sudo make show-targets
图中列出了当前 buildroot 中所有使能了的 packages 包,其中就包括 busybox,如果我们想单独编译并安装 busybox 的话执行下面命令即可:
1sudo make busybox
上述命令就会重新编译 busybox。编译完成以后重新编译 buildroot,主要是对其进行打包,输入如下命令:
1sudo make
重新编译完成以后查看一下 output/images 目录下 rootfs.tar 的创建时间是否为刚刚编译的,如果不是的话就删除掉 rootfs.tar,然后重新执行“sudo make”重新编译一下即可。最后我们使用新的 rootfs.tar 启动 Linux 系统。
五、终端配置1. 终端提示符buildroot构建的根文件系统中的命令提示符前边也是不会显示当前路径的:
我们可以,修改一下PS1变量,我们打开buildroot构建出来的根文件系统的 etc/profile文件,找到如下代码:
1234567if [ "$PS1" ]; then if [ "`id -u`" -eq 0 ]; then export PS1='# ' else export PS1='$ ' fifi
我们把它修改成如下的样子:
12PS1='[\u@\h]:\w$:'export PS1
然后我们再重启开发板就会看到命令提示符前边有显示路径啦:
这里有一个网站可以帮助我们生成PS1变量的代码:Easy Bash Prompt Generator,例如这样:
重新修改后就可以得到这样的一个终端啦:
2. 终端宽度当我们输入过长的命令的时候会出现换行的情况:
这是终端的默认长度有问题,可以参考《01嵌入式开发/02IMX6ULL平台/LV02-开发环境/LV02-04-终端配置-01-默认终端长度问题.md》解决。我们打开开发板的/etc/init.d/rcS文件,去掉这两行:
12shopt -s checkwinsizeresize
没有的话就不管了。然后打开环境变量文件/etc/profile,添加如下内容:
12shopt -s checkwinsizeresize
然后在开机的时候会有如下打印:
然后输入很长的命令也不会有问题啦。可以看到上面其实出现了报错,主要是因为我们制作的根文件系统没有shopt命令,后来我试了,只写这个也没问题:
1resize
这样也可以重新设置默认终端长度。