squashFS 文件系统

squashFS 文件系统

简介

Squashfs(.sfs)是一套供Linux核心使用的GPL开源只读压缩文件系统。
支持的压缩方式有gzip、lzma1、lzma2(xz)、lzo、lz4
它有以下特性

数据、目录、文件节点(inodes)均被压缩
存储完整的uid/gid和文件创建时间
支持最大2^64字节大小的文件
文件节点(inode)和目录数据都被高度压缩,得到的数据以字节为分界,每个被压缩的文件节点(inode)平均长8个字节
能使用最大1M的块大小(block size),128KB为默认值而且具有更好的压缩率
能发现重复的文件并移除
支持大小端架构
(翻译自squashfs官网

由于squashFS可以在不需要解压的情况下直接挂载,因此有许多应用场景,例如:
1、安装Linux时用的live cd
2、小型嵌入式设备中的rootfs。rootfs一般以压缩好的形式存放在ROM中,如果开机时把整个rootfs都解压到内存里再读取,对于ROM和RAM容量一般都很小的小型嵌入式设备来说性价比太低。

使用

//以下所有操作均基于ubuntu 14.04.4 LTS
//使用的squashfs-tools为4.2版本

squashfs使用的工具为squashfs-tools,使用以下命令安装

sudo apt-get install squashfs-tools

打包使用mksquashfs,解包使用unsquashfs,使用方法参照-h

使用这个命令安装的版本默认支持的压缩方式有gzip、lzo、xz,如果想使用其他的压缩方式,需要从官网下载源码自行编译
编译时,需要修改源码的Makefile,文件开头就是压缩选项,请根据注释选择自己需要的压缩方式

如果需要修改squashfs文件系统的flag,在运行程序时传入参数或者修改mksquashfs.c,搜索注释“filesystem flags for building”

如果需要修改lzma压缩参数(参考1:wikipedia)(参考2:stackoverflow),修改lzma_wrapper.c中的LzmaCompress函数调用参数

superblock

squashFS的超级块定义位于squashfs_fs.h中的”squashfs_super_block”结构体

struct squashfs_super_block {
unsigned int        s_magic;
unsigned int        inodes;
int                    mkfs_time;
unsigned int        block_size;
unsigned int        fragments;
unsigned short        compression;
unsigned short        block_log;
unsigned short        flags;
unsigned short        no_ids;
unsigned short        s_major;
unsigned short        s_minor;
squashfs_inode        root_inode;
long long        bytes_used;
long long        id_table_start;
long long        xattr_id_table_start;
long long        inode_table_start;
long long        directory_table_start;
long long        fragment_table_start;
long long        lookup_table_start;
};

s_magic:0x73717368,ascii表示为hsqs,squashfs的魔数
inodes:文件节点数
mkfs_time:此文件系统创建时间
block_size:块大小
fragments:分段数
compression:文件系统所使用的压缩方法

#define ZLIB_COMPRESSION    1
#define LZMA_COMPRESSION    2
#define LZO_COMPRESSION        3
#define XZ_COMPRESSION        4
#define LZ4_COMPRESSION        5

block_log:#未知,实际用于计算块大小时的一个位移参数
flags:文件系统属性标志

#define SQUASHFS_NOI            0        //SQUASHFS_UNCOMPRESSED_INODES
#define SQUASHFS_NOD            1        //SQUASHFS_UNCOMPRESSED_DATA
#define SQUASHFS_CHECK            2
#define SQUASHFS_NOF            3        //SQUASHFS_UNCOMPRESSED_FRAGMENTS
#define SQUASHFS_NO_FRAG        4        //SQUASHFS_NO_FRAGMENTS
#define SQUASHFS_ALWAYS_FRAG    5        //SQUASHFS_ALWAYS_FRAGMENTS
#define SQUASHFS_DUPLICATE        6        //SQUASHFS_DUPLICATES
#define SQUASHFS_EXPORT            7        //SQUASHFS_EXPORTABLE
#define SQUASHFS_NOX            8        //SQUASHFS_UNCOMPRESSED_XATTRS
#define SQUASHFS_NO_XATTR        9        //SQUASHFS_NO_XATTRS
#define SQUASHFS_COMP_OPT        10        //SQUASHFS_COMP_OPTS

#define SQUASHFS_BIT(flag, bit)        ((flag >> bit) & 1)

no_ids:文件中不同的uid和gid的数量和,例如有uid(root(0),user(1000)),有gid(root(0),user(1000),tty(5)),则不同的uid+gid共有3个,no_ids为3
s_major,s_minor:mksquashfs的大小版本
root_inode:#未知,64bit,可能是root_inode的指针

剩余的是文件系统大小和各种表的入口

推荐一个快速查找superblock各定义的值的小程序,squashfs-info(github