Windows文件系统

摘要:
以3.5英寸1.44M标准格式FAT12文件系统的软盘为例。FAT122880扇区(1474560B)逻辑扇区占用扇区内容。磁盘CHS参数(磁头/气缸/扇区)01(512B)引导程序启动:BIOS将在启动时将此扇区读取为0。操作系统识别FAT12文件系统,因为特定数据结构存储在逻辑扇区0(即引导扇区)中,当操作系统格式化此磁盘时自动生成。

  微软在Dos/Windows系列操作系统中共使用了6种不同的文件系统(包括即将在windows的下一个版本中使用的Winfs)。

       它们分别是:FAt12、FAT16、FAT32、NTFS、NTFS5.0和WINFS。

       其中FAT12、FAT16、FAT32均是FAT文件系统。是File Allocation Table的简称。

1. FAT12

  这是伴随着Dos诞生的“老”文件系统了。它采用12位文件分配表,并因此而得名。而以后的FAT系统都按照这样的方式在命名。在DOS3.0以前使用。但是在现在,我们都还能找得到这个文件系统:用于软盘驱动器。当然,其他地方的确基本上不使用这个文件系统了。FAT12可以管理的磁盘容量是8M。这在当时,没有硬盘的情况下,这个磁盘管理能力是非常大的。

  以3.5英寸的1.44M标准格式化的FAT12文件系统的软盘为例,当软盘被标准格式化后,每磁头80个柱面(磁道),每个柱面有18个扇区,每个扇区有512字节空间。所以标准软盘的总空间(容量)为:2*80*18*512=1474560B=1440K=1.44M

但是1.44M的软盘格式化可以不是1.44M,可以大于也可以小于;格式化的文件系统也可以不是FAT12。为什么会出现正常的1.44M软盘格式化后可大可小的情况呢?从软盘及软盘驱动器原理出发,软盘的寻址方式(可以认为是读取数据的方式)是:CHS,C = Cylinder(柱面),H = Header(磁头),S = Sector(扇区)。标准地格式化后,磁盘将被格式化为 每面80磁道(80个同心圆,柱面),每个磁道有18个扇区,每个扇区是 512字节,那么高密3.5英寸软盘的容量为:2×80×18×512 = 1474560 Byte = 1440 KB = 1.44 MB。然而,软盘可以不格式为80磁道,每个磁道也可以不是18扇区。

 

FAT12文件系统将按照下表所示的方式划分全部的容量,即文件系统数据结构:

FAT12 2880扇区 (1474560B)逻辑扇区占用扇区内容磁盘CHS参数(磁头/柱面/扇区)
01(512B)引导程序起:0/0/1
19(4608B)FAT文件分配表1起:0/0/2 止:0/0/10
109(4608B)FAT文件分配表2起:0/0/11 止:1/0/1
1914(9728B)根目录 
3314(9728B)文件数据区 

    操作系统之所以认识FAT12格式的磁盘,其秘密就在于逻辑0扇区这512B上。如果这512字节的最后两个字节的内容分别是55和AA(0xAA55低字节在前,高字节在后)的话,BIOS在启动时会将这个扇区读取到0:7C00h-0:7DFFh处,然后跳转到0:7C00h处继续执行指令,操作系统即用此来达到引导系统的目的,而这个磁盘就称为可引导磁盘。操作系统标识FAT12文件系统是因为在逻辑0扇区(即引导扇区)处还存储着一个特定的数据结构,此结构有固定的格式,在操作系统将此磁盘格式化时自动生成,具体数据结构如下表所示:

标识偏移量类型大小说明默认值
 

0

db

3

跳转指令 
BS_OEMName

3

db

8

OEM字符串,必须为8个字符,不足以空格填空MSWIN4.1
BPB_BytsPerSec

11

dw

2

每扇区字节数200h
BPB_SecPerClus

13

db

1

每簇占用的扇区数1
BPB_RsvdSecCnt

14

dw

2

保留扇区数1
BPB_NumFATs

16

db

1

FAT表的记录数2
BPB_RootEntCnt

17

dw

2

最大根目录文件数0e0h
BPB_TotSec16

19

dw

2

逻辑扇区总数0b40h
BPB_Media

21

db

1

媒体描述符0f0h
BPB_FATSz16

22

dw

2

每个FAT占用扇区数9
BPB_SecPerTrk

24

dw

2

每个磁道扇区数12h
BPB_NumHeads

26

dw

2

磁头数2
BPB_HiddSec

28

dd

4

隐藏扇区数0
BPB_TotSec32

32

dd

4

如果BPB_TotSec16是0,则在这里记录扇区总数0
BS_DrvNum

36

db

1

中断13的驱动器号0
BS_Reserved1

37

db

1

未使用0
BS_BootSig

38

db

1

扩展引导标志29h
BS_VolID

39

dd

4

卷序列号0
BS_VolLab

43

db

11

卷标,必须是11个字符,不足以空格填充 
BS_FileSysType

54

db

8

文件系统类型,必须是8个字符,不足填充空格FAT12  
 

62

 

 

引导代码,由偏移0字节处的短跳转而来 
 

510

dw

2

系统引导标识0aa55h  

    首先是跳转指令,偏移0处的跳转指令必须是合法的可执行的基于x86的CPU指令,如:jmp start,这样可以生成3字节长的指令,(加关键字short的短跳转指令的长度是2字节),指向操作系统引导代码部分。Windows和MS-DOS生成的FAT12启动扇区中的跳转指令是短跳转,如:jmp short start,然后加一个nop的空指令来保持3字节的长度。

    接着是位于偏移3处的OEM字符串,它必须是一个8字节长的字符串,标识了格式化此磁盘的操作系统的名称和版本号,为了保留与MS-DOS的兼容性,通常Windows 2000系统格式化的磁盘上在此记录中的字符串是“MSDOS5.0”,在Windows 95系统格式化的磁盘上在此记录中的字符串是“MSWIN4.0”,在Windows 95 OSR2和Windows 98系统上格式化的磁盘上在此记录中的字符串是“MSWIN4.1”。

   

  接下来是每扇区的字节数,类型是双字节长,标准分区上的每扇区字节数一般是512B,但也可以是其它的数字,如1024,2048和4096,FAT12的格式下设置为512(200h)。

  偏移13处的是每簇所占用的扇区,类型是字节,簇是数据存储的最小单位,此字段的值取决于分区的大小,在FAT12格式下一般为1,即每簇只有1个扇区(512字节),簇越大,那么分区的容量也就越大,通过增加簇的扇区数,可以支持更大的磁盘分区,标准的簇大小为1、2、4、8、16、32、64和128,FAT12格式下只能管理2^12个簇(4096),所以在FAT12格式下能管理和分配的最大空间为:4096*1*512=2097152B=2M,所以FAT12一般只适合3.5寸高密度软盘(1.44M)。

    保留扇区指的是在第一个FAT文件分配表之前的引导扇区,一般情况下只保留1个扇区(512B)。

    接下来是类型为1字节长的FAT表的总数,默认情况下此字段的值为2,也就是有两个FAT表,FAT1和FAT2的内容相同,当FAT1表出错的时候可以使用FAT2来恢复文件分配表。

    位于偏移17处的字段是类型为双字节长的能够储存在根目录下的最大文件(包含子目录)数量,默认为224,每个目录或文件名占用32B的空间,因此根目录的大小为:224*32=7168B=7KB,如果使用长文件名的话,根目录文件数还可能无法达到224的数量。

    接下来是位于偏移19处的逻辑扇区总数,类型是双字节,如果此磁盘的逻辑扇区总数大于2^16位(65536)的话,就设置此字段为0,然后使用偏移32处的双字来表示逻辑总扇区数。

    位于偏移21处的是单字节长的磁盘类型标识符,使用0f0h表示3.5寸高密码软盘,用0f8h来表示硬盘。此字段主要用于FAT12或FAT16的分区格式中,在Windows 2000中未使用。

    偏移22处双字节长的是每个FAT文件分配表所占用的扇区数,操作系统用这个字段和FAT表数量以及隐藏扇区数量来计算根目录所在的扇区。还可以根据最大根目录数来计算用户数据区从哪里开始。

    根目录扇区位置=FAT表数量*FAT表所占用的扇区数量+隐藏扇区数量

    用户数据开始位置=根目录扇区位置+根目录所占用扇区(FAT12格式下为224*32/512)

    此处所说的扇区指的是逻辑(线性)扇区,需要通过转换才能得到CHS磁盘参数,然后通过CHS参数来读写磁盘扇区。

    接下来是位于偏移24处的每磁道扇区总数,类型是双字节长,软盘的默认值为18,即每个磁道有18个扇区。

    然后是双字节长的磁头数,磁头数指的是磁盘面数,每面都有一个磁头,软盘都是2面的,所以在FAT12格式下此字段固定为2。

    接下来是的位于偏移28处类型为双字(4B)长的隐藏扇区数,指的在引导扇区之前的隐藏扇区,在FAT12格式上此字段默认为0,即不隐藏任何扇区,此字段参与计算根目录区和用户数据区位置。

    偏移32处的是类型为双字(4B)长的逻辑扇区总数,如果此分区或磁盘的逻辑扇区总数大于65536则用这个字段来表示逻辑扇区总数,否则设置此字段为0后用位于偏移19处的双字节字段来表示。

    偏移36处的是物理驱动器号,类型是字节长,它与BIOS物理驱动器相关,在磁盘中断Int13h相关的操作中使用,第一个软盘驱动器设置为0,第一个硬盘驱动器设置为80h,第二个硬盘驱动器设置为81h,以此类推。此字段的值可以在系统引导时用dl寄存器得到。

    位于偏移37处的字节没有使用,保留并设置为0。

    位于偏移38处的是扩展引导标识,类型是字节,操作系统用它来识别引导信息,值可以是28h或29h。

    接下来的是位于偏移39处的卷标号,类型是双字(4B)长,在格式化磁盘时所产生的一个随机序号,有助于区分磁盘,可以为0。

    然后是位于偏移43处的卷标,长度必须是11字节长(不足以空格20h填充),此字段只能使用一次,用来保存磁盘卷的标识符,再次设置的时候被保存到根目录中作为一个特殊的文件来储存。

    最后是位于偏移54处的是长度为8字节的文件系统类型标识符,不足8字节则以空格20h来填充。FAT12格式下此字段为“FAT12   ”,相应的还有“FAT16   ”和“FAT32   ”。但要注意的是,操作系统并不使用这个字段来识别此磁盘所用的文件系统。

我们先来看看文件分配表的数据格式,文件分配表所在的扇区应该是(隐藏扇区+保留扇区)=0+1=第1扇区处,从第1扇区开起到第9扇区结束,第一个文件分配表共占用9个扇区,第二个文件分配表从第10个扇区开始到第18扇区结束,在引导扇区的数据结构中明明确的指出了这些位置。

    文件分配表数据结构如下图所示:

   FAT12文件系统 <wbr>数据存储方式详解

    在FAT表开始扇区的第1字节是存储介质,0f0h代表软盘,0f8代表硬盘;第2、3这两个字节都是0ffh,代表了FAT文件分配表标识符,从第四个字节开始与用户数据区所有的簇一一对应,应该注意的是,用户数据区的第一个簇的序号是002,而不是000,因为储存介质和标识符占用了这两个序号。

    在FAT12格式中用12比特位来代表一个簇的序号,我们知道,每个字节有8位比特,所以每个簇要占用1.5个字节,也就是说,占用了第1字节和第2字节的一半才能表示一个簇的序号,半字节的拆分办法按照下图的方式进行:

   FAT12文件系统 <wbr>数据存储方式详解

    例如:在FAT表中开始位置储存的字节内容依次是F0 FF FF FF 4F 00 05 F0 FF,前面三个字节是储存介质和标识符,我们不管它,前面三个字节占用了0和1这两个簇序号,那么就应该从2簇开始了。经过转换得到的簇序号是:0fffh 004h 005h 0fffh,簇号是12位比特,第4字节(1111 1111)的作为第2簇号的低8位(0-7),第5字节(4F)的低4位(1111)作为第2簇号的高4位(8-11),这样就得到了第2簇号的内容为0fffh;然后第5字节的高4位(0100)作为第3簇号的低4位(0-3),第6字节(0000 0000)作为第3簇号的高8位(4-11),这样便得到了第3簇号的内容为004h;第7字节(0000 0101)作为第4簇号的低8位(0-7),第8字节的低4位(0000)作为第4簇号的高4位(8-11),这样可以得到第4簇号的内容为005h;第8字节的高4位(1111)作为第5簇号的低4位(0-3),第9字节(1111 1111)作为第5簇号的高8位(4-11),这样得到第5簇号的内容为0fffh。

  Fat12文件系统的限制:
  1)文件名:只能是8.3格式的文件名。   

  2)磁盘容量:最多8M。(4096clusters×4sectors/clusters×512bytes、sectors)   

  3)文件碎片严重。(只在磁盘上不存储在不连续的簇内。)

免责声明:文章转载自《Windows文件系统》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇记一次ORACLE的UNDO表空间爆满分析过程Promise.then链式调用顺序下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

mysql的索引以及优化

本人qq群也有许多的技术文档,希望可以为你提供一些帮助(非技术的勿加)。 QQ群:   281442983 (点击链接加入群:http://jq.qq.com/?_wv=1027&k=29LoD19)    QQ:1542385235 什么是索引:当你在字典中查找你的名字的时候,你有两种方式。第一、一页一页的翻,第二、通过拼音、笔画,等查找。那么第...

linux系统中不小心执行了rm -rf ./* 怎么办?解决:文件系统的备份与恢复

XFS提供了 xfsdump 和 xfsrestore 工具协助备份XFS文件系统中的数据。xfsdump 按inode顺序备份一个XFS文件系统。centos7选择xfs格式作为默认文件系统,而且不再使用以前的ext,仍然支持ext4,xfs专为大数据产生,每个单个文件系统最大可以支持8eb,单个文件可以支持16tb,不仅数据量大,而且扩展性高。还可以通...

python 字典的操作

可变类型与不可变类型 (字典的键必须是不可变类型的即时可哈希的) 不可变类型,值不可以改变:(可哈希) 数值类型 int, long, bool, float 字符串 str 元组 tuple 可变类型,值可以改变:(不可哈希) 列表 list 字典 dict 字典的常见操作: #增加 变量名['键'] = 数据 如果在使用 变量名['键'] =...

C++ limits头文件的用法(numeric_limits)

初学C++的时候,对这个模板很陌生,不知道它到底是做什么用的,今天拿起《C++标准程序库》,出现了它的讨论,所以决定好好研究一番。 1. numeric_limits是什么? (A)《C++标准程序库》:   [cpp] view plaincop 一般来说,数值型别的极值是一个与平台相关的特性。C++标准程序库通过template numeric_...

Redis bigkey分析

一 现象 某个业务最近2个月每月1号凌晨0点都有业务高峰,但是业务所使用的 Redis 服务 cpu 负载100% ,无法对外提供服务进而影响整体业务访问。 二 分析 2.1 问题分析 因为该业务使用的是云Redis ,我们通过监控看 CPU,QPS ,带宽。   出现问题时系统的QPS 大约为 1200 左右,但是对应时刻的出口带宽竟然达到500MB...

小记 TypeScript 中的循环引用问题

转载至:https://blog.csdn.net/tkokof1/article/details/108984865 平时编写 TypeScript 代码时,一般都倾向于使用模块(Module),通过结合使用 import 和 export 我们便可以方便的进行模块的导入和导出. 举个简单的例子,假设我们有以下的 TypeScript 代码文件(A.ts...