2006年12月12日 星期二
2006年04月26日 星期三
FAT32文件系统简介(zz)
Windows95 OSR2和Windows 98开始支持FAT32 文件系统,它是对早期DOS的FAT16文件系统的增强,由于文件系统的核心--文件分配表FAT由16位扩充为32位,所以称为FAT32文件系统。在一逻辑盘(硬盘的一分区)超过 512 兆字节时使用这种格式,会更高效地存储数据,减少硬盘空间的浪费,一般还会使程序运行加快,使用的计算机系统资源更少,因此是使用大容量硬盘存储文件的极有效的系统。本人对Windows 98下的FAT32 文件系统做了分析实验,总体上与FAT16文件系统变化不大,现将有关变化部分简介如下:
(一)FAT32 文件系统将逻辑盘的空间划分为三部分,依次是引导区(BOOT区)、文件分配表区(FAT区)、数据区(DATA区)。引导区和文件分配表区又合称为系统区。
(二)引导区从第一扇区开始,使用了三个扇区,保存了该逻辑盘每扇区字节数,每簇对应的扇区数等等重要参数和引导记录。之后还留有若干保留扇区。而FAT16文件系统的引导区只占用一个扇区,没有保留扇区。
(三)文件分配表区共保存了两个相同的文件分配表,因为文件所占用的存储空间(簇链)及空闲空间的管理都是通过FAT实现的,FAT如此重要,保存两个以便第一个损坏时,还有第二个可用。文件系统对数据区的存储空间是按簇进行划分和管理的,簇是空间分配和回收的基本单位,即,一个文件总是占用若干个整簇,文件所使用的最后一簇剩余的空间就不再使用,而是浪费掉了。
从统计学上讲,平均每个文件浪费0.5簇的空间,簇越大,存储文件时空间浪费越多,利用率越低。因此,簇的大小决定了该盘数据区的利用率。FAT16系统簇号用16位二进制数表示,从0002H到FFEFH个可用簇号(FFF0H到FFFFH另有定义,用来表示坏簇,文件结束簇等),允许每一逻辑盘的数据区最多不超过FFEDH(65518)个簇。FAT32系统簇号改用32位二进制数表示,大致从00000002H到FFFFFEFFH个可用簇号。FAT表按顺序依次记录了该盘各簇的使用情况,是一种位示图法。
每簇的使用情况用32位二进制填写,未被分配的簇相应位置写零;坏簇相应位置填入特定值;已分配的簇相应位置填入非零值,具体为:如果该簇是文件的最后一簇,填入的值为FFFFFF0FH,如果该簇不是文件的最后一簇,填入的值为该文件占用的下一个簇的簇号,这样,正好将文件占用的各簇构成一个簇链,保存在FAT表中。0000000H、00000001H两簇号不使用,其对应的两个DWORD位置(FAT表开头的8个字节)用来存放该盘介质类型编号。FAT表的大小就由该逻辑盘数据区共有多少簇所决定,取整数个扇区。
(四)FAT32系统一簇对应8个逻辑相邻的扇区,理论上,这种用法所能管理的逻辑盘容量上限为16TB(16384GB),容量大于16TB时,可以用一簇对应16个扇区,依此类推。FAT16系统在逻辑盘容量介于128MB到256MB时,一簇对应8个扇区,容量介于256MB到512MB时,一簇对应16个扇区,容量介于512MB到1GB时,一簇对应32个扇区,容量介于1GB到2GB时,一簇对应32个扇区,超出2GB的部分无法使用。显然,对于容量大于512MB的逻辑盘,采用FAT32的簇比采用FAT16的簇小很多,大大减少了空间的浪费。
但是,对于容量小于512MB的盘,采用FAT32虽然一簇8个扇区,比使用FAT16一簇16个扇区,簇有所减小,但FAT32的FAT表较大,占用空间较多,总数据区被减少,两者相抵,实际并不能增加有效存储空间,所以微软建议对小于512M的逻辑盘不使用FAT32。
另外,对于使用FAT16文件系统的用户提一建议,硬盘分区时,不要将分区(逻辑盘)容量正好设为某一区间的下限,例:将一逻辑盘容量设为1100M(稍大于1024M),则使用时其有效存储容量比分区为950M的一般还少,因其簇大一倍,浪费的空间较多。还有,使用FDISK等对分区指定容量时,由于对1MB的定义不一样(标准的二进制的1MB为1048576B,有的系统将1MB理解为1000000B,1000KB等),及每个分区需从新磁道开始等因素,实际分配的容量可能稍大于指定的容量,亦需注意掌握。
(五)根目录区(ROOT区)不再是固定区域、固定大小,可看作是数据区的一部分。因为根目录已改为根目录文件,采用与子目录文件相同的管理方式,一般情况下从第二簇开始使用,大小视需要增加,因此根目录下的文件数目不再受最多512的限制。FAT16文件系统的根目录区(ROOT区)是固定区域、固定大小的,是从FAT区之后紧接着的32个扇区,最多保存512个目录项,作为系统区的一部分。
(六)目录区中的目录项变化较多,一个目录项仍占32字节,可以是文件目录项、子目录项、卷标项(仅跟目录有)、已删除目录项、长文件名目录项等。目录项中原来在DOS下保留未用的10个字节都有了新的定义,全部32字节的定义如下:
(1) 0-- 7字节 文件正名。
(2) 8--10字节 文件扩展名。
(3) 11字节 文件属性,按二进制位定义,最高两位保留未用,0至5位分别是只读位、隐藏位、系统位、卷标位、子目录位、归档位。
(4) 11--13字节 仅长文件名目录项用,用来存储其对应的短文件名目录项的文件名字节校验和等。
(5) 13--15字节 24位二进制的文件建立时间,其中的高5位为小时,次6位为分钟。
(6) 16--17字节 16位二进制的文件建立日期,其中的高7位为相对于1980年的年份值,次4位为月份,后5位为月内日期。
(7) 18--19字节 16位二进制的文件最新访问日期,定义同(6)。
(8) 20--21字节 起始簇号的高16位。
(9) 22--23字节 16位二进制的文件最新修改时间,其中的高5位为小时,次6位为分钟,后5位的二倍为秒数。
(10)24--25字节 16位二进制的文件最新修改日期,定义同(6)。
(11)26--27字节 起始簇号的低16位。
(12)28--31字节 32位的文件字节长度。
其中第(4)至(8)项为以后陆续定义的。 对于子目录项,其(12)为零;已删除目录项的首字节值为E5H。在可以使用长文件名的FAT32系统中,文件目录项保存该文件的短文件名,长文件名用若干个长文件名目录项保存,长文件名目录项倒序排在文件短目录项前面,全部是采用双字节内码保存的,每一项最多保存十三个字符内码,首字节指明是长文件名的第几项,11字节一般为0FH,12字节指明类型,13字节为校验和,26--27字节为零。
(七)以前版本的 Windows 和DOS与 FAT32 不兼容,不能识别FAT32分区,有些程序也依赖于 FAT16 文件系统,不能和 FAT32 驱动器一道工作。将硬盘转换为 FAT32,就不能再用双引导运行以前版本的 Windows(Windows 95 [Version 4.00.950]、Windows NT 3.x、
分区表、文件分配表探秘(zz)
1、分区表
硬盘只有经过物理格式化、分区、逻辑格式化后才能使用,在进行分区时,FDISK会在硬盘的0柱面0磁头1扇区建一个64字节的分区表,在分区表的前面是主引导记录(MBR),后面是两个字节的有效标志55h、AAh(h表示16进制)。此扇区被称为主引导扇区,也是病毒最爱侵袭的地方,它由主引导记录+分区表+有效标志组成。
分区表对于系统自举十分重要,它规定着系统有几个分区;每个分区的起始及终止扇区、大小以及是否为活动分区等重要信息。分区表由4个表项组成,每个表项16个字节,各字节含义如表1:
表1
字节 含 义
第0字节 是否为活动分区,是则为80h,否则为00h
第1字节 该分区起始磁头号
第2字节 该分区起始扇区号(低6位)和起始柱面
号(高2位)
第3字节 该分区起始柱面号的低8位
第4字节 系统标志,00h表该分区未使用,06h表高
版本DOS系统,05h扩展DOS分区、65h表
Netware分区
第5字节 该分区结束磁头号
第6字节 该分区结束扇区号(低6位)和结束柱面号
(高2位)
第7字节 该分区结束柱面号的低8位
第8~11字节 相对扇区号、该分区起始的相对逻辑扇区
号,高位在后低位在前
第12~15字节 该分区所用扇区数,高位在后、低位在前
注意:
1分区表有四个表项,表示硬盘最多只能容纳四个分区。
2磁盘的各个面称为磁头,软盘只有两个磁头,而硬盘往往有多个。各个磁头相同半径的磁道合称为柱面。
3高位在后,低位在前是一种存储数字方式,读出时应对其进行调整,如两字节12h、34h,应调整为3412h。
现在举例说明,有如下一分区表(16进制):
┋
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 01
01 00 06 0B 23 9B 23 00 00 00 CD FF 00 00 00 00
01 9C 05 0B E3 DB F0 FF 00 00 00 55 05 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 AA
此分区表两个表项已被使用,说明此硬盘上存在两个分区(DOS主引导分区和扩展DOS分区),还有两个表项未用,最后是2个字节的有效标志。现以第一个表项为例说明各字节作用。
第0字节80h表明此分区为活动分区,系统启动时将从此分区读取系统文件,当硬盘上存在一个以上分区时,只能有一个是活动的。
第1字节01h表明此分区起始于第1磁道。
第2个字节01h用二进制表示为00000001,低6位为000001,合十进制为1,表此分区起始扇区为1。
第3字节00h,用二进制表示为00000000,加上第2个字节的高2位00作为高位,表示为0000000000,合十进制0,表此分区起始柱面为0。
第4字节06h表此分区为基本DOS分区。
第5字节0Bh表示该分区结束在第11磁头。
第6字节23h合二进制00100011,低6位100011合十进制35,此分区结束扇区则为35。
第7字节9Bh合二进制10011011,加上第6字节的高2位00作为高位,表示为0010011011,合十进制155,表此分区结束在第155柱面。
第8~11字节为23h,表此分区从相对逻辑35扇区开始。
第12~15字节为FFCDh,表此分区共有65985个扇区。综上所述,此分区为活动的基本DOS分区,分区从0柱面1磁头1扇区开始,即相对逻辑35扇区,终之于155柱面11磁头35扇区。
硬盘自举时,先将主引导扇区的主引导记录读入内存,主引导记录将检查结束标志是否为55AAh,并在分区表中找到唯一的一个活动分区,并根据该分区表项记载的起始扇区地址读入引导文件,完成启动过程。
要注意用PCTOOLS等一般软件无法访问主引导记录,因为它的磁盘编辑功能只能访问到逻辑0扇区,即BOOT扇区。但我们可以通过KV300或Norton的主引记录导出功能,观察自己的磁盘的分区表。也可对它进行修改,实现在不破坏原有数据的情况下增加分区、对某个分区加锁等功能,但用户最好谨慎行事,分区表可是“军事禁区”。
二、文件分配表
当一个磁盘Format后,在其逻辑0扇区(即BOOT扇区)后面的几个扇区中存在着一个重要的数据表——文件分配表(FAT),文件分配表一式两份,占据扇区的多少凭磁盘类型大小而定。顾名思义,文件分配表是用来表示磁盘文件的空间分配信息的。它不对引导区、文件目录表的信息进行表示,也不真正存储文件内容。
我们知道磁盘是由一个一个扇区组成的,若干个扇区合为一个簇,文件存取是以簇为单位的,哪怕这个文件只有1个字节。每个簇在文件分配表中都有对应的表项,簇号即为表项号,每个表项占15个字节(磁盘空间在10MB以下)或2个字节(磁盘空间在10MB以上)。为了方便起见,以后所说的表项都是指2个字节的。
文件分配表结构如表2(h表示16进制)。
注意:
1不要把表项内的数字误认为表示当前簇号,而应是该文件的下一个簇的簇号。
2高字节在后,低字节在前是存储数字的一种方式,读出时应进行调整,如两字节12h,34h,实际应为3412h。
文件分配表与文件目录表(FDT)相配合,可以统一管理整个磁盘的文件。它告诉系统磁盘上哪些簇是坏的或已被使用,哪些簇可以用,并存储每个文件所使用的簇号。它是文件的“总调度师”。
当DOS写文件时,首先在文件目录表中检查是否有相同文件名,若无则使用一个文件目录表项,然后依次检测FAT中的每个表项,找到第一个为0000h的表项后,将文件写入与该表项相对应的簇中,同时将该簇号写入文件目录表项的第26-27字节,如文件长度不止一簇,则继续向后寻找可用簇,找到后将其簇号写入上一次找到的表项中,如此直到文件结束,在最后一簇的表项里填上FFF8h,形成一个单向链表。
DOS删除文件时只是把文件目录表中的该文件的表项第0个字节改为E5h,表此表项已被删除,并在文件分配表中把该文件占用各簇的表项清0,以释放空间。其实文件的内容仍在盘上,并没有被真正删除,这就是undelete.exe、unerase.exe等一类恢复删除工具能起作用的原因。
文件分配表在系统中的地位十分重要,用户最好不要去修改它,以免误操作带来严重的后果。
表2
字 节 含 义
第0字节 表头,表磁盘类型。
FFh 双面软盘 每磁道8扇区
FEh 单面软盘 每磁道8扇区
FDh 双面软盘 每磁道9扇区
FCCh 单面软盘 每磁道9扇区
FC8h 硬盘
第1~2字节(表项号1) 表示第一簇状态,因第一簇已被系统占据,
故此两字节为FFFFh
第3~4字节(表项号2) 表示第二簇状态,若为FFFTh表此簇为坏
的,DOS已标记为不能用;0000h表示此簇
为空,可以用;FFF8h表示该簇为文件的最
后一簇;其余数字表示文件的下一个簇号,
注意高字节在后,低字节在前
第5~6字节(表项号3) 表示第三簇状态,同上
硬盘主引导记录详解(zz)
硬盘的数据结构对于一些朋友来说总是很神密!为什么我们删除了的文件用软件能找到?为什么我们格式化了的硬盘数据还能找回来?要回答这一切,你就得对硬盘的数据结构有个清醒的认识。
硬盘上的数据由五大部分组成,它们分别是:MBR区、DBR区,FAT区,DIR区和DATA区。
1.MBR(Main Boot Record)区,即主引导记录区,位于整个硬盘的0磁道0柱面1扇区.
2.DBR(Dos Boot Record)区,操作系统引导记录区。位于硬盘的0磁道1柱面1扇区,是操作系统可以直接访问的第一个扇区.
3.FAT(File Allocation Table文件分配表)区;
4.DIR(Directory)根目录区,记录着根目录下每个文件(目录)的起始单元,文件的属性等;
5.DATA区是真正意义上的数据存储的地方,位于DIR区之后,占据硬盘上的大部分数据空间。
了解了硬盘数据的基本结构,今天我们把重点放在mbr所在的扇区:主引导扇区。主引导扇区包括:mbr,dpt和结束标志。位于硬盘的0磁道0柱面1扇区,用diskman可以读出其中的内容,下面是一次操作的结果:
表一:
0 1 2 3 4 5 6 7 8 9 A B C D E F
00000000 EB48 90D0 BC00 7CFB 5007 501F FCBE 1B7C
00000010 BF1B 0650 57B9 E501 F3A4 CBBE BE07 B104
00000020 382C 7C09 7515 83C6 10E2 F5CD 188B 148B
00000030 EE83 C610 4974 1638 2C74 F6BE 1007 0302
00000040 8000 0080 68B6 7600 0008 FAEA 507C 0000
00000050 31C0 8ED8 8ED0 BC00 20FB A040 7C3C FF74
00000060 0288 C252 BE81 7DE8 3F01 F6C2 8074 5FB4
00000070 41BB AA55 CD13 7256 81FB 55AA 7550 A041
00000080 7C84 C075 0583 E101 7444 B448 BE00 7FC7
00000090 0442 00CD 1372 3766 8B4C 10BE 057C C644
000000A0 FF01 668B 1E44 7CC7 0410 00C7 4402 0100
000000B0 6689 5C08 C744 0600 7066 31C0 8944 0466
000000C0 8944 0CB4 42CD 1372 05BB 0070 EB7D B408
000000D0 CD13 730A F6C2 800F 84E8 00E9 8D00 BE05
000000E0 7CC6 44FF 0066 31C0 88F0 4066 8944 0431
000000F0 D288 CAC1 E202 88E8 88F4 4089 4408 31C0
00000100 88D0 C0E8 0266 8904 66A1 447C 6631 D266
00000110 F734 8854 0A66 31D2 66F7 7404 8854 0B89
00000120 440C 3B44 087D 3C8A 540D C0E2 068A 4C0A
00000130 FEC1 08D1 8A6C 0C5A 8A74 0BBB 0070 8EC3
00000140 31DB B801 02CD 1372 2A8C C38E 0648 7C60
00000150 1EB9 0001 8EDB 31F6 31FF FCF3 A51F 61FF
00000160 2642 7CBE 877D E840 00EB 0EBE 8C7D E838
00000170 00EB 06BE 967D E830 00BE 9B7D E82A 00EB
00000180 FE47 5255 4220 0047 656F 6D00 4861 7264
00000190 2044 6973 6B00 5265 6164 0020 4572 726F
000001A0 7200 BB01 00B4 0ECD 10AC 3C00 75F4 C300
000001B0 0000 0000 0000 0000 4CA6 4CA6 0000 8001
000001C0 0100 0BFE 3FD8 3F00 0000 5A31 3500 0000
000001D0 01D9 0FFE FFFF 9931 3500 04FF FB00 0000
000001E0 0000 0000 0000 0000 0000 0000 0000 0000
000001F0 0000 0000 0000 0000 0000 0000 0000 55AA
这块10.2G(以下显示为9766MB,误差原因不用我解释了吧?)的硬盘共分了四个区:分区结构如下:
主引导扇区中前446字节--偏移地址从0000H-01BDH为mbr区,存放着主引导程序,从上面的显示中,读者可能已经看出,这个硬盘以linux系统的grub为引导程序。
接下来的64字节为硬盘分区表--dpt,偏移地址从01BEH-01FDH,共分为四个分区表项,每个分区表项占16字节,表示一个分区,从这里大家就可以知道为什么硬盘只能分四个主分区了吧?但有时我们需要更多的分区来规划我们的硬盘,为解决这个问题,就把这四个分区表项中的一个定义为扩展分区(与主分区是并列关系),扩展分区中又可以定义逻辑分区(与扩展分区是包含与被包含的关系)。但读者不要以为这些信息都在这一个16字节的分区表项中。事实上是:被定义为扩展分区的这一个分区表项只包含了指向逻辑分区的信息。而逻辑分区的分区表在其它的扇区中存放!
本文重点介绍dpt中的内容,上面已经提到,dpt分为四个分区表项,每个分区表项占16个字节,下面着重讲述这16个字节是怎么分配的。
表三:
第1字节 引导标志,该值为80H表示为可自举分区(活动分区,仅有一个),该值为00H表示其余分区
第2字节 分区起始磁头
第3字节 低6位是分区起始扇区,高2位是分区起始的柱面的头两位
第4字节 分区起始柱面的低8位
第5字节 系统标志
第6字节 分区终止磁头
第7字节 低6位为分区终止扇区,高2位为终止柱面的前2位
第8字节 分区终止柱面的低8位。
第9-12字节 本分区前的扇区数,低位字节在前(注:不是低位在前)
第13-16字节 本分区总的扇区数,低位字节在前
现在根据上面的列表详细解释一下:我们提取出下面四个分区表项:
表四:
分区 | 字节序号
表项 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
1: | 80 01 01 00 0B FE 3F D8 3F 00 00 00 5A 31 35 00
2: | 00 00 01 D9 0F FE FF FF 99 31 35 00 04 FF FB 00
3: | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
4: | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
由于数据以16进制显示,每个数字占一个字节的四位,所以两个数字占一个字节。
对于第一个分区表项:
第1字节为80,表示活动分区;
第2字节为01,十进制为1,表示起始磁头号;
第3字节为01,二进制为00000001,低6位000001,对应的十进制为1,表示起始扇区;
第4字节为00,二进制为00000000,与第三字节的高2位00组成0000000000,十进制为0,表示起始柱面;
第5字节为0B,为系统标志;
第6字节为FE,十进制为254,表示终止磁头;
第7字节为3F,二进制为00111111,低6位为111111,转换为十进制为63,表示终止扇区;
第8字节为D8,二进制为11011000,与第7字节的高2位00组成0011011000,十进制为216,表示终止柱面;
第9-12字节为3F 00 00 00,按低位字节在前的原则排列为:00 00 00 3F,转换为十进制为63,表示该分区前的扇区数目;
第13-16字节为5A 31 35 00,按低位字节在前的原则排列为:00 35 31 5A,转换为十进制为3486042,表示该分区占用的扇区数目。
我们可以与表2对照,发现两者完全统一!同理,我们还可以分析第2个分区表项,这就交给感兴趣的读者自己完成吧。
在第3和第4个分区表项中,所以数据都为0,表示这两个分区表项没有分配。
最后两个字节--偏移地址从01FEH-01FFH,为结束标志,通常为55 AA,如果改为其它值,则硬盘可能不被引导。
通过以上的讲解,你是不是对硬盘的数据结构又有了更深的认识?对于使用windows和linux双系统的用户,经常要与mbr打交道,有很多网友问:装了linux和windows双系统,现在又不想使用linux了,于是把linux的分区格式化为fat32回收,但当初装在mbr的引导信息老是去不掉。这里我可以告诉你一个方法,就是用windows98启动盘启动电脑,然后运行fdisk/mbr命令就可以了,这条命令是重建mbr(前446字节),但并不破坏dpt中的数据,也就是并不破坏硬盘的分区表,可以安全使用。你可以在使用这条命令前后各查看一下主引导扇区,就会发现从447字节开始以后的数据都没有改变。如果你没有diskman这个软件,下面的C程序一样可以帮你搞掂!
以下是程序的源码:
#include <bios.h>
#include <stdio.h>
int main()
{
register int i;
unsigned char buffer[512] = {0};
biosdisk(2, 0x80, 0, 0, 1, 1, buffer);
for (i=0; i<512; i++)
{
if (!(i%8))
{
printf(" ");
if (!(i%16))
{
printf("\n");
printf("%04x:", i);
}
}
printf("%02x ", buffer);
}
}
在turboc2.0中可编译通过。运行biosdisk()函数,你还可进一步编写备份mbr,恢复mbr的程序或把mbr清0的程序,是不是很想试试。