文章目录
minix文件系统二进制分析1:刚刚格式化后的文件系统
工作几年来,用过不少文件系统,甚至手把手移植和裁剪过Fatfs文件系统,但是却对文件系统内部的存储方式和玩儿法一直一无所知,正巧最近翻阅Linux0.12源码注释这本书,里面专门为文件系统章节写了100余页,不过剖析的是minix文件系统,这是早期在minix系统上用的一种简单的文件系统,所谓麻雀虽小五脏俱全,正好可以做来了解文件系统之用,从而洞察后来更加复杂的文件系统,万变不离其宗,深入剖析了minix文件系统,理解其他类型的文件系统也就举一反三手到擒来了。
创建硬盘
通过在虚拟机里创建一个16M的硬盘作为起点,来一步一步分析minix文件系统。
添加一个16M的块设备
在Ubuntu虚拟机中添加一个大小为16M的块设备,此时还没有将其进行文件系统格式化
格式化块设备
在终端输入 fdisk -l指令查看所有块设备信息,可以找到 /dev/sdb设备即为上一步骤创建的硬盘。
格式化硬盘为minix文件系统
根据格式化后的信息,我们可以知道,硬盘上的minix文件系统一共有5472个inodes,也就是说最多能在上面创建5472个文件,一共16384个数据块,Firstdatazone=176 表示第一个node节点位于第176个块,Maxsize表示每个文件支持的最大长度。
接下来,我们使用hexdump -C /dev/sdb > minix_orig.dat 将硬盘的2进制数据dump出来,如下图所示,特备强调,此时的minix文件系统只有一个根目录,其他什么都没有,干干净净。
minix文件系统的存储结构
超级块
超级块代表了整个文件系统,超级块是文件系统的控制块,有整个文件系统信息,一个文件系统所有的inode都要连接到超级块上,可以说,一个超级块就代表了一个文件系统。
值得一提的是,当我们在linux终端mount某个块设备时,内核会读取超级块的信息,完成文件系统的挂载。
linux中超级块数据结构
内核挂载文件系统时,先去获得超级块的信息并保存在内核数据结构中
/*
* minix super-block data on disk
*/
struct minix_super_block {
__u16 s_ninodes;
__u16 s_nzones;
__u16 s_imap_blocks;
__u16 s_zmap_blocks;
__u16 s_firstdatazone;
__u16 s_log_zone_size;
__u32 s_max_size;
__u16 s_magic;
__u16 s_state;
__u32 s_zones;
};
元素 | 十六进制 | 十进制 | 含义 |
---|---|---|---|
s_ninodes | 0x1560 | 5472 | 一共5472个inode节点 |
s_nzones | 0x4000 | 4096 | 一共16384个 data block |
s_imap_blocks | 0x0001 | 1 | inode位图占用1个block |
s_zmap_blocks | 0x0002 | 2 | data block位图占据2个block |
s_firstdatazone | 0x00b0 | 176 | 第一个data block的编号为176 |
s_log_zone_size | 0x0000 | 0 | 一个data block占用2的0次方K,即1K |
s_max_size | 0x10081c00 | 268966912 | 文件最大长度为268966912字节 |
s_magic | 0x138f | minix文件系统的魔幻数 | |
s_state | 0x0001 | 文件系统当前状态,0为已挂载,1为未挂载 | |
s_zones | 0x0000 |
inode节点
内核数据结构
如下图所示,内核中的struct minix_inode数据结构也是minix文件系统inode节点信息在存储介质中的存储方式,接下来我们对照dump文件中的数据,来看一下inode的值。
/*
* This is the original minix inode layout on disk.
* Note the 8-bit gid and atime and ctime.
*/
struct minix_inode {
__u16 i_mode;
__u16 i_uid;
__u32 i_size;
__u32 i_time;
__u8 i_gid;
__u8 i_nlinks;
__u16 i_zone[9];
};
万物之源No1节点—根目录
太极生两仪,两仪生四象,四象生八卦,宇宙再大,最开始也是从一个点,任何事物都有其起源,文件系统的起点便是从根目录开始,所以在我们格式化硬盘之后,inode节点只有一个,那就是表示根目录的inode节点。
i_mode | 0x41ed | ||
i_uid | 0x0000 | ||
i_size | 0x00000040 | ||
i_time | 0x61a10988 | ||
i_gid | 0x00 | ||
i_nlinks | 0x02 | ||
i_zone | 0x00b0 | 176 | 数据在第176个data block上(1024x176 = 0x2c000) |
第一个数据块
No1节点的i_zone指向了地址0x2c000,接下来我们看一下0x2c000地址处存放的数据,如下图红框所示,前两行是对链接’.‘的目录描述,其指向的inode节点编号为1,即根目录,后两行是对目录’…'的描述,它也指向inode 1节点。