如何理解OpenWRT上的SquashFS 和 OverlayFS 机制,它们何区别?以OpenFi 5Pro为例讲解这两者之间的关系,以及Linux的squashfs固件类型
很多同学不理解squashfs固件类型到底是什么概念,也分不清overlay是什么意思,那今天就正好加班写个文章详细说说这两者的关系,正好利用手头上的OpenFi 5Pro
作为演示,它就运用了经典的SquashFS 文件系统,看看它们究竟存在什么关系。
1. SquashFS 和 OverlayFS 机制
-
SquashFS 分区:SquashFS 是一种只读的压缩文件系统,用于存储固件的核心系统文件(例如
/bin
,/sbin
,/lib
,/etc
等)。由于 SquashFS 是只读的,文件无法被直接修改,因为SquashFS 中的数据是以压缩的形式存在的,只有系统启动时才会把他解压出来放到内存
当中去让系统读取,这就是为什么它不能被修改,如果他能被修改,那么每次关机之前都要对他进行压缩,如果系统直接断电,岂不是直接崩溃? -
OverlayFS 分区:为了支持文件的修改和持久化,OpenWRT 使用 OverlayFS,它是一个联合挂载文件系统,将一个只读的底层文件系统(SquashFS)与一个可读写的上层文件系统(通常是 JFFS2 或 F2FS)结合在一起。上层文件系统通常被称为
overlay
分区,当文件被修改的时候他就会立马被写入到overlay里去,区别就在于他是不用压缩的,也就是说你的文件是6kb,那么他就占用overlay的6kb空间,所以你在软件安装界面看到的剩余空间其实就是overlay的剩余空间。
2. 文件修改和保存原理
-
当系统启动时,内核会首先挂载只读的 SquashFS 文件系统作为根文件系统(
/rom
)。 -
然后,内核会创建并挂载一个可读写的
overlay
分区(一般挂载在/overlay
)。 -
OverlayFS 将这两个分区结合在一起,并将其挂载为最终的根文件系统
/
,在该根文件系统上进行所有操作时,系统会呈现出读写状态。 -
当热然它们都是被挂载在内存当中的,当文件发生改变时系统才会把他们写入flash。
文件修改时的行为:
- 读取操作:当系统尝试读取一个文件时,首先会在
overlay
分区(可写层)查找。如果文件不存在,则会从SquashFS
分区(只读层)读取。 - 写入操作:当系统尝试修改一个文件时,该文件会被复制到
overlay
分区。此后,对该文件的修改操作都只会作用在overlay
分区,SquashFS
上的原始文件不会受到影响。 - 新增文件:如果创建了一个新文件,它会直接被写入
overlay
分区。
3. 分区布局示例
以下是 OpenFi 5Pro上的分区布局(flash大小为64MB):
root@OpenFi:~# df -h
Filesystem Size Used Available Use% Mounted on
/dev/root 14.0M 14.0M 0 100% /rom
tmpfs 248.7M 780.0K 247.9M 0% /tmp
/dev/mtdblock6 46.8M 1.9M 44.9M 4% /overlay
overlayfs:/overlay 46.8M 1.9M 44.9M 4% /
tmpfs 512.0K 0 512.0K 0% /dev
观察Mounted on
一列:
/rom
: 只读的 SquashFS 文件系统,它的大小就是固件的大小。/overlay
: 可读写的分区,用于保存修改,也就是用户的数据。/
: 最终的根文件系统,由 OverlayFS 组合而成。- 为什么**
/overlay
** 和 **/
**的大小一样?其实很容易理解,我们看看flash的分区情况:
root@OpenFi:~# cat /proc/mtd
dev: size erasesize name
mtd0: 00030000 00010000 "bootloader" # 192 KB 引导分区
mtd1: 00010000 00010000 "config" # 64 KB 参数配置分区
mtd2: 00010000 00010000 "factory" # 64 KB 存一些出厂的MAC地址、无线校准参数等等
mtd3: 03f00000 00010000 "firmware" # 63 MB 这里就是存系统文件的分区了
mtd4: 002b769e 00010000 "kernel" # 2.72 MB firmware里的内核分区
mtd5: 03c48962 00010000 "rootfs" # 60.77 MB firmware里的文件系统分区
mtd6: 02ec0000 00010000 "rootfs_data" # 46.75 MB rootfs里的overlay分区(rootfs的大小减去固件的大小)
- 也就是说其实
/dev/mtdblock6
对应的就是以上的rootfs_data
,而overlayfs:/overlay
就是挂载到/dev/mtdblock6
上的overlayfs文件系统,他们本来就是一个东西啊。
4. 检查你的设备 overlay
使用情况
用以下命令检查 overlay
分区的挂载情况和使用情况:
df -h
比如上面的例子里得到以下结果:
5. overlay
分区删掉会发生什么?
答案是:“恢复出厂设置。。。”
此操作会清空所有的用户修改和新增文件,重启后系统会恢复到刷机时的默认状态。
6. 哪些行为会保存文件到 overlay
中
- 当用户或者系统使用
UCI
的时候都会将配置文件保存到overlay
中,比如:
uci set system.@system[0].hostname='OpenFi'
uci commit
- 用户安装的ipk应用程序
- 再或者用户或者程序创建的除了
tmp
临时目录以外的所有文件都会保存到overlay
当中去。
如何给openwrt扩容?
- 既然我们知道了overlay的作用是存储用户的数据,那么我们只需要将overlay的位置转移到内存更大的地方去,就能实现扩容。当然了,前提是你的flash还有未应用的空间,或者你有外置的存储设备可以被openwrt识别。
- 具体的扩容方法其实有很多教程,具体可以自行搜索。比如用cfdisk工具进行修改等。
总结:
- 不可修改的文件:保存在 SquashFS 中,无法被直接修改。
- 被修改和新增的文件:保存在
overlay
分区中,这部分是可读写的,会在系统重启后保留修改。
为什么要选择这种机制?
squashfs
一般用于小闪存的机器中,这种分区布局设计使得 OpenWRT 可以在很小的闪存中存储一个几十MB甚至更大的系统文件,同时得益于内存优越的读写速度,使得系统可以非常流畅的运行。这也是 OpenWRT 使用 SquashFS 文件系统的一个主要原因。