[Linux]从零开始的STM32MP157 Buildroot根文件系统构建

一、前言

在前面的教程中,教了大家如何移植一个LInux的内核并且正确启动,我们发现Linux内核在启动后会出现一个错误,提示我们没有找到根文件系统。那么什么是根文件系统呢?之前我们使用Ubuntu编译了STM32MP157的TF-A,UBOOT,LINUX内核相信大家对Ubuntu已经不陌生了,我们可以看到Ubuntu的路径都是从"/"开始写的,然而这个"/"就被我们叫做根,"/"与它下面挂载的文件并称为根文件系统。可以看到,根文件系统构建了我们系统的整个文件管理系统,我们的所有操作都是建立在根文件系统之上的,所以Linux内核一般与根文件系统一起出现,那么本次教程就来教大家如何为STM32MP157移植一个根文件系统并且正确启动,如果你准备好了,就让我们开始吧!

二、谁适合本次教程

根文件系统已经处于Linux内核的上层了,本质上是一些较为上层的操作,移植起来也比较简单,甚至需要我们改动的地方都很少,所以难度是比较低的,至少比移植前面几个模块的难度要低。所以如果你能完成前面模块的移植,那么本次移植肯定是没问题的。如果你使用的是别的开发板,也可以参考本次教程,上层的操作都大同小异,但是也仅仅只是作为参考,中间肯定有不一样的地方。

三、资料的准备

本次我们依然会使用正点原子的官方资料,下载方式在搭建编译环境时就讲过了,如果还不知道如何下载,可以看下面的文章中的资料下载部分:

STM32MP157交叉编译环境搭建:Linux从零开始的STM32MP157交叉编译环境配置-CSDN博客

资料下载完成以后如图所示:

准备好资料以后,就可以进行下一步了。

四、根文件系统的选择

目前主流的根文件系统有两个,分别是Busybox和Buildroot。我们应该如何选择这两种根文件系统呢,下面会分别探讨一下这两种根文件系统的优缺点。首先时Busybox,这是一款比较老的根文件系统,里面整理了常用的工具,缺点也很明显,许多链接库或者系统文件需要我们自己进行复制,不利于新手,但Busybox可以让我们更好的理解根文件系统中每个文件夹的作用,毕竟每个文件夹都是自己来构建的嘛!然后是Buildroot,Buildroot中集成了我们常用的模块,它将Busybot甚至Uboot与Linux内核都集成到了其中。所以可以看出Buildroot的集成度是非常高的,这也为我们编译省去了非常多不必要的步骤,在本次教程中也会使用Buildroot来进行演示,当然在后面的教程中也会为大家讲解Busybox。

五、Buildroot的编译与挂载

与前面几个模块一样,Buildroot是需要我们自己编译并且挂载的。当然,编译的第一步我们还是先找源码,Buildroot的源码在它的官网可以直接下载到,但是有一些问题,如果现在去官网下载Buildroot的源码的话,下载下来的源码是2025年2月份的,如果使用正点原子提供的2019年的gcc编译器去编译这个源码的话,就可能出现一些路径找不到的问题,这里除非换编译器,不然编译肯定是会失败的,这里我已经替大家测试过了。所以我们这里就使用正点原子提供给我们的源码。Buildroot的源码被放在了正点原子资料目录下的"01、程序源码\07、Buildroot源码"目录下,如图所示:

这里我们在Ubuntu的用户目录下的"Linux"目录下新建一个名为"BUILDROOT"的文件夹,使用下面的命令即可:

复制代码
mkdir BUILDROOT

新建完成以后如图所示:

然后我们将一开始找到的Buildroot的源码拷贝的这个目录中,这里不管是使用sftp还是直接复制都可以,将文件传输过去就行,完成以后如图所示:

我们使用下面的命令来解压这个压缩包:

复制代码
tar -xvf buildroot-2020.02.6.tar.bz2

解压完成以后,得到以下文件夹:

进入这个文件夹中,可以看到以下文件:

这些就是Buildroot的源码文件,下面我们来配置Buildroot,Buildroot是支持图形化配置的,所以我们可以直接在Buildroot的源码目录下输入下面的命令来启动图形化配置:

复制代码
make menuconfig

关于图形化配置,在之前的UBOOT图像化配置中已经讲得很详细了,这里就不多说了,如果你还不会图形化配置,或者不知到图像化配置的原理,可以看下面的文章:

UBOOT图形化配置及原理讲解:Linux从零开始的STM32MP157 U-Boot图形化配置及Kconfig文件讲解_kconfig图形化配置应用于应用层软件代码项目中-CSDN博客

下面我们继续回到正题。

图形化配置启动以后,如图所示:

下面我们开始配置,首先我们来配置"Target options":

进入"Target options"后,可以看到以下配置项:

这里我们选择"Target Architecture (i386) ---> "回车进入,进图后可以看到以下选项:

针对STM32MP157来说我们需要选择"( ) ARM (little endian) ",如图所示:

将选框移动到该位置然后按下回车就可以选中这个选项了,选择以后,我们界面中就会出现下面这些选项:

这里我们需要对这些选项进行以下配置:

这里选项都是一一对应,大家直接跟着图上配即可,配置完成以后,如图所示:

这样我们"Target options"的配置就完成了。下面我们来配置"Toolchain"位置如图所示:

"Toolchain"主要用于配置交叉编译器,进入后,可以看到以下选项:

这里的配置我们只需要修改几项即可,大家跟着我操作,首先就是"Toolchain type"我们将其配置为"(External toolchain) ---> "配置完成以后如图所示:

然后将"Toolchain"配置为"(Custom toolchain) ---> ",表示使用用户自己的编译器,完成后如图:

随后的"Toolchain origin"要配置为"(Pre-installed toolchain) ---> ":

随后我们要将"Toolchain path (NEW) "配置为我们自己交叉编译器的路径,这里如果大家之前也是跟着我配的的话,那么路径就是:

复制代码
/usr/local/arm/gcc-arm-9.2-2019.12-x86_64-arm-none-linux-gnueabihf

我们直接填入即可:

完成以后如图所示:

此后我们还需要将"Toolchain prefix"修改为"$(ARCH)-none-linux-gnueabihf",如图:

下方的"External toolchain gcc version "我们选项"9.x","External toolchain kernel headers series"我们选择"4.20.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"就配置完成了。下面我们来配置"System configuration",位置如图所示:

进入以后,可以看到以下选项:

同样的,这里只需要修改几个选项即可,首先是"System hostname"这是我们平台的名字,大家可以自行设置:

"System banner"表示系统的欢迎语,大家自行设置即可:

"Init system"我们这里选择"Busybox":

"/dev management"我们选择"Dynamic using devtmpfs + mdev":

这里我们选中"Enable root login with password"表示使能root用户的登录密码,在下方我们可以设置root用户的登录密码:

当然,这里的密码会在我们做Linux驱动开始时取消掉,不然我们每次进入系统都需要输入密码,非常不利于开发。这里作为测试,所以使能了密码。

至此,"System configuration"配置就完成了,下面我们来配置"Filesystem images",在如图所示位置:

进入以后可以看到以下选项:

这里我们选中"ext2/3/4 root filesystem",然后在下方新弹出的"ext2/3/4 variant"选项中选择"ext4":

然后我们将下方的"exact size"改为1G:

至此"Filesystem images"配置就完成了。下面我们来配置"Target packages",在如图所示位置:

进入以后,可以看到以下选项:

我们往下滑找到"System tools"选项并且进入,在如图所示位置:

进入以后,可以看到以下选项:

我们往下滑找到"kmod"并且选中:

因为buildroot在编译时会在一些国外的网站下载东西,因为网络问题可能会下载失败,所以这里我们需要将下载连接配置为国内镜像,这里我们进入"Build options"选项,在如图所示位置:

进入以后,可以看到以下选项:

我们进入"Mirrors and Download locations"选项,可以看到以下界面:

我们进行下面的修改:

复制代码
Backup download site  :http://sources.buildroot.net
Kernel.org mirror     :https://mirror.bjtu.edu.cn/kernel/
GNU Software mirror   :http://mirrors.nju.edu.cn/gnu/
LuaRocks mirror       :https://luarocks.cn
CPAN mirror (Perl packages) :http://mirrors.nju.edu.cn/CPAN/

修改完成以后,如图所示:

至此,我们所有的配置都已经完成,我们将配置文件保存到"./configs/stm32mp1_atk_defconfig"目录中,作为默认配置,后面直接加载即可:

保存完成以后,我们使用下方的命令加载配置文件:

复制代码
make stm32mp1_atk_defconfig

加载完成以后,可以看到,相关配置已经被写到了".config"文件中:

我们使用下面的命令,这里的编译线程数大家根据自己的情况写即可:

复制代码
make -j16

编译完成以后,如图所示:

这里我们进入Buildroot项目文件夹的"output/image"文件夹中,可以看到以下文件:

在"rootfs.tar"内就是我们编译的根文件系统了,下面来教大家如何挂载根文件系统。

这里我们要使用nfs来挂载根文件系统,所以这里大家需要确保自己的网络和nfs配置都没有问题,如果你还不会配置Uboot的网络和nfs可以看下面的文章:

UBOOT网络配置:Linux从零开始的STM32MP157 U-Boot网络命令讲解及相关配置_stm32mp157 联网-CSDN博客

这里我们在开发板一侧是可以ping到ubuntu的:

现在我们首先在nfs目录中新建一个名为"rootfs"的文件夹用来存放我们的根文件系统:

这里我们将刚才编译出来的"rootfs.tar"复制到新建的"rootfs"中:

然后使用下方的命令解压这个压缩包:

复制代码
tar -xvf rootfs.tar

解压后我们可以看到以下文件夹,这些文件夹都是Linux的根文件,想必大家已经非常熟悉了:

最后我们使用下面的命令将原本的压缩包删掉:

复制代码
rm -rf ./rootfs.tar

这里我们还需要修改以下nfs的配置文件,使用下面的命令打开配置文件:

复制代码
sudo nano /etc/default/nfs-kernel-server

打开后可以看到以下内容:

我们在最后一行加上下面的内容:

复制代码
RPCNFSDOPTS="--nfs-version 2,3,4 --debug --syslog" 

修改完以后如图所示:

最后我们保存退出即可。

修改完配置文件以后,我们使用下面的命令重新启动软件:

复制代码
sudo /etc/init.d/nfs-kernel-server restart 

这里显示ok以后,nfs的配置就修改完成了:

现在在开发板端,我们需要修改一下bootargs环境变量,使用下面的命令:

复制代码
setenv bootargs console=ttySTM0,115200 root=/dev/nfs nfsroot=192.168.1.100:/home/chulingxiao/linux/nfs/rootfs,proto=tcp rw ip=192.168.1.106:192.168.1.100:192.168.1.1:255.255.255.0::eth0:off

这里大家注意,这是一行命令,不要换行。大家使用时,需要修改几个地方,下面一一来讲,首先是"nfsroot=192.168.1.100:/home/chulingxiao/linux/nfs/rootfs"这里大家需要把这里的IP地址修改为自己Ubuntu的地址。后面的路径大家写自己的rootfs文件夹的路径。然后是"ip=192.168.1.106:192.168.1.100:192.168.1.1:255.255.255.0::eth0:off"这里有三个地址,按照从前到后的顺序是"开发板的IP地址","Ubuntu的IP地址","网关的IP地址",大家根据自己的情况配置即可。

输入命令后,使用"saveenv"将环境变量保存到EMMC中:

完成以后,我们使用"boot"命令加载内核和根文件系统:

等内核启动以后,根文件系统就挂载完成了,并且出现了登录提示:

这里用户名我们使用root,密码就是我们设置的密码:

登录完成以后,可以看到前面变成了"#",我们可以使用cd命令切换到根目录:

这里可以看到,我们的根文件系统已经启动完成了,虽然前面被提示一些目录找不到,但是问题不大,至少根文件系统启动成功,后面我们再来慢慢完善这个系统吧!

六、结语

在本次教程中,我们编译并且成功启动了buildroot根文件系统,这也意味着我们移植了一个完整可用的Linux系统,在后续,我们会在此基础上进行完善以及进行LInux驱动开发,那么最后,感谢大家的观看!

相关推荐
xexpertS16 小时前
CI/CD 熔断机制:如何通过编排级熔断器提升开发者效率
java·linux·运维
带娃的IT创业者16 小时前
突破内存瓶颈:利用 Nvidia GPU 显存作为 Linux Swap 空间的深度实践
linux·运维·服务器·nvidia·swap·gpu显存
zy happy16 小时前
VMware虚拟机添加新的硬盘
java·linux·jvm·docker
LCG元16 小时前
嵌入式开发踩坑排查实战:从 STM32 外设初始化到 Linux SPI 驱动的 15 类硬件疑难故障深度复盘
linux·stm32·单片机
代码AC不AC16 小时前
【Linux】Socket编程TCP
linux·tcp·socket编程
扛枪的书生16 小时前
SeaweedFS 学习总结
linux
piaoyiren17 小时前
基于 STM32F103 蓝牙遥控云台超声波避障小车
stm32·单片机·嵌入式硬件·蓝牙·超声波测距·直流电机
minglie117 小时前
香橙派zero3配个iic屏显示ip
linux·学习
edwarddamon17 小时前
SSH 指定端口建立隧道:打通内网访问完整教程
linux·命令行
ShirleyWang01217 小时前
Day02 K3s NGF(Nginx Gateway Fabric)单 Worker 环境网关更新与故障处置 SOP
linux·服务器·python·k8s·k3s