简介

Linux 的目录结构的最顶层是一个被称为“/”的根目录。系统加载 Linux 内核之后,就会挂载一个设备到根目录上。存在于这个设备中的文件系统被称为根文件系统。所有的系统命令、系统配置以及其他文件系统的挂载点都位于这个根文件系统中。根文件系统通常存放于内存和 Flash 中,或是基于网络的文件系统。根文件系统中存放
了嵌入式系统使用的所有应用程序、库以及其他需要用到的服务。下面列出了根文件系统的顶层目录。
image.png
通用的 Linux 系统的根文件系统中会包括根文件系统顶层目录结构图中所有的目录,不过在嵌入式系统中,需要精简根文件系统。下面是嵌入式系统可以忽略的一些文件。
image.png

嵌入式常用文件系统简介

嵌入式系统中常用文件系统包括有 squashfscramfsJFFS2NFSyaffs2 以及 ext4。它们的特点如下:

  • cramfs 和 JFFS2 具有好的空间特性,很适合嵌入式产品应用。
  • cramfs 和 squashfs 为只读文件系统。
  • JFFS2 为可读写文件系统。
  • NFS 文件系统适用于开发初期的调试阶段,为网络文件系统。
  • yaffs2 文件系统只用于 NAND Flash。
  • JFFS2 文件系统、cramfs 文件系统和 squashfs 文件系统主要用于 spi flash; yaffs2 只能用于nand,ext4 一般用于 eMMC。

    cramfs

    cramfs 是针对 Linux 内核 2.4 之后的版本所设计的一种新型文件系统,使用简单,加载容易,速度快。
    cramfs 的优缺点如下:

  • 优点:将文件数据以压缩形式存储,在需要运行时进行解压缩,能节省 Flash 存储空间。

  • 缺点:由于它存储的文件是压缩的格式,所以文件系统不能直接在 Flash 上运行。同时,文件系统运行时需要解压数据并拷贝至内存中,在一定程度上降低读取效率。另外 cramfs 文件系统是只读的。

如果想要在单板运行的 Linux 中提供 cramfs 的能力,必须要在编译内核时把 cramfs 的选项加入。在 make menuconfig 后,进入“File>systems”,选择“miscellaneous filesystems”,最后选中其中的“Compressed ROM file system support”。
mkfs.cramfs 是用来制作 cramfs 文件系统映象的工具。通过这个工具处理已经制作好的
根文件系统,就可以生成 cramfs 文件系统的映象(这类似于我们把光盘制作成 ISO 文
件映像)。具体操作如下所示:

  1. mkfs.cramfs ./rootbox ./cramfs-root.img

其中,rootbox 是之前已经制作好的根文件系统,cramfs-root.img 是生成的 cramfs 文件系统映像文件

squashfs

squashfs 文件系统也是一种压缩的只读文件系统。与 cramfs 相比,能提供更大的压缩
比,支持更大的镜像和文件。squashfs 文件系统的支持需要配置内核

  1. File systems --->
  2. [*] Miscellaneous filesystems --->
  3. <*> SquashFS 4.0 - Squashed file system support //支持squashfs文件系统
  4. [*] Include support for XZ compressed file systems //如果是XZ算法

mksquashfs 工具是用来制作 squashfs 文件系统镜像的工具,命令如下):

  1. mksquashfs ./rootbox rootbox.squashfs -no-fragments -noappend -comp xz

rootbox 是要文件系统目录,rootbox.squashfs 是要制作的文件系统镜像名称。指定了对应的算法。xz

JFFS2

JFFS2 是 RedHat 的 David Woodhouse 在 JFFS 基础上改进的文件系统,是用于微型嵌入式设备的原始闪存芯片的实际文件系统。JFFS2 文件系统是日志结构化的可读写的文件系统。
JFFS2 的优缺点如下:

  • 优点:使用了压缩的文件格式。最重要的特性是可读写操作。
  • 缺点:JFFS2 文件系统挂载时需要扫描整个 JFFS2 文件系统,因此当 JFFS2 文件系统分区增大时,挂载时间也会相应的变长。使用 JFFS2 格式可能带来少量的Flash 空间的浪费,这主要是由于日志文件的过度开销和用于回收系统的无用存储单元,浪费的空间大小大致是若干个数据段。JFFS2 的另一缺点是当文件系统已 满或接近满时,JFFS2 运行速度会迅速降低。这是因为垃圾收集的问题。

加载 JFFS2 文件系统时的步骤如下:

  • 步骤 1 扫描整个芯片,对日志节点进行校验,并且将日志节点全部装入内存缓存。
  • 步骤 2 对所有日志节点进行整理,抽取有效的节点并整理出文件目录信息。
  • 步骤 3 找出文件系统中无效节点并且将它们删除。
  • 步骤 4 最后整理内存中的信息,将加载到缓存中的无效节点释放。

由此可以看出虽然这样能有效地提高系统的可靠性,但是在一定程度上降低了系统的速度。尤其对于较大的闪存芯片,加载过程会更慢。为了使内核支持 JFFS2 文件系统,必须在编译内核时把 JFFS2 的选项加入(我们发布
的内核默认已经加入了支持)。在 make menuconfig 后,进入“File>systems”,选择
“miscellaneous filesystems”,最后选中其中的“Journalling FLASH File System v2 (JFFS2) support”选项。

  1. mkfs.jffs2 d ./rootbox -l e 0x20000 -o jffs2-root.img # 指定块大小为 128K字节

NFS

使用 cramfs 和 JFFS2 时,需要先将根文件系统映像烧入 Flash,系统启动时会从 Flash中加载。但是在系统开发或移植的初期,需要经常修改或者添加应用程序。每修改一次就需要重新烧入一次,这样做不仅耗费时间,而且对 Flash 的寿命会有影响。NFS 是一种分布式的文件系统,用于共享文件和打印机。它允许用户调用挂载远端的文件系统或设备来实现共享,使用方式与挂载本机的文件系统一样。NFS 使用“客户-服务器”模型。在这种模型中,服务器输出需要共享的目录,客户可通过网络挂载这些目录并访问其中的文件。
使用 initramfs 作为根文件系统,系统启动之后再挂在 NFS 文件系统,这个过程不需要任何对 Flash 的操作,修改应用程序完全在 Linux 服务器中进行,非常适于开发初期的调试阶段。在 Linux 服务器配置 NFS 根文件系统的方法为:编辑/etc/exports 配置文件,添加路径及参数,然后执行/etc/init.d/ nfs start 启动 NFS 服务。

  • 步骤 1 制作 initramfs 镜像并启动系统initramfs 文件系统需要内核的支持,需要配置内核(配置方法请参见 2.2 配置内核):
    1. General setup --->
    2. [ ] Initial RAM filesystem and RAM disk (initramfs/initrd) support

yaffs2

yaffs2 是专门为 NANDFlash 设计的嵌入式文件系统。它是日志结构的文件系统,提供了损耗平衡和掉电保护,可以有效地避免意外掉电对文件系统一致性和完整性的影响。
yaffs2 的优缺点如下:

  • 优点
    • 专门针对 NANDFlash,软件结构得到优化,速度快。
    • 使用硬件的 spare area 区域存储文件组织信息,启动时只需扫描组织信息,启动比较快。
    • 采用多策略垃圾回收算法,能够提高垃圾回收的效率和公平性,达到损耗平衡的目的。
  • 缺点
    • 没有采用压缩的文件格式。包含同样内容,yaffs2 镜像文件要比 jffs2 镜像文件大。
      1. mkfs.yaffs2 ./rootfs/ ./images/rootfs_2k_1bit.yaffs2 2048 1
      2. 其中,rootbox 是之前已经制作好的根文件系统,2k_1bit.yaffs2 是生成的 yaffs2 文件系
      3. 统镜像文件。2048 表示页大小,1 表示 ECC 类型。