读取Ext2的meta信息

看了很多内核的教学书籍,比如ULK之类的,到头来还是不知道文件系统在磁盘上的确切组织形式。最近想个办法能依次读取磁盘上的meta data的信息,其间发现了自己不少理解上的错误,在此也做个记录。

实验环境:首先在虚拟机中重新添加一个本地的硬盘(2G),格式话为Ext2。然后本次的实验就是读取/dev/sdb等类似的信息。当然原理上是打开了设备文件,然后从pagecache中读取,但是在不考虑可能的不一致性(比如读取的时候有磁盘的写回操作)的话,还是可以读取其中的内容的。

使用系统调用open,mmap等映射相应的地址。(具体函数用法可以查考man)

比如:

int fd = open("/dev/sdb",O_RDONLY);

char *addr = mmap(NULL,size,PROT_READ,MAP_PRIVATE,fd,0);

这样就可以从/dev/sdb的开头处读取了。

一般翻开一本介绍Ext2的书籍都会发现上面介绍磁盘的结构为:

--------------------------------------------------------------------------------------------------------------------------------

  Boot  |  super_block  |  group_descriptor  |  block bitmap  |   inode bitmap |  inode table |   data area 

--------------------------------------------------------------------------------------------------------------------------------

然后会告诉你super_block占了一个块(逻辑上的单位,此处取为最一般得4K),group_deacriptor占了n个块,block bitmap和inode bitmap各占了一个块,inode table占了一个块。当然ULK是这么说的,但是当想读取这些信息的时候不禁产生问题:boot有多大?

有可能想到以前看过的boot部分是512字节,那么是不是就是从512B偏移开始就是super_block呢?很可惜不是。现在文件系统的第一个块中的前1024个字节全部是属于boot(可能是为了对齐的原因还是效率的原因吧),那么super_block也就是从开始的地址处偏移1024初开始。很好,这样程序可以正常运行,也能成功的读取super_block信息。

然后该是group_descriptor了吧,很好,按照书上说的super_block占了一个块,那么该是从偏移1024 + 4096处读取group_descriptor了吧。很可惜,还不是这样,经过我无数次的实验,我发现,实际上boot和super_block都是在第一个块中,boot是第一个块中的前1024字节,super_block是紧跟其后的1024字节,然后再偏移2048字节,也就是从开头的地方偏移第一个块就正好是group_descriptor。

然后呢,group_descriptor是怎么存储的呢,是所有的组描述符都在一起,一个紧跟着一个还是每个组描述符按1024对齐,还是每个组描述符都占一个块呢?书上仅给出了他们一共占了n个块,并没有给出他们的具体存储的格式。通过无数次血与泪的实验,我这里得出的结论是所有的组描述符是一个接一个存储的(每个32字节,一个小一点的磁盘哪有n个块啊,我确实是被误导了...)。

然后紧接这是一个块得block bitmap和inode bitmap,没问题。inode table有了group_table的先例也计算正确了。好了现在可以写代码了吧。写出来的时候又发现悲剧了。第一个组(第0组)的信息还是很好读,第1组没问题,第二组就开始出现乱七八糟的信息了,头疼了好长时间。其间上网查了没搞定。最后想起来了去看了一下fsck的源代码,恍然大悟,原来并不是所有的组中的meta信息都是完整的,很多时候系统使用sparse的方法来对磁盘上的meta信息组织(推荐大家去看e2prog源码e2fsprogs.sourceforge.net)。这样super_block只存在于0,1,3,5,7或者这些数的幂数的组上,而当super_block没有时group_descriptor也就没有了。

终于可以写代码了:下面是我写的第一个版本的代码,可以读取第一个组中的super_block信息和第一个组描述符,后面各个组的内容可以根据第一个读出来的super_block中的信息进行偏移设置读出。此处就只抛砖引玉了。

 

还是老话,预知其事必躬行啊.......

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值