Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2118716
  • 博文数量: 438
  • 博客积分: 3871
  • 博客等级: 中校
  • 技术积分: 6075
  • 用 户 组: 普通用户
  • 注册时间: 2011-09-10 00:11
个人简介

邮箱: wangcong02345@163.com

文章分类

全部博文(438)

文章存档

2017年(15)

2016年(119)

2015年(91)

2014年(62)

2013年(56)

2012年(79)

2011年(16)

分类: LINUX

2016-10-03 22:36:49

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文件的大小
  1. cong@msi:/tmp/minix$ ls -l bin/
  2. total 548
  3. -rwxr-xr-x 1 root root 7293 Oct 5 00:13 init  -->它的大小为7293=7×1024+125
b. 计算init在hdc.img中的偏移
  1. REG
  2. i_mode=0x81ed,i_uid=0x0,i_size=0x1c7d,i_time=0x57f3d521,i_gid=0x0,i_nlinks=0x1
  3. 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. 大小
  1. REG
  2. i_mode=0x81ed,i_uid=0x0,i_size=0x3d400,i_time=0x57f3d74e,i_gid=0x0,i_nlinks=0x1
  3. 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]中
  1. cong@msi:/tmp/minix$ ls -l dev/tty1
  2. crw-r--r-- 1 root root 4, 1 Oct 5 00:13 dev/tty1




附录1. mkfs的调试方法
a.准备工作
  1. cong@msi:/work/os/linux12/tools/mkfs$ ls
  2. 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脚本
  1. cong@msi:/work/os/linux12/tools/mkfs$ cat create.sh
  2. #!/bin/sh
  3. #fdisk hdc.img to minix 80
  4. make_fs()
  5. {
  6.     #32M disk, sector=32*1024*1024/512=65536
  7.     dd if=/dev/zero of=./hdc.img bs=1M count=32
  8.     fdisk ./hdc.img <<EOF
  9.     n
  10.     p
  11.     1
  12.     2048
  13.     65535
  14.     t
  15.     80
  16.     w
  17. EOF
  18.     sleep 1
  19.     echo "cong: next show disk partition"
  20.     fdisk -l ./hdc.img
  21.     echo "cong: next losetup entiry disk"
  22.     sudo losetup /dev/loop0 ./hdc.img
  23.     #512*2048=1048576
  24.     echo "cong: next losetup partion 1"
  25.     sudo losetup -o 1048576 /dev/loop1 /dev/loop0
  26.     echo "cong: next show losetup"
  27.     sudo losetup -a
  28. }

  29. clean_fs()
  30. {
  31.     #sudo umount /tmp/minix
  32.     sudo losetup -d /dev/loop0
  33.     sudo losetup -d /dev/loop1
  34.     rm -rf ./hdc.img
  35.     echo "cong: next show losetup"
  36.     losetup -a
  37. }

  38. case "$1" in
  39.     fs)
  40.         make_fs
  41.         ;;
  42.     clean)
  43.         clean_fs
  44.         ;;
  45.     *)
  46.         make_fs
  47.         ;;
  48. esac


阅读(1201) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~