文件系统(十一):Linux Squashfs只读文件系统介绍

news/2024/11/14 3:13:12/文章来源:https://www.cnblogs.com/liwen01/p/18329306

liwen01 2024.07.21

前言

嵌入式Linux系统中,squashfs文件系统使用非常广泛。它主要的特性是只读,文件压缩比例高。对于flash空间紧张的系统,可以将一些不需要修改的资源打包成压缩的只读文件系统格式,从而达到节省空间的目的。

另外还有个特性就是它可以分块解压缩,使用数据会更加灵活,但同时也会引入读放大的问题。

(一)制作squash文件系统

使用mksquashfs可以将文件及文件夹制作成squash文件系统镜像文件,比如我们要将squashfs-root文件夹打包成squashfs镜像文件,可以使用命令:

mksquashfs squashfs-root squashfs-root.sqsh -comp xz

这里是使用xz压缩方式进行文件压缩

(1)压缩比例测试

squashfs是一个只读压缩的文件系统,我们简单测试一下它的压缩功能

使用/dev/zero生成零数据写入到文件夹squashfs_zero对应的文件中

dd if=/dev/zero of=file1 bs=256K count=1

制作如下测试文件目录及测试文件:

biao@ubuntu:~/test/squashfs/squashfs_zero$ tree
.
├── test1
│   ├── file1
│   ├── file1_1
│   └── file1_2
├── test2
│   ├── file2
│   ├── file2_1
│   └── file2_2
├── test3
│   ├── file3
│   ├── file3_1
│   └── file3_2
└── test4├── file4├── file4_1└── file4_24 directories, 12 files
biao@ubuntu:~/test/squashfs/squashfs_zero$

文件大小如下:

biao@ubuntu:~/test/squashfs/squashfs_zero$ du -h
1.5M    ./test3
2.1M    ./test2
2.1M    ./test1
1.7M    ./test4
7.3M    .
biao@ubuntu:~/test/squashfs/squashfs_zero$

使用xz压缩方式将squashfs_zero制作成镜像文件

mksquashfs squashfs_zero squashfs_zero.sqsh -comp xz

文件大小如下:

biao@ubuntu:~/test/squashfs$ ll -h squashfs_zero.sqsh 
-rw-r--r-- 1 biao biao 4.0K Jun 26 23:48 squashfs_zero.sqsh
biao@ubuntu:~/test/squashfs$

这里是将7.3M大小squashfs_zero文件夹压缩成了一个4k大小的squashfs_zero.sqsh。当然,这里的测试是非常极端的,因为文件写入的数据都是0,如果写入随机数那压缩比例就会相差非常大了。

(二)squashfs数据分析

(1)数据布局

Squashfs的一个镜像文件它最多包含下面9个部分:Superblock、Compression options、Data blocks fragments、Inode table、Directory table、Fragment table、Export table、 UID/GID lookup table、Xattr table

最多包含的意思,也就是有些部分不是必须的,比如Compression options 部分。

它们在镜像文件中的数据分布如下图:

(2)制作测试镜像文件

使用/dev/urandom 生成随机数写到文件夹squashfs_urandom对应的文件:

dd if=/dev/urandom of=filex bs=10K count=50

制作如下测试文件目录及测试文件:

biao@ubuntu:~/test/squashfs/squashfs_urandom$ tree
.
├── test1
│   ├── file1
│   ├── file1_1
│   └── file1_2
├── test2
│   ├── file2
│   ├── file2_1
│   └── file2_2
├── test3
│   ├── file3
│   ├── file3_1
│   └── file3_2
└── test4├── file4├── file4_1└── file4_24 directories, 12 files
biao@ubuntu:~/test/squashfs/squashfs_urandom$

squashfs 文件系统的组成部分,大部分也都是压缩的,为了我们后面的数据分析,我们设置Data blocks fragments、Inode table、Directory table、Fragment table不进行压缩

制作命令如下:

mksquashfs squashfs_urandom squashfs_urandom.sqsh -comp xz  -noF -noX -noI -noD

(3)查看镜像数据信息

如果要查看squashfs的概要信息,可以使用unsquashfs命令进行查看

unsquashfs -s squashfs_urandom.sqsh

输出内容信息如下:

biao@ubuntu:~/test/squashfs$ unsquashfs -s squashfs_urandom.sqsh 
Found a valid SQUASHFS 4:0 superblock on squashfs_urandom.sqsh.
Creation or last append time Wed Jun 26 23:28:18 2024
Filesystem size 5032.60 Kbytes (4.91 Mbytes)
Compression xz
Block size 131072
Filesystem is exportable via NFS
Inodes are uncompressed
Data is uncompressed
Fragments are uncompressed
Always-use-fragments option is not specified
Xattrs are uncompressed
Duplicates are removed
Number of fragments 2
Number of inodes 37
Number of ids 1
biao@ubuntu:~/test/squashfs$

这里我们可以看到,上面我们设置-no的部分,是没有进行数据压缩的。

(4)Superblock参数分析

Superblock 在镜像文件的最开始位置,大小固定为96个字节,查看数据内容如下:

biao@ubuntu:~/test/squashfs$ hexdump  -s 0 -n 96 -C squashfs_urandom.sqsh 
00000000  68 73 71 73 11 00 00 00  ec 5c 7a 66 00 00 02 00  |hsqs.....\zf....|
00000010  02 00 00 00 04 00 11 00  cb 01 01 00 04 00 00 00  |................|
00000020  ac 02 00 00 00 00 00 00  16 9d 4e 00 00 00 00 00  |..........N.....|
00000030  0e 9d 4e 00 00 00 00 00  ff ff ff ff ff ff ff ff  |..N.............|
00000040  60 98 4e 00 00 00 00 00  2e 9b 4e 00 00 00 00 00  |`.N.......N.....|
00000050  6e 9c 4e 00 00 00 00 00  00 9d 4e 00 00 00 00 00  |n.N.......N.....|
00000060
biao@ubuntu:~/test/squashfs$

对Superblock的数据进行解析

这里我们看到几个比较关键的数据

  1. 最开始的4个字节为squashfs的magic,值为hsqs
  2. block size 是每个数据块的最大长度,这里是128KB,squashfs支持的块大小范围是:4KB~1MB
  3. compressor 表示压缩类型,这里的4表示xz压缩,其它还支持GZIP、LZMA、LZO、LZ4、ZSTD 数据压缩格式。
  4. frag count 表示有多少段数据是存储在fragments组块中
  5. 最后面是各个table组块的开始位置

(5)inode table数据分析

从superblock中我们知道inode table的开始位置是在0x4e9860位置

biao@ubuntu:~/test/squashfs$ hexdump  -s 0x4e9860 -n 718 -C squashfs_urandom.sqsh     
004e9860  cc 82 02 00 b4 01 00 00  00 00 9b e9 78 66 02 00  |............xf..|
004e9870  00 00 60 00 00 00 ff ff  ff ff 00 00 00 00 00 20  |..`............ |
004e9880  03 00 00 00 02 01 00 20  01 01 02 00 b4 01 00 00  |....... ........|
004e9890  00 00 c3 e9 78 66 03 00  00 00 60 20 03 00 ff ff  |....xf....` ....|
004e98a0  ff ff 00 00 00 00 00 d0  07 00 00 00 02 01 00 00  |................|
004e98b0  02 01 00 00 02 01 00 d0  01 01 02 00 b4 01 00 00  |................|
004e98c0  00 00 cf e9 78 66 04 00  00 00 60 f0 0a 00 ff ff  |....xf....`.....|
004e98d0  ff ff 00 00 00 00 00 80  0c 00 00 00 02 01 00 00  |................|
004e98e0  02 01 00 00 02 01 00 00  02 01 00 00 02 01 00 00  |................|
004e98f0  02 01 00 80 00 01 01 00  fd 01 00 00 00 00 b1 e9  |................|
004e9900  78 66 01 00 00 00 00 00  00 00 02 00 00 00 3a 00  |xf............:.|
004e9910  00 00 11 00 00 00 02 00  b4 01 00 00 00 00 f9 e9  |................|
004e9920  78 66 06 00 00 00 00 00  00 00 00 00 00 00 00 00  |xf..............|
004e9930  00 00 00 78 00 00 02 00  b4 01 00 00 00 00 01 ea  |...x............|
004e9940  78 66 07 00 00 00 00 00  00 00 00 00 00 00 00 78  |xf.............x|
004e9950  00 00 00 18 01 00 02 00  b4 01 00 00 00 00 08 ea  |................|
004e9960  78 66 08 00 00 00 00 00  00 00 01 00 00 00 00 00  |xf..............|
004e9970  00 00 00 f0 00 00 01 00  fd 01 00 00 00 00 ea e9  |................|
.........
.........
biao@ubuntu:~/test/squashfs$

对数据进行分析

这里有几个参数需要注意:

(a)inode_type

inode_type 是inode的类型,数值2表示普通文件,其它类型定义如下:

(b)block_sizes

这里是描述的块的大小(有可能是压缩的),这个大小需要解析。

为什么有些inode有多个block_sizes呢?这个是因为superblock中定义了一个block的最大值,如果一个文件的大小大于block最大值,那它就存在多个block_sizes。

实际每一个文件都有一个对应的inode,它都是按序分布在inode table中。

(6)directory table 数据分析

从superblock中我们知道directory table的开始位置是在0x4e9b2e位置:

biao@ubuntu:~/test/squashfs$ hexdump  -s 0x4e9b2e -n 320 -C squashfs_urandom.sqsh          
004e9b2e  1c 81 02 00 00 00 00 00  00 00 02 00 00 00 00 00  |................|
004e9b3e  00 00 02 00 04 00 66 69  6c 65 31 28 00 01 00 02  |......file1(....|
004e9b4e  00 06 00 66 69 6c 65 31  5f 31 58 00 02 00 02 00  |...file1_1X.....|
004e9b5e  06 00 66 69 6c 65 31 5f  32 02 00 00 00 00 00 00  |..file1_2.......|
004e9b6e  00 06 00 00 00 b4 00 00  00 02 00 04 00 66 69 6c  |.............fil|
004e9b7e  65 32 d4 00 01 00 02 00  06 00 66 69 6c 65 32 5f  |e2........file2_|
004e9b8e  31 f4 00 02 00 02 00 06  00 66 69 6c 65 32 5f 32  |1........file2_2|
004e9b9e  02 00 00 00 00 00 00 00  0a 00 00 00 34 01 00 00  |............4...|
004e9bae  02 00 04 00 66 69 6c 65  33 68 01 01 00 02 00 06  |....file3h......|
004e9bbe  00 66 69 6c 65 33 5f 31  98 01 02 00 02 00 06 00  |.file3_1........|
004e9bce  66 69 6c 65 33 5f 32 02  00 00 00 00 00 00 00 0e  |file3_2.........|
004e9bde  00 00 00 f8 01 00 00 02  00 04 00 66 69 6c 65 34  |...........file4|
004e9bee  28 02 01 00 02 00 06 00  66 69 6c 65 34 5f 31 60  |(.......file4_1`|
004e9bfe  02 02 00 02 00 06 00 66  69 6c 65 34 5f 32 03 00  |.......file4_2..|
004e9c0e  00 00 00 00 00 00 01 00  00 00 94 00 00 00 01 00  |................|
004e9c1e  04 00 74 65 73 74 31 14  01 04 00 01 00 04 00 74  |..test1........t|
004e9c2e  65 73 74 32 d8 01 08 00  01 00 04 00 74 65 73 74  |est2........test|
004e9c3e  33 8c 02 0c 00 01 00 04  00 74 65 73 74 34 20 80  |3........test4 .|
004e9c4e  60 70 17 00 00 00 00 00  00 90 01 01 00 00 00 00  |`p..............|
004e9c5e  60 a8 4d 00 00 00 00 00  00 f0 00 01 00 00 00 00  |`.M.............|
004e9c6e
biao@ubuntu:~/test/squashfs$

对数据进行解析:

这里最开始是一个directory header结构,它由count、start、inode number组成,它们定义如下:

每个directory header 至少需要携带一个Directory Entry,Directory Entry的定义如下:

这里的inode number 与 inode table 中的inode number是相互对应的

(7)Data blocks fragments 分析

(a)Data blocks

在我们测试的这个镜像文件中,应为使用的是xz压缩方式,属于常规压缩方式,Compression options中不会有描述,也就是说Compression options组成部分是为空。

在Superblock后面紧接着的就是Data blocks数据。

从inode table和dir table我们知道,最开始存储的是inode number为2的file1 文件。

因为我们这里的数据未进行压缩,正常应该是对比镜像文件0x60地址开始的数据与file1文件开始的数据一样的。

(b)fragments

fragments 组块设计的目的是用来存储一些小文件,将它们组合成一个block来存储,还有一种就是前面文件剩余的一小部分数据,也有可能会被存储在fragments组块中。

具体哪些数据存储到了fragments,可以查看fragments table表

(三)squashfs工作原理

(1)挂载文件系统

squashfs被挂载的时候,系统首先读取superblock块,获取squashfs基本信息和各个表格的位置。

(2)访问文件或目录

  • 系统从 superblock 获取 inode table 和 directory table 的位置。
  • 如果是访问目录,系统查找 directory table,获取目录中每个文件和子目录的名称及其 inode 编号。
  • 通过 inode 编号,从 inode table 获取文件或目录的 inode,了解文件的元数据和数据块位置。
  • 对于小文件或大文件的片段,通过 inode 中的信息查找 fragment table,获取片段的数据位置。

(四)squashfs优缺点

(1)优点

高压缩率:SquashFS 使用 gzip、lzma、lz4、xz 等压缩算法,能够显著减少文件系统的大小,节省存储空间。

只读特性:适合用于需要保护数据完整性的环境,如嵌入式系统和操作系统的只读镜像。

高效的随机访问:SquashFS 支持高效的随机读取访问,适合读取频繁的场景。

碎片处理: 通过 Fragment Table,SquashFS 能有效处理小文件,减少存储碎片,提高存储效率。

存储和性能优化: 支持文件、目录和 inode 的压缩,减少了存储占用和 I/O 操作,提高了性能。

数据完整性:SquashFS 可以包含校验和,用于确保数据的完整性和防止数据损坏。

(2)缺点

只读特性:SquashFS 是只读的,不能直接修改文件系统中的文件或目录。这意味着需要更新或更改文件系统时,必须重新生成整个文件系统镜像。

压缩开销:虽然读取速度较快,但解压缩过程仍然需要一定的 CPU 资源。在低性能的嵌入式系统中,这可能会对系统性能产生一定影响。

内存消耗:在读取大文件时,解压缩过程可能会消耗大量内存,尤其是在资源受限的嵌入式系统中,这可能会成为一个瓶颈

结尾

上面介绍了squashfs文件系统的数据组成和它们相互工作的原理以及squash文件系统的优缺点。

这里提一个问题:如果根文件系统使用squashfs文件系统,main执行文件也位于根文件系统中,在不考虑双分区备份升级的情况下,要怎么升级根文件系统?

在main程序中直接将新squashfs镜像文件写入到根文件系统所在的mtdblock中是否可以?会不会存在根文件系统更新异常的风险?

 

-------------------End-------------------
如需获取更多内容
请关注 liwen01 公众号

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

《抓娃娃》电影迅雷百度云下载/HD2.59GB高清版磁力种子资源

电影《抓娃娃》自2024年7月16日在中国大陆上映以来,迅速成为暑期档的一部热门影片。该片由闫非和彭大魔联合执导,沈腾和马丽领衔主演,以其独特的剧情设定和深刻的家庭教育主题,引发了广泛的讨论和关注。本文将从影片的基本信息、剧情解析、演员表现、主题探讨以及观众反馈等…

C# 网络编程:.NET 开发者的核心技能

原文:C# 网络编程:.NET 开发者的核心技能 - 小码编匠 - 博客园 (cnblogs.com)一、HTTP 请求 HTTP(Hypertext Transfer Protocol)是互联网上应用最为广泛的一种网络协议,主要用于从万维网服务器传输超文本到本地浏览器的传输协议。 在C#中,处理HTTP请求有多种方式,从传统…

转行自我介绍思路参照

一 面试官你好 很高兴来参加这次的面试沟通,我自从毕业以来从事的是IT行业的软件测试工作, 这些年的工作让我系统的掌握了软件测试的技能和优秀的与人沟通的能力。那么过往的工作呢 也取得了不错的成绩, 那么也是一路从测试工程师到高级测试。 二、但是比较遗憾的是,在…

NPU 芯片技术杂谈

NPU 芯片技术杂谈 对于AI芯片并无明确统一的定义,广义上所有面向人工智能(Artificial Intelligence,AI),包括Training(训练)和Inference(推理)应用的芯片都可以被称为AI芯片。参考文献链接 https://www.zhihu.com/question/64895191 https://zhuanlan.zhihu.com/p/7992114…

windows 如何暂停更新

使用windows 系统的伙伴都深受其扰,动不动就要强制更新,并且无法长时间关闭更新。这里推荐一个工具来禁止更新。 下载地址 https://github.com/WereDev/Wu10Man/releases

珂朵莉树

好文章 个人理解:珂朵莉树其实就是\(set\)大法,就是暴力,可以构造特殊数据卡掉,但是在随机数据的情况下,它是非常快的 struct ASD {ll l,r;mutable ll val;//方便更改,指针是常量,必须加上mutablebool operator < (const ASD& A)const{return l<A.l;}ASD(ll a,ll…

云原生 .NET Aspire 8.1 新增对 构建容器、编排 Python的支持

.NET Aspire 用于云原生应用开发,提供用于构建、测试和部署分布式应用的框架,这些应用通常利用微服务、容器、无服务器体系结构等云构造。2024年7月23日宣布的新 8.1 版本是该平台自 5 月正式发布以来的第一次重大更新,Microsoft 对 .NET Aspire 的第一个重大更新Aspire 8.1…

读零信任网络:在不可信网络中构建安全系统04最小特权

最小特权1. 公钥基础设施 1.1. PKI 1.2. 数字证书本身并不能解决身份认证问题 1.2.1. 需要一种方法来验证获得的公钥的确属于某人 1.2.2. 公钥基础设施(PKI)解决了这个问题 1.3. PKI定义了一组角色及其职责,能够在不可信的网络中安全地分发和验证公钥 1.4. PKI的目标是允许无…

Linux工作原理13用户环境

13用户环境 本书主要关注 Linux 系统中通常作为服务器进程和交互式用户会话基础的部分。但是,系统和用户最终还是要在某个地方相遇。在这一点上,启动文件扮演着重要角色,因为它们为 shell 和其他交互式程序设置了默认值。它们决定了用户登录时系统的行为方式。 大多数用户不…

[vue3] Vue3源码阅读笔记 reactivity - baseHandlers

vue3的reactivity模块的baseHandlers主要为普通对象和数组的Proxy实现了拦截操作的处理,通过3个类分别实现了getter和setter等操作的拦截,并对一些数组原型上的方法做了特殊处理,使得数组操作可以更好地适配vue的响应式系统。源码位置:https://github.com/vuejs/core/blob/…

Go语言结构体(struct)面向对象编程进阶篇(封装,继承和多态)

作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任。 目录一.Go语言的封装(encapsulation)实现1.什么是封装(encapsulation)2.封装(encapsulation)的好处3.golang如何实现封装(encapsulation)4.代码实现4.1 代码组织结构4.2 创建go.mod文件4.3 dongman.go4.4 mai…

解决历理 如何用cmd运行小键盘

cmd不可以直接运行键盘上的按键,但是可以打开电脑上的软键盘来对应键盘键。 打开软键盘来运行键盘上的按键步骤如下: 1、点击Windows徽标键和R键,在出现的窗口中输入cmd; 2、点击确定,弹出命令提示符窗口; 3、在命令提示符窗口输入osk,点击键盘上的Enter,屏幕上就会出现…