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

发布于:2025-05-12 ⋅ 阅读:(28) ⋅ 点赞:(0)

一、前言

        在上一篇教程中,已经教了大家如何使用Buildroot构建根文件系统,并且在最后我们已经完整的构建了一个可以运行的根文件系统。但是,Buildroot的集成度太高了,不利于小白理解根文件系统,所以本次教程,我们将会使用一种更为复杂的方式来构建根文件系统,那就是Busybox,它可以让我们自己去手动复制一些文件来构建根文件系统,可以让我们对根文件系统有更深刻的认识,如果你准备好了,就让我们开始吧!

二、谁适合本次教程

        如果你之前已经构建好了Buildroot根文件系统,那么本篇教程对你来说应该是完全没问题的,虽说Busybox根文件系统的构建过程繁琐但是绝对谈不上很难。如果你之前没有构建过Buildroot根文件系统还是建议先看我的上一篇教程。当然,如果你使用的开发板不是STM32MP157也可以将本篇教程作为参考,毕竟道理都是大差不差的。

三、资料的准备

        本次教程我们依然使用正点原子官方的资料,关于资料的下载在之前的交叉编译环境搭建的教程中就已经讲过了,如果你还没有下载正点原子的官方资料可以看下面的教程:

STM32MP157交叉编译环境搭建:[Linux]从零开始的STM32MP157交叉编译环境配置_stm32mp157 linux 开发 单片机开发-CSDN博客

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

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

四、Busybox的编译

        我们为了使用Busybox那么首先就是编译Busybox,正点原子的资料中已经提供了Busybox的源码。这里也建议大家直接使用正点原子官方给的源码,不要去官网自己下载,从官网下载的源码可能版本太新,从而导致编译失败。正点原子官方提供的源码被放在了正点原子资料目录下的“01、程序源码\06、BusyBox源码”目录下,如图所示:

如果你发现你没有这个目录,可以找到对应的压缩包将其解压。

这里我们在Ubuntu的用户目录的linux目录下新建一个名为“BUSYBOX”的目录,完成以后如图所示:

然后我们可以将正点原子提供的Busybox的源码拷贝到这个我们新建的目录中,这里不管大家是使用sftp也好,直接复制也好,只要将源码压缩包拷贝到这个目录即可,完成以后如图所示:

然后我们再使用下面的命令解压源码:

tar -xvf busybox-1.32.0.tar.bz2

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

进入这个文件夹中可以看到如下内容:

这些就是Busybox的源码了,我们下面会对源码进行一些修改操作。

这里我们首先使用vs code打开Busybox源码目录,方便我们修改,如图所示:

这里我们首先来配置Busybox的编译器,这里需要我们打开Busybox的顶层Makefile:

这里我们往下滑,找到大约在164行的“CROSS_COMPILE ?=”,如图所示:

这里我们直接将“CROSS_COMPILE ?=”的值写为“arm-none-linux-gnueabihf-”即可,因为我们已经将交叉编译器的路径配置到环境变量了,所以不用写绝对路径。修改完成以后如图所示:

CROSS_COMPILE ?=arm-none-linux-gnueabihf-

然后我们来到大约191行处,找到“ARCH ?= $(SUBARCH)”,如图所示:

这一行是为了配置编译的架构,我们直接写成“arm”即可,修改完成以后如图所示:

至此我们顶层Makefile就修改好了。大家保存退出即可。

默认情况下Busybox是没有提供中文支持的,我们需要修改一部分的代码使其支持中文,这里我们打开Busybox源码文件夹下的“libbb/printable_string.c”文件,打开以后,如图所示:

这里我们将31与32行的代码直接注释掉:

这里代码的意思是,当字符的编码大于“0x7f”的话就直接跳出函数了。

然后我们看到大约第45行的“if (c < ' ' || c >= 0x7f)”代码,如图所示:

这里我们需要将其注释掉,并且在它的下面写入下面的内容:

if( c < ' ')

修改完以后,如图所示:

至此,我们的“printable_string.c”文件就修改完成了。大家记得保存。

然后打开Busybox源码目录下的“libbb/unicode.c”:

我们来到1028行,找到如图所示代码“*d++ = (c >= ' ' && c < 0x7f) ? c : '?';”:

将其注释掉,在它的下面加上如下内容:

*d++ = (c >= ' ') ? c : '?';

然后来到大约1037行的位置,找到下面的代码“if (c < ' ' || c >= 0x7f)”,如图所示:

我们将其注释掉,添加如下内容:

if(c < ' ')

修改完以后,如图所示:

Busybox也是支持图形化配置的,下面的配置我们需要借助图形化来进行,如果你还没有配置过图形化或者想知道图形化配置的原理可以看下面的文章:

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

这里我们直接在Busybox的源码目录中使用下面的命令加载一下默认配置:

make defconfig

完成后如图所示:

然后使用下面的命令启动图形化配置:

make menuconfig

启动以后如图所示:

这里我们首先看到“Settings  --->  ”选项:

进入后,可以看到以下内容:

我们往下滑找到“Build static binary (no shared libs) ”:

这行配置是决定使用静态编译还是动态编译的,我们这里使用动态编译,所以这里不使能,注意是不使能。

然后我们再往下找到“vi-style line editing commands ”选项:

我们这里需要将其选中,如图所示:

然后我们再回到最外面的目录,找到“Linux Module Utilities  ---> ”:

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

这里我们需要取消勾选“Simplified modutils”选项:

然后我们再回到最外面的目录,找到“Linux System Utilities  --->  ”选项:

进入以后如图所示:

往下滑,我们找到“[*] mdev (17 kb) ”,确保它下面的选项都是选中的状态:

下面我们需要使能“unicode”编码,使Busybox构建的根文件系统支持中文,我们同样回到最外面的目录,然后进入“Settings  --->  ”往下滑找到“[*] Support Unicode ”,将其使能,如图所示:

然后将它下面的“Check $LC_ALL, $LC_CTYPE and $LANG environment variables”也使能,如图所示:

至此,我们的Busybox配置就已经完成了,下面我们回到最外层的目录,找到“Save Configuration to an Alternate File”选项:

来到这个选项回车以后,会问我们将配置文件保存在哪儿,这里我们将其保存到“configs”目录下斌且名为“stm32mp1_atk_defconfig”:

./configs/stm32mp1_atk_defconfig 

完成配置以后,我们退出即可,退出时提示我们是否要保存新配置,选择“yes”即可:

当我们配置完Busybox以后,就可以准备编译了,我们首先在Busybox的源码目录下方输入下面的命令加载默认配置文件:

make stm32mp1_atk_defconfig

然后使用下面的命令开始编译,这里编译的线程数大家根据自己电脑的实际情况调整即可:

make -j16

编译完成以后如图所示:

这里我们也会像使用Buildroot构建根文件系统时一样用nfs来挂载根文件系统,这里我们需要在nfs目录下新建一个rootfs目录,如果之前创建过了直接删掉重新创建即可:

完成以后,我们再次回到Busybox的源码目录中,使用下面的命令将编译出来的根文件系统安装到我们创建的rootfs目录中:

make install CONFIG_PREFIX=/home/chulingxiao/linux/nfs/rootfs

这里因为用户名不同,所以路径也会不同,大家根据自己的情况调整命令即可:

命令执行完成后如图所示:

这时候我们来到rootfs目录中,可以发现其中已经有一些基本目录了:

当然,只有这些目录的话我们的Linux根文件系统并不是完整的,下面我们来完善根文件系统。

我们首先使用下面的命令在rootfs目录下新建两个目录,后面我们会往这两个目录中复制库文件:

mkdir lib usr/lib

当我们新建好文件夹以后,我们需要将一些必要的库文件复制到这两个文件夹中,这里我们先使用下面的命令去到编译器对应的文件夹中,这里可能会因为编译器位置的不同命令也不同,大家根据自己编译器的位置写命令:

cd /usr/local/arm/gcc-arm-9.2-2019.12-x86_64-arm-none-linux-gnueabihf/arm-none-linux-gnueabihf/libc/lib/

去到对应的目录以后,我们可以看到如图所示的文件:

我们使用下面的命令将这个目录下的所有文件复制到rootfs下的lib目录中,同样的大家根据自己的情况写命令:

cp *so* /home/chulingxiao/linux/nfs/rootfs/lib/ -d

完成以后如图所示:

在这些文件中,“ld-linux-armhf.so.3”是一个比较特殊的文件,它是一个软链接,我们可以使用下面的命令看它指向了哪个文件:

ls  ld-linux-armhf.so.3 -l

这里我们可以看到这个软链接指向了一个名为“ld-2.30.so”的文件:

因为软链接在实际使用中是无效的,我们将原本复制到rootfs中名为“ld-linux-armhf.so.3 ”删掉。然后使用下面的命令重新复制一份“ld-linux-armhf.so.3 ”文件:

cp ld-linux-armhf.so.3 /home/chulingxiao/linux/nfs/rootfs/lib/

完成以后,rootfs的lib目录内容如图所示:

然后我们再使用下面的命令进入另一个目录:

cd /usr/local/arm/gcc-arm-9.2-2019.12-x86_64-arm-none-linux-gnueabihf/arm-none-linux-gnueabihf/lib

我们同样使用下面的命令将这个目录的文件也复制到“lib”目录中:

cp *so* *.a /home/chulingxiao/linux/nfs/rootfs/lib/ -d

完成以后lib目录如图所示:

我们现在向“usr/lib”目录添加文件,首先使用下面的命令切换文件夹:

cd /usr/local/arm/gcc-arm-9.2-2019.12-x86_64-arm-none-linux-gnueabihf/arm-none-linux-gnueabihf/libc/usr/lib

切换到对应目录后,使用下面的命令复制文件:

cp *so* *.a /home/chulingxiao/linux/nfs/rootfs/usr/lib/ -d

完成以后“usr/lib”目录下如图所示:

完成上面的步骤后,我们回到rootfs目录,我们使用下面的命令检查一下对应目录的大小:

du ./lib ./usr/lib/ -sh

这里可以看到,目录大小如下,如果你的目录大小和我差距非常大的话,看看是不是忘了什么步骤:

然后我们再使用下面的命令往我们的根文件系统中创建其它的基础文件夹:

 mkdir dev proc mnt sys tmp etc root

完成后我们的根文件系统如图所示:

因为要使用nfs挂载根文件系统,这里我们还需要修改以下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”命令加载内核和根文件系统:

当出现以下提示以后,我们按回车即可:

回车以后就可以看到我们进入根文件系统了:

就算前面有报错也没关系,至少Busybox构建的根文件系统已经正常启动了,我们可以来测试一下基础命令,比如“ls”:

输入ls以后就能看到我们根文件系统的全部内容。

至此,我们使用Busybox构建根文件系统就已经完成了。

五、结语

        相信完成了以上步骤,大家对根文件系统一定有了更深刻的认识,但是我们目前也只是将根文件系统构建好,还有一些错误仍然没有解决,并且我们构建的根文件系统的功能我们也没有测试,这就留到下一篇教程再来为大家讲解吧,那么最后,感谢大家的观看!

 


网站公告

今日签到

点亮在社区的每一天
去签到