根文件系统的构建

news2024/11/16 14:11:31

文章目录

  • 一、根文件系统是什么?
  • 二、根文件目录
    • 1.bin目录
    • 2.etc
    • 3.lib
    • 4.mnt
    • 5.proc
    • 6.sys
    • 7.usr
    • 8.dev
    • 9.opt
    • 10.var
  • 三.使用工具Busybox构建根文件系统
    • 1.rootfs文件夹创建
    • 2.在makefile中添加交叉编译器
    • 3.busybox 中文字符支持
    • 4.配置 默认busybox
    • 5.使用图形界面配置busybox
    • 6.编译
  • 四.将库文件添加到编译后的目录
    • 1.向 rootfs 的“/lib”目录添加库文件
    • 2.向 rootfs 的“usr/lib”目录添加库文件
    • 3.检查lib是否都正常复制到rootfs/lib,rootfs/usr/lib,和大小验证
    • 4.补全其他文件夹
    • 5.初步测试
    • 6.文件补充


一、根文件系统是什么?

💦根文件系统也称rootfs,在学习STM32的过程中,与SD卡通讯过,涉及到
FATFS系统,根文件系统与FATFS是否一致呢,答案是不同的。
💦根文件系统,简单来说就是一系列文件的集合,文件包括“图片,软件,配置文件,驱动库”等等,在Linux中,内核就是通过调用根文件系统运行的 ,Linux系统内核没有那么大,其他的都是根文件系统。
那么这个根文件系统是怎么来的呢,需要自己构建。

二、根文件目录

💦既然根文件系统需要自己构建,在构建前,肯定需要了解,根文件系统有哪些东西,换种说法就是有哪些目录。
💦举例:以Ubuntu系统为例
在这里插入图片描述

1.bin目录

💦bin目录,通过目录名字,应该可以能想到 此目录,存放bin 文件,bin 文件也就是可执行文件。所以此目录下存放着系统需要的可执行文件,大多都是一些命令,比如 ls、mv 等命令。并且此目录下的命令所有的客户都可以使用。
比如,cp,ls命令等。
在这里插入图片描述

2.etc

💦此目录下存放着各种配置文件,比如在Ubuntu系统中,配置环境变量的profile文件。在构建自己的根文件系统的时候,需要哪些配置文件加入哪些,其他的不用不需要添加。这样自己构建的嵌入式 Linux 下此目录会很简洁。
在这里插入图片描述

3.lib

💦lib 是 library 的简称,也就是库的意思,因此此目录下存放着 Linux 所必须的库文件。比如C库,或者其他的第三方的库文件,这些库文件是共享库,命令和用户编写的应用程序要使用这些库文件。

4.mnt

💦l临时挂载目录,一般是空目录,可以在此目录下创建空的子目录,比如/mnt/sd、/mnt/usb,这样就可以将 SD 卡或者 U 盘挂载到/mnt/sd 或者/mnt/usb 目录中。

5.proc

sweat_drops:此目录一般是空的,当 Linux 系统启动以后会将此目录作为 proc 文件系统的挂载点,proc是个虚拟文件系统,没有实际的存储设备。proc 里面的文件都是临时存在的,一般用来存储系统运行信息文件

6.sys

💦系统启动以后此目录作为 sysfs 文件系统的挂载点,sysfs 是一个类似于 proc 文件系统的特殊文件系统,sysfs 也是基于 ram 的文件系统,也就是说它也没有实际的存储设备。此目录是系统设备管理的重要目录,此目录通过一定的组织结构向用户提供详细的内核数据结构信息

7.usr

💦要注意,usr 不是 user 的缩写,而是 Unix Software Resource 的缩写,也就是 Unix 操作系统软件资源目录。补充个小知识点,方便类比记忆,那就是 Linux 一般被称为类 Unix 操作系统,苹果的 MacOS也是类 Unix 操作系统。既然是软件资源目录,因此/usr 目录下也存放着很多软件,一般系统安装完成以后此目录占用的空间最多。

8.dev

💦dev 是 device 的缩写,所以此目录下的文件都是和设备有关的,此目录下的文件都是设备文件。在 Linux 下一切皆文件,即使是硬件设备,也是以文件的形式存在的,比如/dev/ttymxc0(I.MX6ULL 根目录会有此文件)就表示 I.MX6ULL 的串口 0,我们要想通过串口 0发送或者接收数据就要操作文件/dev/ttymxc0,通过对文件/dev/ttymxc0 的读写操作来实现串口
0 的数据收发。

9.opt

💦可选的文件、软件存放区,由用户选择将哪些文件或软件放到此目录中。

10.var

💦此目录存放一些可以改变的数据。

💦注意:其他的目录是Ubuntu系统的目录,不用了解太深。

三.使用工具Busybox构建根文件系统

💦Busybox是比较基础的根文件系统工具,有比较好用的buildroot,yocto等比较先进的工具流程比较完善,对学习来说,性价比低。

1.rootfs文件夹创建

将编译后的文件都放在这个rootfs文件夹中并解压缩,最后使用nfs服务挂载。

在这里插入图片描述

2.在makefile中添加交叉编译器

💦修改ARCH
在这里插入图片描述
💦修改CROSS_COMPILE 这个一定要使用绝对目录,arm-linux-gnueabihf-安装的目录。
在这里插入图片描述
💦注意:arm-linux-gnueabihf-后边不要有空格

CROSS_COMPILE ?= /usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-

3.busybox 中文字符支持

💦需要修改libbb文件夹下的 printable_string.c文件。
在这里插入图片描述
💦在函数printable_string中将大于0x7f的语句屏蔽掉。

const char* FAST_FUNC printable_string(uni_stat_t *stats, const char *str)

在这里插入图片描述
💦需要修改libbb文件夹下的 unicode.c文件,在unicode_conv_to_printable2中屏蔽掉大于0x7f的语句。

static char* FAST_FUNC unicode_conv_to_printable2(uni_stat_t *stats, const char *src, unsigned width, int flags)

在这里插入图片描述
在这里插入图片描述

4.配置 默认busybox

💦busybox跟我们编译 Uboot、Linux kernel 一样,编译器先对 busybox 进行默认的配置,有以下几种配置选项:
①、defconfig,缺省配置,也就是默认配置选项。
②、allyesconfig,全选配置,也就是选中 busybox 的所有功能。
③、allnoconfig,最小配置。
常用选项默认配置

make defconfig

💦注意:编译的过程中会有很多错误,解决办法,给busybox目录赋予权限。
在这里插入图片描述
💦编译成功会生成.config文件。

在这里插入图片描述

5.使用图形界面配置busybox

命令如下:

make menuconfig

💦选项“Build static binary (no shared libs)”用来决定是静态编译 busybox 还是动态编译,静态编译的话就不需要库文件,但是编译出来的库会很大。
动态编译的话要求根文件系统中有库文件,但是编译出来的 busybox 会小很多。这里我们不能采用静态编译!因为采用静态编译的话 DNS 会出问题!无法进行域名解析。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
💦保存退出。

6.编译

💦编译指令如下:

make install CONFIG_PREFIX=/home/che/linux/nfsfile/rootfs

💦生成文件如下。
在这里插入图片描述

四.将库文件添加到编译后的目录

1.向 rootfs 的“/lib”目录添加库文件

💦Linux 中的应用程序运行都是需要动态库的,由于我们编译的时候使用的是动态库编译,编译后的文件是缺少动态库的,所以我们需要向根文件系统中添加动态库。
当然了也可以编译成静态的,但是静态的可执行文件会很大。
添加动态库的方法:
💦在 rootfs 中创建一个名为“lib”的文件夹,命令如下:

sudo mkdir lib

在这里插入图片描述
💦lib 文件夹创建好了,库文件从哪里来呢?lib 库文件是从交叉编译器中获取,在安装
交叉编译环境的时候,将交叉编译器存放到了“/usr/local/arm/”目录中。
sweat_drops:交叉编译器里面有很多的库文件,这些库文件具体是做什么的,作为初学者肯定不知道,既然不知道那就先把所有的库文件都放到我们的根文件系统中,后期知道了可以进行裁剪。
💦第一个目录:/arm-linux-gnueabihf/libc/lib

/usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/arm-linux-gnueabihf/libc/lib

💦在上述目录中输入下面指令:

cp *so* *.a /home/che/linux/nfsfile/rootfs/lib/ -d  //-d表示复制符号连接

💦补充:符号连接的含义是相当于windows中的快捷方式,它也链接着一个文件,输入下方指令查看。

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

在这里插入图片描述
💦如果根文件系统中存在这个ld-linux-armhf.so.3符号链接,运行时会报错,所以解决方法是将其在roots/lib目录中删除,在交叉编译器中从新复制一个到roots/lib目录中,在查看其变成正常的文件了。
在这里插入图片描述
💦注意:其他的符号链接则可以正常运行。
在这里插入图片描述
💦第二个目录:/arm-linux-gnueabihf/lib

/usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/arm-linux-gnueabihf/lib

💦在上述目录中输入下面指令:也要加入-d复制符号链接

cp *so* *.a /home/che/linux/nfsfile/rootfs/lib/ -d

2.向 rootfs 的“usr/lib”目录添加库文件

💦在 rootfs /usr中创建一个名为“lib”的文件夹,命令如下:

mkdir lib

💦目录如下:/arm-linux-gnueabihf/libc/usr/lib

/usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/arm-linux-gnueabihf/libc/usr/lib

💦在上述目录中输入下面指令:

cp *so* *.a /home/che/linux/nfsfile/rootfs/usr/lib/ -d

3.检查lib是否都正常复制到rootfs/lib,rootfs/usr/lib,和大小验证

在这里插入图片描述

在这里插入图片描述
💦检查大小,指令如下:

du ./lib ./usr/lib -sh

在这里插入图片描述

4.补全其他文件夹

💦在根文件系统中创建其他文件夹,如 dev、proc、mnt、sys、tmp 和 root 等
在这里插入图片描述

5.初步测试

💦测试方法:使用nfs进行网络挂载根文件系统,原因是根文件系统很大的,如果每次修改文件都需要烧录,太浪费时间,使用nfs的好处是每次修改文件,直接复制到nfs的挂载目录即可,等Linux系统启动后就会通过nfs挂载根文件系统。
💦前提条件:
1)网络要能正常使用,nfs可以正常使用,注意nfs要支持v2版本,内核版本不要太高
2)修改uboot的bootargs 环境变量的值。
3)bootcmd设置tftp从Ubuntu系统加载zImage,dtb。
💦开始设置:nsf挂载
💦在 Linux 内核源码里面有相应的文档讲解如何设置,文档为 Documentation/filesystems/nfs/
nfsroot.txt
💦格式如下:bootargs 环境变量设置格式

root=/dev/nfs nfsroot=[<server-ip>:]<root-dir>[,<nfs-options>] 
ip=<client-ip>:<server-ip>:<gwip>:<netmask>:<hostname>:<device>:<autoconf>:<dns0-ip>:<dns1-ip>
<server-ip>:服务器 IP 地址,也就是存放根文件系统主机的 IP 地址,那就是 Ubuntu 的 IP
地址,比如我的 Ubuntu 主机 IP 地址为 192.168.1.50250<root-dir>:根文件系统的存放路径,比如我的就是/home/che/linux/nfsfile/rootfs。
<nfs-options>:NFS 的其他可选选项,一般不设置。
<client-ip>:客户端 IP 地址,也就是我们开发板的 IP 地址,Linux 内核启动以后就会使用
此 IP 地址来配置开发板。此地址一定要和 Ubuntu 主机在同一个网段内,并且没有被其他的设
备使用,在 Ubuntu 中使用 ping 命令 ping 一下就知道要设置的 IP 地址有没有被使用,如果不能
ping 通就说明没有被使用,那么就可以设置为开发板的 IP 地址,比如我就可以设置为
192.168.1.20<server-ip>:服务器 IP 地址。
<gw-ip>:网关地址,我的就是 192.168.1.255<netmask>:子网掩码,我的就是 255.255.255.0<hostname>:客户机的名字,一般不设置,此值可以空着。
<device>:设备名,也就是网卡名,一般是 eth0,eth1….,I.MX6U-ALPHA 开
发板的 ENET2 为 eth0,ENET1 为 eth1。如果你的电脑只有一个网卡,那么基本只能是 eth0。
这里我们使用 ENET2,所以网卡名就是 eth0。
<autoconf>:自动配置,一般不使用,所以设置为 off。
<dns0-ip>:DNS0 服务器 IP 地址,不使用。
<dns1-ip>:DNS1 服务器 IP 地址,不使用。
setenv bootargs 'console=ttymxc0,115200 root=/dev/nfs nfsroot=192.168.1.20:/home/che/linux/nfsfile/rootfs ip=192.168.1.50:192.168.1.20:192.168.1.1:255.255.255.0::eth0:off'

💦成功后界面如下:
在这里插入图片描述
💦VFS:Mounted root (nfs filesystem)readonly on device 安装只读系统,因为在设置bootargs变量的时候,没有设置全,修改bootargs变量加入rw功能。

bootargs=console=ttymxc0,115200 root=/dev/nfs nfsroot=192.168.1.20:/home/che/linux/nfsfile/rootfs,proto=tcp rw ip=192.168.1.50:192.168.1.20:192.168.1.1:255.255.255.0::eth0:off

💦可以创建文件了
在这里插入图片描述

6.文件补充

文件系统启动的时候
报错一如下:
在这里插入图片描述
💦解决办法:
💦缺啥补啥,先创建个etc目录,因为使用nfs挂载Ubuntu系统中rootfs,所以在Ubuntu系统中操作就可以,

PATH=/sbin:/bin:/usr/sbin:/usr/bin:$PATH
/sbin是绝对路径,$PATH加上以前的环境变量
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/lib:/usr/lib
$LD_LIBRARY_PATH加上以前的lib库
mount -a
mkdir /dev/pts
mount -t devpts devpts /dev/pts
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s

💦解析:
💦PATH 环境变量保存着可执行文件可能存在的目录,这样我们在执行一些命令或者可执行文件的时候就不会提示找不到文件这样的错误。
💦LD_LIBRARY_PATH 环境变量保存着库文件所在的目录。
💦使用 export 来导出上面这些环境变量,相当于声明一些“全局变量”。
💦使用 mount 命令来挂载所有的文件系统,这些文件系统由文件/etc/fstab 来指定,所以我们一会还要创建/etc/fstab 文件。
💦创建目录/dev/pts,然后将 devpts 挂载到/dev/pts 目录中。
💦使用 mdev 来管理热插拔设备,通过这两行,Linux 内核就可以在/dev 目录下自动创建设备节点。关于 mdev 的详细内容可以参考 busybox 中的 docs/mdev.txt 文档。

💦复杂的 rcS 文件也是借助其他工具创建的,比如 buildroot 等。

💦报错二如下:
在这里插入图片描述
💦“mount -a”挂载所有根文件系统的时候需要读取/etc/fstab,因为/etc/fstab 里面定义了该挂载哪些文件,所以需要创建/etc/fstab 文件并指明需要挂载系统类型。
在这里插入图片描述
在这里插入图片描述
💦fstab内容如下:
在这里插入图片描述
💦最后在创建/etc/inittab 文件,此文件的作用解析如下:

💦init是Linux系统操作中不可缺少的程序之一。是一个由内核启动的用户级进程。
Linux系统的启动过程为:加电自检–>根据BIOS中的设置从指定的设备启动–>找到设备MBR中的bootloader引导启动系统–>启动kernel–>启动init进程
💦我们看到,Linux系统启动的最后是启动init进程,而init进程是怎么工作的呢?init进程就是根据/etc/inittab这个文件来在不同的运行级别启动相应的进程或执行相应的操作。

在这里插入图片描述

💦对于busybox而言格式如下:
在这里插入图片描述
在这里插入图片描述
💦inittab内容如下:最好用vim编译器编写。
在这里插入图片描述

在这里插入图片描述

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

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

相关文章

Mysql 、Redis 数据双写一致性 更新策略与应用

零、important point 1. 缓存双写一致性问题 2. java实现逻辑&#xff08;对于 QPS < 1000 可以使用&#xff09; public class UserService {public static final String CACHE_KEY_USER "user:";Resourceprivate UserMapper userMapper;Resourceprivate Re…

部署Hyperledger Fabric测试区块链网络

一. 快速启动区块链测试网络 启动Fabric虚拟机 将 fabric-samples.zip 拷贝进虚拟机 ubzip fabric-samples.zip 解压并重命名为fabric-samples mv fabric-samples-main fabric-samples 拷贝bin和config目录 cd fabric-samples cp ~/fabric/bin bin -r cp ~/fabric/config …

企业如何走出“费控”迷雾,打造逆势增长“新引擎”?

“你先自己垫一下&#xff0c;回头再报销。”职场中人或多或少都听到过这句话&#xff0c;这一等可能就是猴年马月。 报销数字化仅仅是企业费控管理的一方面&#xff0c;随着企业对费用的认知从“管控”到“管理”的升级&#xff0c;企业对于费用管理的期望也向全流程、精细化&…

报错The chromedriver version cannot be discovered以及下载chromedriver.exe和查看其版本的命令

python3.8.10&#xff0c;win10。 谷歌浏览器版本&#xff08;我写代码的时候还是123.0.x.x&#xff0c;没几天就自动更新到124.0.x.x了&#xff09;&#xff1a; 在使用selenium的时候&#xff0c;出现报错&#xff0c;The chromedriver version cannot be discovered。 &am…

C语言中字符串函数以及内存函数的使用和注意事项

目录 0. 前言 1、求字符串长度函数 1.1、strlen 模拟实现 2.长度不受限制的字符串函数 2.1 strcpy 模拟实现 2.2strcat 模拟实现 2.3strcmp 模拟实现 3.长度受限制的字符串函数 3.1strncpy 3.2strncat 3.3strncmp 4、字符串查找函数 4.1strstr 模拟实现 3.2strt…

使用51单片机控制T0和T1分别间隔1秒2秒亮灭逻辑

#include <reg51.h>sbit LED1 P1^0; // 设置LED1灯的接口 sbit LED2 P1^1; // 设置LED2灯的接口unsigned int cnt1 0; // 设置LED1灯的定时器溢出次数 unsigned int cnt2 0; // 设置LED2灯的定时器溢出次数// 定时器T0 void Init_Timer0() {TMOD | 0x01;; // 定时器…

HarmonyOS ArkUI实战开发-页面跳转(Router、Ability)

页面跳转可以分为页面内跳转和页面间跳转&#xff0c;页面内跳转是指所跳转的页面在同一个 Ability 内部&#xff0c;它们之间的跳转可以使用 Router 或者 Navigator 的方式&#xff1b;页面间跳转是指所跳转的页面属与不同的 Ability &#xff0c;这种跳转需要借助 featureAbi…

Java中的对象

什么是类和对象 在Java中类是物以类聚&#xff0c;分类的思维模式&#xff0c;思考问题首先会解决问题需要哪些分类&#xff0c;然后对这些类进行单独思考&#xff0c;最后才是对某分类下的细节进行单独思考 面向对象适合处理复杂问题适合处理需要多人协作的问题 在Java中面向…

二维前缀和与差分

前言 延续前面所讲的一维前缀和以及差分&#xff0c;现在来写写二维前缀和与差分 主要这个画图就比前面的一维前缀和与差分复杂一点&#xff0c;不过大体思路是一样的 一维和二维的主要思路在于一维是只针对对一行一列&#xff0c;而二维是针对与一个矩阵的 好吧&#xff0…

可视化大屏在政务领域应用非常普遍,带你看看

可视化大屏在政务领域的应用非常普遍&#xff0c;政务领域需要处理大量的数据和信息&#xff0c;通过可视化大屏可以将这些数据以直观、易懂的方式展示出来&#xff0c;帮助政府决策者和工作人员更好地了解和分析数据&#xff0c;从而做出更准确、科学的决策。 在政务领域&…

java学习之路-抽象类和接口

目录 前言 1.抽象类 1.2抽象类语法 1.3抽象类特性 1.4抽象类的作用 2.接口 2.1接口概念 2.2接口的定义 2.3接口的使用 接口使用栗子 2.4接口特性 2.5 实现多个接口 请看栗子 2.6接口间的继承 2.7接口使用实例 2.8Clonable 接口和深浅拷贝 2.9 抽象类和接口的区别…

Qt图片等资源管理

Qt的图片等资源管理通常有两种方式 1&#xff0c;直接将图标和一些配置文件打包在可执行程序中 添加qrc文件&#xff0c;可使用qtcreator直接添加 右键选中工程 点击选择即可。 然后添加文件。我这个例子是添加了Image文件夹下的图片资源 使用的时候&#xff0c;可以在代码…

MySQL学习笔记1(MySQL基础)

1.MySQL基础 1.数据库相关概念 ​ *数据库&#xff1a;存储数据的仓库&#xff0c;数据是有组织的进行存储 DtaBase(DB) ​ *数据管理系统&#xff1a;操纵和管理数据库的大型软件 DataBase Management System (DBMS) ​ *SQL&#xff1a;操作关系型数据库的编程语言&#…

【GNSS】GNSS开源相关代码汇总

仅作为笔者的学习笔记使用 参考&#xff1a;GNSS算法相关开源代码&#xff08;含多传感器融合相关项目&#xff09; - 知乎 (zhihu.com)

C语言本身不难,难得是应用场景很多

你学了C语言多半是要做项目的&#xff0c;这个过程中C语言是远远不够的&#xff0c;你把这部分难度加到C语言上&#xff0c;自然就难了在开始前我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「C语言的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区…

浅谈防火墙,IPS,APT威胁检测的互补性

在学习网络安全产品时发现很多产品的目的与功能大同小异都是防范非法流量或威胁&#xff0c;但是既然有产品的差异就有作用的目的的差异&#xff0c;下面浅谈一下三个网络安全产品的差异化与互补点 防火墙 传统防火墙主要是工作在二到四层&#xff0c;不会对报文的载荷进行检…

大家期待的「红米汽车」,可能真的要来了

不知道从啥时候开始&#xff0c;小米逐渐摘掉了那顶让人越看越顺眼的「亲民帽子」。 从最开始 1999 到后来 3999 甚至是 4999、5999&#xff0c;雷军口中的高端梦正在一步步实现。 前段时间小米首款汽车 SU7 上市&#xff0c;21.59-29.99 万元定价再次引来大批网友直呼&#…

串联滞后校正及matlab实现

syms b_1 Z[]; P[0,-10,-5]; K1500; G_0zpk(Z,P,K); %G_0为校正前系统开环传递函数 [num,den]tfdata(G_0); %求解b&#xff0c;T [Gm,Pm,wg_0,wc_0]margin(G_0); %Pm为校正前的幅值裕度, gamma60; %确定校正后的相角裕度 Phi_c-6; %校正后的截止频率下Gc(s)的相角&#xff0c;一…

C++ 散列表(hash table)

目录 一&#xff0c;哈希表 1&#xff0c;哈希表概述 2&#xff0c;哈希函数 3&#xff0c;碰撞冲突 二&#xff0c;代码实现 1&#xff0c;哈希函数与素数函数 2&#xff0c;哈希节点与哈希表数据结构 3&#xff0c;构造、析构以及一些简单的功能 4&#xff0c;清空&…

如何使用渐变块创建自定义聊天机器人

如何使用渐变块创建自定义聊天机器人 文章目录 如何使用渐变块创建自定义聊天机器人一、介绍二、参考示例1、一个简单的聊天机器人演示2、将流式传输添加到您的聊天机器人3、喜欢/不喜欢聊天消息4、添加 Markdown、图像、音频或视频 一、介绍 **重要提示&#xff1a;**如果您刚…