微軟在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參數(磁頭/柱面/扇區) |
|---|---|---|---|---|
| 0 | 1(512B) | 引導程序 | 起:0/0/1 | |
| 1 | 9(4608B) | FAT文件分配表1 | 起:0/0/2 止:0/0/10 | |
| 10 | 9(4608B) | FAT文件分配表2 | 起:0/0/11 止:1/0/1 | |
| 19 | 14(9728B) | 根目錄 | ||
| 33 | 14(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扇區結束,在引導扇區的數據結構中明明確的指出了這些位置。
文件分配表數據結構如下圖所示:
在FAT表開始扇區的第1字節是存儲介質,0f0h代表軟盤,0f8代表硬盤;第2、3這兩個字節都是0ffh,代表了FAT文件分配表標識符,從第四個字節開始與用戶數據區所有的簇一一對應,應該注意的是,用戶數據區的第一個簇的序號是002,而不是000,因為儲存介質和標識符占用了這兩個序號。
在FAT12格式中用12比特位來代表一個簇的序號,我們知道,每個字節有8位比特,所以每個簇要占用1.5個字節,也就是說,占用了第1字節和第2字節的一半才能表示一個簇的序號,半字節的拆分辦法按照下圖的方式進行:
例如:在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)文件碎片嚴重。(只在磁盤上不存儲在不連續的簇內。)


