参考
https://www.zybuluo.com/harpsword/note/207478
https://blog.youkuaiyun.com/hejinjing_tom_com/article/details/52319189
http://www.cnblogs.com/zhangchaoyang/articles/1896605.html
https://www.cnblogs.com/codestub/archive/2011/08/31/2160739.html
http://bachue.is-programmer.com/user_files/Bachue/File/Linux%200.11文件系统的实现.pdf
http://www.voidcn.com/article/p-vizxcuae-dd.html
https://blog.youkuaiyun.com/ac_dao_di/article/details/54670516
http://www.rutk1t0r.org/2016/12/22/Linux内核0-11完全注释-来吧-Minix/
https://blog.youkuaiyun.com/fukai555/article/details/42060837
准备
创建一个128KB的名为disk的文件,把文件格式化为minix文件系统, minix文件系统有3个版本,这里默认的是版本1:
$ dd if=/dev/zero of=disk bs=1K count=128
$ mkfs.minix disk
64 inodes
128 blocks
Firstdatazone=6 (6)
Zonesize=1024
Maxsize=268966912
磁盘的最小读写单位是块,一般磁盘块大小是512字节, linux定义的块大小为1024。
上面以1KB的磁盘块(block)分成128个;
ZoneSize >= BlockSize, 在这里都是1024;
第一个数据Zone从索引6的Zone开始;
文件最大可达到268966912。
创建几个目录和文本文件:
$ mkdir mnt
$ mount disk -o loop -t minix mnt
.......
$ tree
mnt/
├── document
│ └── uname.txt
├── number.txt
└── text.txt
hexdump -C disk显示如下:
00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 引导块1K
*
00000400 40 00 80 00 01 00 01 00 06 00 00 00 00 1c 08 10 |@...............| 超级块
00000410 8f 13 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000420 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00000800 3f 00 00 00 00 00 00 00 fe ff ff ff ff ff ff ff |?...............| inode bitmap
00000810 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
*
00000c00 3f 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f8 |?...............| zone bitmap
00000c10 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
*
00001000 ed 41 e8 03 a0 00 00 00 1b 92 f3 5b e8 03 06 00 |.A.........[....| inode1
00001010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00001020 b4 81 e8 03 0a 00 00 00 ec 91 f3 5b e8 01 07 00 |...........[....| inode2
00001030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00001040 b4 81 e8 03 08 00 00 00 0f 92 f3 5b e8 01 08 00 |...........[....| inode3
00001050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00001060 fd 41 e8 03 60 00 00 00 35 92 f3 5b e8 02 09 00 |.A..`...5..[....| inode4
00001070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00001080 b4 81 e8 03 72 00 00 00 35 92 f3 5b e8 01 0a 00 |....r...5..[....| inode5
00001090 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00001800 01 00 2e 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| ZONE 6
00001810 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00001820 01 00 2e 2e 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00001830 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00001840 02 00 6e 75 6d 62 65 72 2e 74 78 74 00 00 00 00 |..number.txt....|
00001850 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00001860 03 00 74 65 78 74 2e 74 78 74 00 00 00 00 00 00 |..text.txt......|
00001870 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00001880 04 00 64 6f 63 75 6d 65 6e 74 00 00 00 00 00 00 |..document......|
00001890 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00001c00 31 32 33 34 35 36 37 38 39 0a 00 00 00 00 00 00 |123456789.......| ZONE7
00001c10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00002000 61 62 63 64 65 66 67 0a 00 00 00 00 00 00 00 00 |abcdefg.........| ZONE8
00002010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00002400 04 00 2e 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| ZONE9
00002410 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00002420 01 00 2e 2e 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00002430 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00002440 05 00 75 6e 61 6d 65 2e 74 78 74 00 00 00 00 00 |..uname.txt.....|
00002450 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00002800 4c 69 6e 75 78 20 75 62 75 6e 74 75 20 34 2e 31 |Linux ubuntu 4.1| ZONE10
00002810 35 2e 30 2d 33 36 2d 67 65 6e 65 72 69 63 20 23 |5.0-36-generic #|
00002820 33 39 7e 31 36 2e 30 34 2e 31 2d 55 62 75 6e 74 |39~16.04.1-Ubunt|
00002830 75 20 53 4d 50 20 54 75 65 20 53 65 70 20 32 35 |u SMP Tue Sep 25|
00002840 20 30 38 3a 35 39 3a 32 33 20 55 54 43 20 32 30 | 08:59:23 UTC 20|
00002850 31 38 20 78 38 36 5f 36 34 20 78 38 36 5f 36 34 |18 x86_64 x86_64|
00002860 20 78 38 36 5f 36 34 20 47 4e 55 2f 4c 69 6e 75 | x86_64 GNU/Linu|
00002870 78 0a 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |x...............|
00002880 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00020000
0. 引导块
最前面1KB是引导区,用于存放系统启动的引导代码,没有使用,全部为0;
1. 超级块
minix文件系统超级块,占用1KB:
00000400 40 00 80 00 01 00 01 00 06 00 00 00 00 1c 08 10 |@...............| 超级块
00000410 8f 13 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000420 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
struct minix_super_block {
__u16 s_ninodes; //0x0040, 64个索引节点
__u16 s_nzones; //0x0080, 128个zone, 每个1K
__u16 s_imap_blocks; //0x0001, inode 位图点用一个块(1KB)
__u16 s_zmap_blocks; //0x0001, zone位图占用一个块(1KB)
__u16 s_firstdatazone; //0x0006第一个数据ZONE索引号
__u16 s_log_zone_size; //0x0000, log2(zone/block), zone与block 都为1024
__u32 s_max_size; //0x10081c00, 十进制268966912, 文件最大尺寸
__u16 s_magic; //0x138f(MINIX1.0文件系统)
__u16 s_state;
__u32 s_zones;
};
2. inode bitmap
3f 00 00 00 00 00 00 00
0011_1111 ......
bit0 保留但置1,bit1表示该文件系统的根目录, 共占用了5个inode(根目录、document和3个文件)。
3. zone bitmap
3f 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f8
0011_1111 ......
bit0 保留但置1,bit1表示该文件系统的根目录数据区(存储多个目录项), 共占用了5个zone, 前面超级块的firstdatazone为6, 所以这里的bit1 对应 DataZone 6, bit2对应 7, bit3 对应 8……
4. inode
00001000 ed 41 e8 03 a0 00 00 00 1b 92 f3 5b e8 03 06 00 |.A.........[....| inode1
00001010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00001020 b4 81 e8 03 0a 00 00 00 ec 91 f3 5b e8 01 07 00 |...........[....| inode2
00001030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00001040 b4 81 e8 03 08 00 00 00 0f 92 f3 5b e8 01 08 00 |...........[....| inode3
00001050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00001060 fd 41 e8 03 60 00 00 00 35 92 f3 5b e8 02 09 00 |.A..`...5..[....| inode4
00001070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00001080 b4 81 e8 03 72 00 00 00 35 92 f3 5b e8 01 0a 00 |....r...5..[....| inode5
00001090 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
32字节为一条inode,最前两行为根目录的inode,inode编号为1; inode为0表示空闲:
struct minix_inode {
__u16 i_mode; //0x41ed, 040755, 目录文件, rwxr-xr-x
__u16 i_uid; //0x03e8, 1000
__u32 i_size; //000000a0, 160
__u32 i_time; //0x5bf3921b
__u8 i_gid; //0xE8, 232
__u8 i_nlinks; //0x03, 自身引用,上级目录引用,document引用
__u16 i_zone[9]; //0x06, 0x00..... 目前只占用了6号ZONE,存储目录项
};
stat设备根目录(当前目录)输出验证:
konga@ubuntu:~/work/temp/mnt$ stat .
File: '.'
Size: 160 Blocks: 2 IO Block: 1024 directory
Device: 700h/1792d Inode: 1 Links: 3
Access: (0755/drwxr-xr-x) Uid: ( 1000/ konga) Gid: ( 232/ UNKNOWN)
Access: 2018-11-20 12:48:28.000000000 +0800
Modify: 2018-11-20 12:48:27.000000000 +0800
Change: 2018-11-20 12:48:27.000000000 +0800
Birth: -
接下去的两行,inode为2,内容分析:
struct minix_inode {
__u16 i_mode; // 0x81b4, 0100664 常规文件 rw-rw-r--
__u16 i_uid; // 0x03e8, 1000
__u32 i_size; // 0000000a, 10
__u32 i_time; // 0x5bf391ec
__u8 i_gid; // 0xE8, 232
__u8 i_nlinks; // 0x01, 没有其他硬链接
__u16 i_zone[9]; //0x07, 0x00..... 目前只占用了7号ZONE,存储目录项
};
konga@ubuntu:~/work/temp/mnt$ stat number.txt
File: 'number.txt'
Size: 10 Blocks: 2 IO Block: 1024 regular file
Device: 700h/1792d Inode: 2 Links: 1
Access: (0664/-rw-rw-r--) Uid: ( 1000/ konga) Gid: ( 1000/ konga)
Access: 2018-11-20 12:47:40.000000000 +0800
Modify: 2018-11-20 12:47:40.000000000 +0800
Change: 2018-11-20 12:47:40.000000000 +0800
Birth: -
5. DATA
第一个数据ZONE从第6个块开始,这里的首个1KB是当前文件系统根目录的数据区,对应zone 位图的bit1; ZONE7即是number.txt 对应inode2中i_zone[9]记录占用的一块,存储的是文件内容。
00001800 01 00 2e 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| ZONE 6
00001810 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00001820 01 00 2e 2e 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00001830 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00001840 02 00 6e 75 6d 62 65 72 2e 74 78 74 00 00 00 00 |..number.txt....|
00001850 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00001860 03 00 74 65 78 74 2e 74 78 74 00 00 00 00 00 00 |..text.txt......|
00001870 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00001880 04 00 64 6f 63 75 6d 65 6e 74 00 00 00 00 00 00 |..document......|
00001890 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00001c00 31 32 33 34 35 36 37 38 39 0a 00 00 00 00 00 00 |123456789.......| ZONE7
00001c10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
ZONE6存储的是目录项,这里是32字节为一条项目项。
struct minix_dir_entry {
__u16 inode;
char name[0];
};
前面两条目录项为当前目录”." 和上一级目录”.."