文件系统详解

发布时间 2023-11-14 16:22:50作者: caseyzz

1.根文件系统

根文件系统:linux内核加载的第一个文件系统。
 Rootfs是一个特殊的文件系统,它是Linux操作系统中的根文件系统。它包含了操作系统所需的基本文件和目录结构,如/bin、/usr、/etc等。在Linux启动过程中,内核需要加载rootfs,使得系统能够正常运行。

rootfs的特点:

  • 只读性:rootfs通常是只读的,这意味着系统运行时无法对其进行修改。只读属性可以保证rootfs的完整性和稳定性,防止意外的修改或破坏。
  • 轻量级:rootfs只包含最基本的文件和目录结构,不包含大型应用程序或数据文件,因此它比较小巧,占用系统资源较少。
  • 可移植性:由于rootfs相对简单,它可以很容易地在不同的硬件平台上进行移植和使用。

MTD

 mtd(Memory technology device),指存储技术设备的意思,多指flash。

cat /proc/mtd:可以看到当前系统的各个mtd情况

dev:    size   erasesize  name
mtd0: 00280000 00040000 "sbl"
mtd1: 00280000 00040000 "mibib"
mtd2: 01600000 00040000 "efs2"
mtd3: 00500000 00040000 "sys_rev"
mtd4: 00300000 00040000 "rawdata"
mtd5: 00280000 00040000 "cust_info"
mtd6: 00140000 00040000 "reserved"
mtd7: 00280000 00040000 "tz"
mtd8: 00280000 00040000 "b_tz"
mtd9: 00180000 00040000 "devcfg"
mtd10: 00180000 00040000 "rpm"
mtd11: 00180000 00040000 "b_rpm"
mtd12: 00180000 00040000 "aboot"
mtd13: 00180000 00040000 "b_aboot"
mtd14: 00e00000 00040000 "boot"
mtd15: 00e00000 00040000 "b_boot"
mtd16: 00140000 00040000 "misc"
mtd17: 00140000 00040000 "sec"
mtd18: 00140000 00040000 "rawpersist"
mtd19: 00140000 00040000 "secdata"
mtd20: 00140000 00040000 "b_secdata"
mtd21: 02680000 00040000 "modem"
mtd22: 02680000 00040000 "b_modem"
mtd23: 04000000 00040000 "system"
mtd24: 04000000 00040000 "b_system"
mtd25: 01200000 00040000 "persist"
mtd26: 01040000 00040000 "quecrw"
mtd27: 05040000 00040000 "oemapp"
mtd28: 05040000 00040000 "b_oemapp"
mtd29: 01ac0000 00040000 "userdata"

以上mtd设备是根据分区信息而来(存放在flash上),可查看partition_nand.xml

cat /proc/partitions 查看

major minor  #blocks  name

  31        0       2560 mtdblock0
  31        1       2560 mtdblock1
  31        2      22528 mtdblock2
  31        3       5120 mtdblock3
  31        4       3072 mtdblock4
  31        5       2560 mtdblock5
  31        6       1280 mtdblock6
  31        7       2560 mtdblock7
  31        8       2560 mtdblock8
  31        9       1536 mtdblock9
  31       10       1536 mtdblock10
  31       11       1536 mtdblock11
  31       12       1536 mtdblock12
  31       13       1536 mtdblock13
  31       14      14336 mtdblock14
  31       15      14336 mtdblock15
  31       16       1280 mtdblock16
  31       17       1280 mtdblock17
  31       18       1280 mtdblock18
  31       19       1280 mtdblock19
  31       20       1280 mtdblock20
  31       21      39424 mtdblock21
  31       22      39424 mtdblock22
  31       23      65536 mtdblock23
  31       24      65536 mtdblock24
  31       25      18432 mtdblock25
  31       26      16640 mtdblock26
  31       27      82176 mtdblock27
  31       28      82176 mtdblock28
  31       29      27392 mtdblock29
 253        0      56296 ubiblock0_0
 253        1      32240 ubiblock1_0
 179        0    7653888 mmcblk0
 179        1    7653880 mmcblk0p1
 179       32       4096 mmcblk0rpmb
 253        2      73656 ubiblock3_0

可以看到分区里有mtd,ubiblock和mmc设备。

ubi

 ubi(Unsorted Block Images),是一种原始flash设备的卷管理系统。这个系统能在一个物理的flash设备上管理多个卷并且能在整个flash芯片上实现损耗均衡。
 一个UBI卷就是一串连续的逻辑擦除块(LEBS)。

ubifs

 Ubi文件系统是为了闪存设备而设计的。与传统文件系统相比,Ubi可以更好的处理flash设备上的坏块,因为它可以将坏块转换为虚拟块,并将数据移动到其他可用块。
 ubi文件系统可以跨多个flash设备进行分区,并支持多个Ubi卷。
 Ubi文件系统支持动态卷大小调整,这意味着可以根据需要增加或减小卷的大小。

1.制作ubifs
 需要使用到mkfs.ubifs工具

${QL_SDK_DIR}/ql_fakeroot $(QL_TOOLS_BIN_DIR)/mkfs.ubifs -r ${QL_USRDATA_DIR} -o $(QL_TARGET_DIR)/usrdata.ubifs $(QL_MKUBIFS_ARGS) --selinux=${QL_SELINUX_DIR}/file_contexts -F

2.制作ubi镜像

$(QL_TOOLS_BIN_DIR)/ubinize  -o $(QL_TARGET_DIR)/usrdata.ubi $(QL_UBINIZE_ARGS) $(QL_TOOLS_CONF_DIR)/ubinize_usrdata_ubifs.cfg 

需要使用到ubi配置文件/tools/conf/ubinize_usrdata_ubifs.cfg

[volume]
mode=ubi
image=./usrdata.ubifs
vol_id=0
vol_type=dynamic
vol_name=usrdata
vol_flags=autoresize
  • 动态卷0,命名为usrdata;卷的内容取自usrdata.ubifs

UBIFS工作在UBI卷之上,不能在MTD设备之上运行

squashfs

 Squashfs是一套基于Linux内核使用的压缩只读文件系统。该文件系统能够压缩系统内的文档,inode以及目录,文件最大支持2^64字节
特点:

  • 数据(data),节点(inode)和目录(directories)都被压缩
  • 保存了全部的32位uid/gids和文件的创建时间
  • 支持多达4G的文件系统
  • 节点和目录都是高度压缩, 所有压缩的节点长度平均在8个字节左右
  • squashfs可以有更大的块大小, 这样可以达到比4K块大小更大的压缩率
  • squashfs引进了碎片块(fragment blocks)的概念: 一种将许多比块小的文件存储在一个块中, 以达到更大的压缩率
  • 重复的文件会被检测并删除掉
  • 同时支持big和little endian架构

特性:
 squashfs文件系统的内容是在创建时被压缩并且固定下来,无法再进行修改或扩展。因此,无论实际使用的空间有多少,df -h命令都会显示使用率为100%。

制作suqashfs

${QL_SDK_DIR}/ql_fakeroot $(QL_TOOLS_BIN_DIR)/mkfs.ubifs -r ${QL_USRDATA_DIR} -o $(QL_TARGET_DIR)/usrdata.ubifs $(QL_MKUBIFS_ARGS) --selinux=${QL_SELINUX_DIR}/file_contexts -F

制作镜像

$(QL_TOOLS_BIN_DIR)/ubinize  -o $(QL_TARGET_DIR)/usrdata.ubi $(QL_UBINIZE_ARGS) $(QL_TOOLS_CONF_DIR)/ubinize_usrdata_ubifs.cfg 
[oemapp_volume]
mode=ubi
image=./oemapp.squashfs
vol_id=0
vol_type=dynamic
vol_name=oemapp
vol_flags=autoresize

ubifs与squashfs

 ubifs是运行在UBI卷之上的文件系统,而squashfs是运行在block device上的文件系统。UBI提供了能够在ubi卷之上创建只读块设备的特性,这使得squashfs也能够运行在ubi卷上。

R/O block devices on top of UBI volumes
 UBI允许在UBI卷上创建只读块设备,该卷适用于只读的,面向块的文件系统,例如squashfs.
 UBI允许在UBI卷上创建块设备,但是有限制吧:

  • 只读操作。
  • 串行化 I/O 操作,但请记住 NAND 驱动内核也已经串行化了所有 I/O。

 块设备对于在UBI卷上安装只读的常规文件系统非常有用。以squashfs为例,它可以作为NADN设备之上的轻量级只读rootfs。

  • 基于任意MTD设备,attach之后创建2个UBI卷(volume0和volume1)
  • 将squashfs镜像存入volume0,将ubifs镜像存入volume 1
  • 基于volume0 创建 ubi block device,使用该block device 挂载 squashfs
  • 使用vloume 1挂载ubifs

挂载
 对于ubifs可以直接挂载
 对于squashfs不可以直接挂载,需要创建ubi block。

ubiblock -c "/dev/ubi3_0"

执行完会生成一个ubi块设备/dev/ubiblock3_0,通过这个设备文件才能实现suqashfs文件系统的挂载。

UBI设备创建

ubinfo -a

ubi3
Volumes count:                           1
Logical eraseblock size:                 253952 bytes, 248.0 KiB
Total amount of logical eraseblocks:     321 (81518592 bytes, 77.7 MiB)
Amount of available logical eraseblocks: 0 (0 bytes)
Maximum count of volumes                 128
Count of bad physical eraseblocks:       0
Count of reserved physical eraseblocks:  20
Current maximum erase counter value:     1
Minimum input/output unit size:          4096 bytes
Character device major/minor:            232:0
Present volumes:                         0

Volume ID:   0 (on ubi3)
Type:        dynamic
Alignment:   1
Size:        297 LEBs (75423744 bytes, 71.9 MiB)
State:       OK
Name:        oemapp
Character device major/minor: 232:1

会显示所有的ubi设备及分卷。

那么这些ubi设备是如何创建的?

通过ubiattach来创建UBI设备(/etc/init.d/find_partitions.sh)

ubiattach -m ${mtdnum} -d ${ubinum} ${UbiCtrl}

ubinum指ubi设备号

作用:
链接MTD设备(原始Flash设备)到UBI并且创建相应的UBI设备。

疑问:

du -sh 读取文件实际占用空间

df -h 查看挂载的磁盘使用空间

 如图所示:oemapp目录 du -sh 显示99M+,这个所有文件实际占用空间。

 这个大小对应的是编译时整个oemapp目录下的文件大小,可以通过属性查看。
而df -h里显示的27M+,是/dev/ubiblock3_0 这个分卷的大小。通过上面的学习可以了解到,这个分卷实际就是编译生成的squashfs,可以查看编译target目录下生成的oemapp.squashfs文件的大小。