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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/79891.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2025-05-07 学习记录--Python-变量 + 常量 + 命名规则 + 变量的数据类型 + 数据类型

合抱之木,生于毫末;九层之台,起于累土;千里之行,始于足下。💪🏻 一、变量 ⭐️ 多个变量的赋值 🍭 二、常量 ⭐️ 程序在运行的过程中,值永远不会发生改变的量称之为常量…

16.状态模式:思考与解读

原文地址:状态模式:思考与解读 更多内容请关注:深入思考与解读设计模式 引言 在开发软件系统时,特别是当对象的行为会随着状态的变化而变化时,系统往往会变得复杂。你是否遇到过这样的情况:一个对象的行为在不同的状…

从 Pretrain 到 Fine-tuning:大模型迁移学习的核心原理剖析

引言 在人工智能领域,大模型的出现掀起了一场技术革命。这些拥有海量参数的模型,如 GPT-4、PaLM 等,在众多任务上展现出了惊人的能力。然而,训练一个大模型需要耗费巨大的计算资源和时间,而且直接让大模型处理特定领域…

Java详解LeetCode 热题 100(11):LeetCode 239. 滑动窗口最大值(Sliding Window Maximum)详解

文章目录 1. 题目描述2. 理解题目3. 解法一:暴力法3.1 思路3.2 Java代码实现3.3 代码详解3.4 复杂度分析3.5 适用场景 4. 解法二:优先队列(最大堆)4.1 思路4.2 Java代码实现4.3 代码详解4.4 复杂度分析4.5 适用场景 5. 解法三&…

org.apache.poi——将 office的各种类型文件(word等文件类型)转为 pdf

org.apache.poi——将 office的各种类型文件&#xff08;word等文件类型&#xff09;转为 pdf 简介使用方法word转pdf 使用示例word转pdf 简介 使用方法 word转pdf Maven坐标为 <dependency><groupId>com.documents4j</groupId><artifactId>documen…

二叉树与优先级队列

1.树 树是由n个数据构成的非线性结构&#xff0c;它是根朝上&#xff0c;叶朝下。 注意&#xff1a;树形结构之中&#xff0c;子树之间不能连接&#xff0c;不然就不构成树形结构 1.子树之间没有交集 2.除了根节点以外&#xff0c;每一个节点有且只有一个父亲节点 3.一个n个…

如何进行室内VR全景拍摄?

如何进行室内VR全景拍摄&#xff1f; 室内VR全景拍摄作为先进的视觉技术&#xff0c;能够为用户提供沉浸式的空间体验。本文介绍如何进行室内VR全景拍摄&#xff0c;并阐述众趣科技在这一领域的技术支持和服务优势。 室内VR全景拍摄基础 1. 室内VR全景拍摄概述 室内VR全景拍…

如何通过代理 IP 实现异地直播推流

在直播行业日益火爆的今天&#xff0c;许多主播希望突破地域限制&#xff0c;实现异地直播推流&#xff0c;以获得更广泛的观众群体和更好的直播效果。代理 IP 作为一种有效的网络工具&#xff0c;能够帮助主播轻松达成这一目标。本文将详细介绍如何通过代理 IP 实现异地直播推…

随机变量数字特征

主要介绍一维随机变量期望和方差、二维随机变量期望和方差、以及协方差相关公式&#xff0c;及推导。 一维随机变量 以一个抛硬币的场景作为例子&#xff0c;如下&#xff1a; 抛掷两枚均匀硬币&#xff0c;如果两枚都是正面向上&#xff0c;则赢得2元&#xff0c;否则就输掉…

上传图片后,如何调用API进行商品搜索?

以下是一个完整的示例&#xff0c;展示如何在上传图片后调用淘宝按图搜索商品&#xff08;拍立淘&#xff09;API进行商品搜索&#xff1a; 1. 准备工作 注册账号并获取API密钥&#xff1a;在淘宝开放平台注册账号&#xff0c;创建应用&#xff0c;获取app_key和app_secret。 …

Android 数据持久化之 Room 数据库存储

一、简介 Room 是 Google 推出的 Android 持久层框架,建立在 SQLite 之上,提供了一个抽象层,简化了数据库操作。它通过注解和编译时检查来确保数据操作的正确性。 Room 主要由以下三个组件组成: Entity(实体):定义封装实际数据的实体类,每个实体类对应数据库中的一个…

react中的用法——setDisabled dva dispatch effects

setDisabled 在react中&#xff0c;setDisabled通常是指通过状态管理来控制某个组件&#xff08;如按钮、输入框等&#xff09;的禁用状态。虽然react本身没有内置的setDisabled方法&#xff0c;但你可以使用useState钩子来实现类似的功能。以下是一个简单的示例&#xff0c;展…

html css js网页制作成品——HTML+CSS珠海网页设计网页设计(4页)附源码

目录 一、&#x1f468;‍&#x1f393;网站题目 二、✍️网站描述 三、&#x1f4da;网站介绍 四、&#x1f310;网站效果 五、&#x1fa93; 代码实现 &#x1f9f1;HTML 六、&#x1f947; 如何让学习不再盲目 七、&#x1f381;更多干货 一、&#x1f468;‍&#x1f…

C语言复习笔记--自定义类型

今天我们来复习一下自定义类型.自定义类型大概分为结构体,枚举,联合体,数组这几种.数组在之前就介绍过.今天我们来看下其他三种. 结构体 首先来看结构体. 结构体类型的声明 之前在操作符的地方简单认识过结构体.下面我们回顾一下. 结构体回顾 结构是⼀些值的集合&#xff0c;这…

python jupyter notebook

什么是Jupyter Notebook Jupyter Notebook是一个开源的Web应用程序&#xff0c;允许用户创建和共享包含实时代码、方程、可视化和解释性文本的文档。它最初由IPython团队开发&#xff0c;现在已经成为一个独立的项目&#xff0c;并广泛用于数据清理和转换、数值模拟、统计建模…

Linux——https基础理论

1. 初步认识https协议 • 属于应用层 • 相较于http协议&#xff0c;https在应用层多了一层加密层&#xff0c;为了保证数据安全 • 简单理解&#xff1a;https就是对http的加密和解密 2. 中间人攻击 • 数据在传输过程中&#xff0c;遭第三方篡改。 3. 加密方式 • 对称加密&a…

在 C++ 中对类型进行排序

0.前言 在 C 中&#xff0c;我编写了一个 tuple-like 模板&#xff0c;这个模板能容纳任意多且可重复的类型&#xff1a; template<typename... Ts> struct TypeList {};// usage: using List1 TypeList<int, double, char, double>; using List2 TypeList<…

Unity-Socket通信实例详解

今天我们来讲解socket通信。 首先我们需要知道什么是socket通信&#xff1a; Socket本质上就是一个个进程之间网络通信的基础&#xff0c;每一个Socket由IP端口组成&#xff0c;熟悉计网的同学应该知道IP主要是应用于IP协议而端口主要应用于TCP协议&#xff0c;这也证明了Sock…

使用Go语言对接全球股票数据源API实践指南

使用Go语言对接全球股票数据API实践指南 概述 本文介绍如何通过Go语言对接支持多国股票数据的API服务。我们将基于提供的API文档&#xff0c;实现包括市场行情、K线数据、实时推送等核心功能的对接。 一、准备工作 1. 获取API Key 联系服务提供商获取访问密钥&#xff08;替…

LeetCode 热题 100 17. 电话号码的字母组合

LeetCode 热题 100 | 17. 电话号码的字母组合 大家好&#xff0c;今天我们来解决一道经典的算法题——电话号码的字母组合。这道题在 LeetCode 上被标记为中等难度&#xff0c;要求给定一个仅包含数字 2-9 的字符串&#xff0c;返回所有它能表示的字母组合。下面我将详细讲解解…