1. minix的文件系统在硬盘上的结构
a. 如下图所示
《Linux内核完全注释V3.0.pdf》中没有说明在文件系统在硬盘上的格式,其实把12章的图结合起来看就差不多了。
b.但是上图不全对,下面说明一下:
minix文件系统作为一个分区时:
第0个块是引导块占用[0-1]2个扇区,
第1个块是super_block占用[2-3]2个扇区,
i节点位图区-->占用的扇区数不确定-->大小是:(inode_nr/8)/1024
z位图区(逻辑位图区)-->占用的扇区数不确定-->大小是:(block_nr/8)/1024
i节点区
-->占用的扇区数不确定-->大小是:inode_nr/(1024/(sizeof (struct d_inode)))
剩下的都是数据区
2. 调试mkfs
mkfs是对分区进行格式化, 主要是对上图的超级块 imap zmap inode区进行操作
2.1 setup_tables的主要作用是对超级块进行操作
a. i节点位图
(gdb) p p->s_ninodes -->有多少个inodes=g_blocks/3;
$7 = 21845
(gdb) p p->s_ninodes/8 -->inodes占的字节数
$8 = 2730
(gdb) p p->s_imap_blocks -->这些个inodes位图占多少个blocks
$9 = 3
b. 逻辑块位图
(gdb) p g_blocks -->有多少个blocks
$9 = 65535
(gdb) p g_blocks/8 -->这些blocks占的字节数
$10 = 8191
(gdb) p p->s_zmap_blocks -->这些blocks位图占多少个blocks
$11 = 8
c. i节点
(gdb) p (sizeof (struct d_inode)) -->d_inodes占的字节数
$6 = 32
(gdb) p 1024/(sizeof (struct d_inode)) -->1个block中有多少个d_inodes
$7 = 32
(gdb) p p->s_ninodes/(1024/(sizeof (struct d_inode))) -->d_inodes所占的blocks数目
$8 = 682
21845/32=682.65=683
d. 以上a+b+c推导出数据起始blocks
#define NORM_FIRSTZONE (2+IMAPS+ZMAPS+INODE_BLOCKS)
2+3+8+683=696 //boot+super=2 IMAP ZMAPS INODE_BLOCKS
(gdb) p p->s_firstdatazone
$6 = 696
static char inode_map[BLOCK_SIZE * I_MAP_SLOTS];
static char zone_map[BLOCK_SIZE * Z_MAP_SLOTS];
BLOCK_SIZE=1024
I_MAP_SLOTS=Z_MAP_SLOTS=8
bits = (8*1024*8)
最大可以映射 (8*1024*8)*1024=67108864=65536K=64M
(gdb) p INODE_BUFFER_SIZE -->d_inodes所占的blocks数目=683*1024
$4 = 699392
2.2 make_root_inode是将root结点写到硬盘的数据区,并修改buffer,此时这些buffer还只在内存中。
写root
44545 00ae000: 0100 2e00 0000 0000 0000 0000 0000 0000 ................
44546 00ae010: 0100 2e2e 0000 0000 0000 0000 0000 0000 ................
44547 00ae020: 0200 2e62 6164 626c 6f63 6b73 0000 0000 ...badblocks....
44548 00ae030: 0000 0000 0000 0000 0000 0000 0000 0000 ................
2.3 write_write_tables,是将最终的buffer数据写到磁盘上
将super_block的数据写到super_block处
将imap的数据写到imap处
将zmap的数据写到zmap处
将inode的数据写到inode处
3. 关于如何将数据dd出来
a. 分区的前面部分
cong@msi:/work/test$ dd if=./hdc.img of=1.hex bs=512 count=1024 skip=2048
1024+0 records in
1024+0 records out
524288 bytes (524 kB) copied, 0.0062566 s, 83.8 MB/s
b. 分区的数据部分
cong@msi:/work/test$ dd if=./hdc.img of=2.hex bs=512 count=1024 skip=2746
1024+0 records in
1024+0 records out
524288 bytes (524 kB) copied, 0.017539 s, 29.9 MB/s
三.文件在minix中的存储
3.1 关于一次间接块
a. 查看init文件的大小
-
cong@msi:/tmp/minix$ ls -l bin/
-
total 548
-
-rwxr-xr-x 1 root root 7293 Oct 5 00:13 init -->它的大小为7293=7×1024+125
b. 计算init在hdc.img中的偏移
-
REG
-
i_mode=0x81ed,i_uid=0x0,i_size=0x1c7d,i_time=0x57f3d521,i_gid=0x0,i_nlinks=0x1
-
node[0]=0x164 node[1]=0x165 node[2]=0x166 node[3]=0x167 node[4]=0x168 node[5]=0x169 node[6]=0x16a node[7]=0x16b node[8]=0x0
一次间接块: 0x16b=363
2048+363*2=2774
c. 从hdc.img中dd出数据
cong@msi:/work/os/test$ dd if=./hdc.img of=2.hex bs=512 count=1024 skip=2774
d. 查看2.hex的内容
一次间接块的内容是: 0x16c
e.查看0x16C的内容
其中2.hex是从0x16b开始的,0x16c就是2.hex的偏移0x400处,init的结束位置是0x47D,在这块中占用了125个字节
cong@msi:/work/os/11/test$ dd if=./hdc.img of=3.hex bs=512 count=1024 skip=2792再去查看0x175 0x176 --> 0x25f的内容就行了
3.2 再看另一个文件
a. 大小
-
REG
-
i_mode=0x81ed,i_uid=0x0,i_size=0x3d400,i_time=0x57f3d74e,i_gid=0x0,i_nlinks=0x1
-
node[0]=0x16d node[1]=0x16e node[2]=0x16f node[3]=0x170 node[4]=0x171 node[5]=0x172 node[6]=0x173 node[7]=0x174 node[8]=0x0
从大小中可以看出 0x3d400=250880=245K,是sh
245K-7K=238K
在一次间接块中238K占用238*2=476=1DC个字节
b. 一次间接块的偏移=0x174=372
2048+372*2=2792
cong@msi:/work/os/11/test$ dd if=./hdc.img of=3.hex bs=512 count=1024 skip=2792
1024+0 records in
1024+0 records out
524288 bytes (524 kB) copied, 0.00540711 s, 97.0 MB/s
一次间接块的内容是:
0000000: 7501 7601 7701 7801 7901 7a01 7b01 7c01 u.v.w.x.y.z.{.|.
0000010: 7d01 7e01 7f01 8001 8101 8201 8301 8401 }.~.............
...
00001c0: 5502 5602 5702 5802 5902 5a02 5b02 5c02 U.V.W.X.Y.Z.[.\.
00001d0: 5d02 5e02 5f02 6002 6102 6202 0000 0000 ].^._.`.a.b.....
00001e0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
里面的内容全都是块号,再去查看0x175 0x176 --> 0x25f的内容就知道sh这个文件了。
3.3 赵博关于一次间接块的解释:
"i_zone[]是含有块号。一个块大小为1KB,而每个块号使用2字节,因此一个间接块中可以存放512个块号。
同样道理,二次块也是512个块号。两者是“串连”的,因此二次间接块可以寻址512 * 512个块。"
i_zone[7]指向的是一个盘块,而这个盘块里面存放盘块号,每个块号使用2字节,所以共有1024/2=512个,
所以一个间接块中可以存放512个块号,即这个文件又可以再用512K了。
3.4 关于设备文件在minix中的存储
a. CHAR
i_mode=0x21a4,i_uid=0x0,i_size=0x0,i_time=0x57f3d51a,i_gid=0x0,i_nlinks=0x1
i_zone[0]=0x401 i_zone[1]=0x0 i_zone[2]=0x0 i_zone[3]=0x0 i_zone[4]=0x0 i_zone[5]=0x0 i_zone[6]=0x0 i_zone[7]=0x0 i_zone[8]=0x0
b. 设备号存在zone[0]中
-
cong@msi:/tmp/minix$ ls -l dev/tty1
-
crw-r--r-- 1 root root 4, 1 Oct 5 00:13 dev/tty1
附录1. mkfs的调试方法
a.准备工作
-
cong@msi:/work/os/linux12/tools/mkfs$ ls
-
create.sh fs.h Makefile mkfs.c -->将脚本与mkfs.c的源码放在一起
b. make 编译出mkfs命令
c. 执行 create.sh, 生成hdc.img镜像,并将minix分区losetup到loop1
d. sudo gdb ./mkfs --> 进入gdb 后set args /dev/loop1 65535
e.这样就可以调试了,若要重新调试 ./create.sh clean-->先清除hdc.img并解除losetup
f. 执行以上c-d就可以重新调试了。
下面是create.sh脚本
-
cong@msi:/work/os/linux12/tools/mkfs$ cat create.sh
-
#!/bin/sh
-
#fdisk hdc.img to minix 80
-
make_fs()
-
{
-
#32M disk, sector=32*1024*1024/512=65536
-
dd if=/dev/zero of=./hdc.img bs=1M count=32
-
fdisk ./hdc.img <<EOF
-
n
-
p
-
1
-
2048
-
65535
-
t
-
80
-
w
-
EOF
-
sleep 1
-
echo "cong: next show disk partition"
-
fdisk -l ./hdc.img
-
echo "cong: next losetup entiry disk"
-
sudo losetup /dev/loop0 ./hdc.img
-
#512*2048=1048576
-
echo "cong: next losetup partion 1"
-
sudo losetup -o 1048576 /dev/loop1 /dev/loop0
-
echo "cong: next show losetup"
-
sudo losetup -a
-
}
-
-
clean_fs()
-
{
-
#sudo umount /tmp/minix
-
sudo losetup -d /dev/loop0
-
sudo losetup -d /dev/loop1
-
rm -rf ./hdc.img
-
echo "cong: next show losetup"
-
losetup -a
-
}
-
-
case "$1" in
-
fs)
-
make_fs
-
;;
-
clean)
-
clean_fs
-
;;
-
*)
-
make_fs
-
;;
-
esac
阅读(1240) | 评论(0) | 转发(0) |