LV05-04-根文件系统-01-根文件系统基础

本文主要是根文件系统——根文件系统基础的相关笔记,若笔记中有错误或者不合适的地方,欢迎批评指正😃。

点击查看使用工具及版本
PC端开发环境 Windows Windows11
Ubuntu Ubuntu20.04.2的64位版本
VMware® Workstation 17 Pro 17.6.0 build-24238078
终端软件 MobaXterm(Professional Edition v23.0 Build 5042 (license))
Win32DiskImager Win32DiskImager v1.0
Linux开发板环境 Linux开发板 正点原子 i.MX6ULL Linux 阿尔法开发板
uboot NXP官方提供的uboot,使用的uboot版本为U-Boot 2019.04
linux内核 linux-4.19.71(NXP官方提供)
点击查看本文参考资料
分类 网址 说明
官方网站 https://www.arm.com/ ARM官方网站,在这里我们可以找到Cotex-Mx以及ARMVx的一些文档
https://www.nxp.com.cn/ NXP官方网站
https://www.nxpic.org.cn/NXP 官方社区
https://u-boot.readthedocs.io/en/latest/u-boot官网
https://www.kernel.org/linux内核官网
点击查看相关文件下载
分类 网址 说明
NXP https://github.com/nxp-imx NXP imx开发资源GitHub组织,里边会有u-boot和linux内核的仓库
nxp-imx/linux-imx/releases/tag/v4.19.71 NXP linux内核仓库tags中的v4.19.71
nxp-imx/uboot-imx/releases/tag/rel_imx_4.19.35_1.1.0 NXP u-boot仓库tags中的rel_imx_4.19.35_1.1.0
I.MX6ULL i.MX 6ULL Applications Processors for Industrial Products I.MX6ULL 芯片手册(datasheet,可以在线查看)
i.MX 6ULL Applications ProcessorReference Manual I.MX6ULL 参考手册(下载后才能查看,需要登录NXP官网)
Source Code https://elixir.bootlin.com/linux/latest/source linux kernel源码
https://elixir.bootlin.com/u-boot/latest/source uboot源码

一、根文件系统简介

根文件系统一般也叫做 rootfs,那么什么叫根文件系统?看到“文件系统”这四个字,第一反应就是 FATFS、 FAT、 EXT4、YAFFS 和 NTFS 等这样的文件系统。但是在这里所说的根文件系统却不是那些。

Linux 中的根文件系统更像是一个文件夹或者叫做目录,在这个目录里面会有很多的子目录。根目录下和子目录中会有很多的文
件,这些文件是 Linux 运行所必须的,比如库、常用的软件和命令、设备文件、配置文件等等。相当于windows下的C盘,保存了系统启动后的应用程序和系统配置。

对于根文件系统专业的解释,百度百科上是这么说的:根文件系统首先是内核启动时所 mount(挂载)的第一个文件系统,内核代码映像文件保存在根文件系统中,而系统引导启动程序会在根文件系统挂载之后从中把一些基本的初始化脚本和服务等加载到内存中去运行。

百度百科上说内核代码镜像文件保存在根文件系统中,但是我们嵌入式 Linux 并没有将内核代码镜像保存在根文件系统中,而是保存到了其他地方。比如 NAND Flash 的指定存储地址、EMMC 专用分区中。根文件系统是 Linux 内核启动以后挂载(mount)的第一个文件系统,然后从根文件系统中读取初始化脚本,比如 rcS, inittab 等。根文件系统和 Linux 内核是分开的,单独的 Linux 内核是没法正常工作的,必须要搭配根文件系统。如果不提供根文件系统, Linux 内核在启动的时候就会提示内核崩溃(Kernel panic)的提示。

根文件系统是其他文件系统的根,没有这个“根”,其他的文件系统或者软件就无法工作。比如我们常用的 ls、 mv、 ifconfig 等命令其实就是一个个小软件,只是这些软件没有图形界面,而且需要输入命令来运行。这些小软件就保存在根文件系统中,这些小软件是怎么来的呢?后边的笔记就是构建自己的根文件系统的过程,这个根文件系统是满足 Linux 运行的最小根文件系统,后续我们可以根据自己的实际工作需求不断的去填充这个最小根文件系统,最终使其成为一个相对完善的根文件系统。

根文件系统的作用?

(1)根文件系统提供了根目录/,这样才实现了我们的文件访问

(2)shell脚本是在根文件系统上实现的,提供了我们所需的linux命令,例如ls cd pwd等

根文件系统的实质

(1)根文件系统是一种特殊的文件系统

(2)根文件系统属于用户进程,和内核无关

(3)根文件系统具有一定的格式

二、根文件系统里有什么?

我们进入ubuntu的根目录,这其实也就是ubuntu的根文件系统了:

image-20241117110957348

会发现里边有大量的子目录,子目录中还会有相应的子目录,这里我们只关心我们可能会用到的几个。

1. /bin 目录

bin 文件就是可执行文件。所以此目录下存放着系统需要的可执行文件,一般都是一些命令,比如 ls、 mv 等命令。此目录下的命令所有的用户都可以使用 ,我们可以打开这个目录看一下:

image-20241117111103446

2. /sbin目录

该目录下存放系统命令,即只有系统管理员(俗称最高权限的root)能够使用的命令,系统命令还可以存放在/usr/sbin,/usr/local/sbin目录下,/sbin目录中存放的是基本的系统命令,它们用于启动系统和修复系统等,与/bin目录相似,在挂接其他文件系统之前就可以使用/sbin,所以/sbin目录必须和根文件系统在同一个分区中。 /sbin目录下常用的命令有:shutdown、reboot、fdisk、fsck、init等,本地用户自己安装的系统命令放在/usr/local/sbin目录下。

image-20241117111236958

3. /dev 目录

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

image-20241117111329830

4. /etc 目录

该目录下存放着系统主要的配置文件,例如人员的账号密码文件、各种服务的其实文件等。一般来说,此目录的各文件属性是可以让一般用户查阅的,但是只有root有权限修改。对于PC上的Linux系统,/etc目录下的文件和目录非常多,这些目录文件是可选的,它们依赖于系统中所拥有的应用程序,依赖于这些程序是否需要配置文件。在嵌入式系统中,这些内容可以大为精减。

我们可以进入ubuntu的这个目录中看一下,会发现里面的配置文件非常多。但是在嵌入式 Linux 下此目录会很简洁。

image-20241117111458534

5. /lib 目录

lib 是 library 的简称,也就是库的意思,因此此目录下存放着 Linux 所必须的库文件。这些库文件是共享库,命令和用户编写的应用程序要使用这些库文件。

image-20241117112015326

6. /mnt 目录

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

image-20241117112108254

这里的hgfs就是vmware中ubuntu与windows共享目录所在的位置。

7. /proc 目录

此目录一般是空的,当 Linux 系统启动以后会将此目录作为 proc 文件系统的挂载点, proc是个虚拟文件系统,没有实际的存储设备。 proc 里面的目录,文件都是由内核临时生成的,用来表示系统的运行状态,也可以操作其中的文件控制系统。

image-20241117112300402

8. /usr 目录

要注意, usr 不是 user 的缩写,而是 Unix Software Resource 的缩写,也就是 Unix 操作系统软件资源目录。既然是软件资源目录,因此/usr 目录下也存放着很多软件,一般系统安装完成以后此目录占用的空间最多。

image-20241117112529170

usr目录的内容可以存在另一个分区中,在系统启动后再挂接到根文件系统中的/usr目录下。里面存放的还有一些共享、只读的程序和数据,这表明/usr目录下的内容可以在多个主机间共享,这些主要也符合FHS标准的。/usr中的文件应该是只读的,其他主机相关的,可变的文件应该保存在其他目录下,比如/var。/usr目录在嵌入式中可以精减。

9.  /var 目录

与/usr目录相反,/var目录中存放可变的数据,比如spool目录(mail,news),log文件,临时文件。

image-20241117112622754

10. /sys 目录

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

image-20241117112737771

11.  /opt

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

12. home和root

  • /home目录:系统默认的用户文件夹,它是可选的,对于每个普通用户,在/home目录下都有一个以用户名命名的子目录,里面存放用户相关的配置文件。
image-20241117112847331
  • /root目录:系统管理员(root)的主文件夹,即是根用户的目录,与此对应,普通用户的目录是/home下的某个子目录。
image-20241117112920605

13. 总结

对于嵌入式Linux系统的根文件系统来说,一般可能没有上面所列出的那么复杂,比如嵌入式系统通常都不是针对多用户的,所以/home这个目录在一般嵌入式Linux中可能就很少用到,而/boot这个目录则取决于所使用的BootLoader是否能够重新获得内核映像从我们的根文件系统在内核启动之前。一般说来,只有/bin,/dev,/etc,/lib,/proc,/var,/usr这些需要的,而其他都是可选的。

三、常见的根文件系统

根文件系统本质都是一些文件和配置信息组成,之间的界限没有很明确的界定,下面是一些常见的:

四、uClibc与glibc的差异

glibc和libc都是Linux下的C函数库,libc是Linux下的ANSI C的函数库;glibc是Linux下的GUN C的函数库;GNU C是一种ANSI C的扩展实现。ANSI C是基本的C语言函数库,包含了C语言最基本的库函数。在写程序时,需要用到很多c语言的库函数,这些所有的库函数整合起来,就是对应的C语言(标准)函数库。

目前在普通GNU/Linux系统中所用的C语言标准库,叫做glibc。它的功能很全,函数很多,但是就是因为代码太多,编译出来的函数库的大小也很大,占用的资源也很多,可以简单地认为glibc就是为了实现完整功能设计的。

由于在嵌入式系统中,也需要C语言写代码实现特定功能,因此需要用到C语言函数库,但是由于嵌入式系统中,一般资源比较有限,所以不适合直接使用太占用资源的glibc。uClibc 是一个面向嵌入式Linux系统的小型的C标准库,最初uClibc是为了支持uClinux而开发,这是一个不需要内存管理单元(MMU)的Linux版本。uClibc比一般用于Linux发行版的C库GNU C Library (glibc)要小得多, 因此uClibc专注于嵌入式Linux,除此之外uClibc比glibc更可配置,这意味着开发人员可以根据功能与空间需求进行裁剪。

简单总结以下几点:

(1)uClibc比glibc占用的资源小,虽然uClibc和glibc在已有的接口上是兼容的,而且采用uClibc编译应用程序比采用glibc编译应用程序要更方便,但是uClibc并没有包括glibc中的所有接口实现,因此有些应用可能在uClibc中不能编译。

(2)uClibc在可配置性上比glibc要好。

提示:关于uClibc与glibc更多的差异比较信息请看 简单总结以下几点:

  1. uClibc比glibc占用的资源小,虽然uClibc和glibc在已有的接口上是兼容的,而且采用uClibc编译应用程序比采用glibc编译应用程序要更方便,但是uClibc并没有包括glibc中的所有接口实现,因此有些应用可能在uClibc中不能编译。
  2. uClibc在可配置性上比glibc要好。

提示:关于uClibc与glibc更多的差异比较信息请看:简单总结以下几点:

  1. uClibc比glibc占用的资源小,虽然uClibc和glibc在已有的接口上是兼容的,而且采用uClibc编译应用程序比采用glibc编译应用程序要更方便,但是uClibc并没有包括glibc中的所有接口实现,因此有些应用可能在uClibc中不能编译。
  2. uClibc在可配置性上比glibc要好。

关于uClibc与glibc更多的差异比较信息请看:Comparison of C/POSIX standard library implementations for Linux (etalabs.net)

五、制作工具?

根文件系统里面就是一堆的可执行文件和其他文件组成的?难道我们得一个一个的从网上去下载这些文件?显然这是不现实的!那么有没有人或者组织专门干这个事呢?他们负责“收集”这些文件,然后将其打包,像我们这样的开发者可以直接拿来用。

答案当然是有的,也会有多种工具来帮助我们构建根文件系统,例如 busybox 、Buildroot 、Yocto 等,其中我们常用的就是前两个,最后的 Yocto 的编译是比较复杂的,一般见得多的还是 busybox。

但是其实busybox 构建的根文件系统不齐全,很多东西需要我们自行添加,比如 lib 库文件。在我们后面的驱动开发中很多第三方软件也需要我们自己去移植,这些第三方软件有很多又依赖其他的库文件,导致移植过程非常的繁琐。busybox 仅仅只是帮我们构建好了一些常用的命令和文件,像 lib 库、 /etc 目录下的一些文件都需要我们自己手动创建,busybox 构建的根文件系统默认没有用户名和密码设置。在后续的学习,我们还要自己去移植一些第三方软件和库,比如 alsa、 iperf、 mplayer 等等。

buildroot 就会好很多,它比 busybox 更上一层楼, buildroot 不仅集成了 busybox,而且还集成了各种常见的第三方库和软件,我们需要什么就选择什么, buildroot 极大的方便了嵌入式 Linux 开发人员构建实用的根文件系统。

从 busybox 开始一步一步的构建根文件系统适合学习、了解根文件系统的组成,但是不适合做产品(主要是自己构建的话会有很多不完善、没有注意到的细节)。 buildroot 会帮我们处理好各种细节,根文件系统也会更加的合理、有效。因此在做产品的时候推荐使用 buildroot 来构建自己的根文件系统,当然了,类似 buildroot 的软件还有很多,比如 yocto。