[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驱动开发,那么最后,感谢大家的观看!

相关推荐
努力学习的小廉3 分钟前
深度理解linux系统—— 进程优先级
linux·运维·服务器
浅安的邂逅7 分钟前
Linux进程7-signal信号处理方式验证、可重入函数举例、信号集函数验证、信号集阻塞验证
linux·c语言·vim·进程通信·gcc
胖大和尚1 小时前
Linux C++ xercesc xml 怎么判断路径下有没有对应的节点
xml·linux·c++
hallo-ooo1 小时前
【STM32】定时器的外部时钟模式
stm32·单片机
hallo-ooo1 小时前
【STM32】定时器输入捕获
stm32·单片机
花酒锄作田1 小时前
个人对Debian桌面系统的简单使用分享
linux
我是唐青枫1 小时前
Linux diff 命令使用详解
linux·运维·服务器
獭.獭.1 小时前
Linux -- 操作系统
linux·操作系统·冯诺依曼体系
小镇敲码人2 小时前
【Linux深入浅出】之全连接队列及抓包介绍
linux·服务器·网络
小智学长 | 嵌入式2 小时前
单片机-STM32部分:1、STM32介绍
stm32·单片机·嵌入式硬件