詳解FAT32文件系統
硬盤是用來存儲數據的,為了使用和管理方便,這些數據以文件的形式存儲在硬盤上。任何操作系統都有自己的文件管理系統,不同的文件系統又有各自不同的邏輯組織方式。例如:常見的文件系統有FAT,NTFS,EXT,UFS,HFS+等等。下面就來學習一下基於Windows的FAT32文件系統。
FAT32文件系統由DBR及其保留扇區,FAT1,FAT2和DATA四個部分組成,其機構如下圖:
這些結構是在分區被格式化時創建出來的,含義解釋如下:
DBR及其保留扇區:DBR的含義是DOS引導記錄,也稱為操作系統引導記錄,在DBR之后往往會有一些保留扇區。
FAT1:FAT的含義是文件分配表,FAT32一般有兩份FAT,FAT1是第一份,也是主FAT。
FAT2:FAT2是FAT32的第二份文件分配表,也是FAT1的備份。
DATA:DATA也就是數據區,是FAT32文件系統的主要區域,其中包含目錄區域。
一、分析FAT32文件系統的DBR
FAT32文件系統的DBR有5部分組成,分別為跳轉指令,OEM代號,BPB,引導程序和結束標志。如下圖是我U盤上一個完整的FAT32文件系統的DBR。
E8 58 90 :(跳轉指令) 本身占2字節它將程序執行流程跳轉到引導程序處。
“EB 58 90″清楚地指明了OS引導代碼的偏移位置。jump 58H加上跳轉指令所需的位移量,即開始於0x5A。
4D 53 57 49 4E 34 2E 31 :(OEM代號) 這部分占8字節,其內容由創建該文件系統的OEM廠商具體安排。
跳轉指令之后是8字節長的OEM ID,它是一個字符串, OEM ID標識了格式化該分區的操作系統的名稱和版本號。為了保留與MS-DOS的兼容性,通常Windows 2000格式化該盤是在FAT16和FAT32磁盤上的該字段中記錄了“MSDOS 5.0”,在NTFS磁盤上(關於ntfs,另述),Windows 2000記錄的是“NTFS”。通常在被Windows 95格式化的磁盤上OEM ID字段出現“MSWIN4.0”,在被Windows 95 OSR2和Windows 98格式化的磁盤上OEM ID字段出現“MSWIN4.1”。
BPB:FAT32的BPB從DBR的第12個字節開始,占用79字節,記錄了有關該文件系統的重要信息,各參數解釋如下表:
前面53個字節是BPB,后面26個字節是擴展BPB。
對照上面分析:
02 00:每扇區512字節
40:每簇64個扇區
26 B0:保留9904個扇區
02:FAT數
00 00:根目錄項數為0
00 00:小扇區數為0
F8:硬盤
00 00:每FAT扇區數為0
00 3F:每磁道63個扇區
00 80:128磁頭
00 00 1F 80:隱藏扇區8064
03 A8 E4 00:總共61400064個扇區
00 00 1D 48:每個FAT有7496個扇區
00:擴展標志
00 00:文件系統版本
00 00 00 02:根目錄簇號2
00 01:文件系統信息扇區號
00 08:備份引導扇區
后12個字節為0:保留
00:軟盤驅動器
01:未知
29:擴展引導標簽
78 7B 52 18:分區引導序號
4B 49 4E 47 53 54 4F 4E 20 20 20:卷標KINGSTON
46 41 54 33 32 20 20 20:系統ID FAT32
FAT32文件系統在DBR的保留扇區中安排了一個文件系統信息扇區,用以記錄數據區中空閑簇的數量及下一個空閑簇的簇號,該扇區一般在分區的1號扇區,也就是緊跟着DBR后的一個扇區,其內容如下:
52 52 61 41:擴展引導標簽
接下來的480個字節:未用
72 72 41 61:文件系統信息簽名
00 02 07 9E:空閑簇數
00 00 01 8F:下一個空閑簇的簇號
接下來的14個字節:未用
55 AA:結束標志
引導程序代碼:FAT32的DBR引導程序占用420字節,對於沒有安裝操作系統的分區來說這段程序是沒有用處的。
結束標志:DBR的結束標志與MBR,EBR的結束標志相同,為“55 AA”。
二、分析FAT32文件系統的FAT表
從FAT32的組織形式來看FAT1在保留扇區(包括引導扇區)的后面,然后就是FAT2.
所以我們在加上保留扇區的數量來到FAT1的第一個扇區:
FAT文件系統之所以有12,16,32不同的版本之分,其根本在於FAT表用來記錄任意一簇鏈接的二進制位數。以FAT16為例,每一簇在FAT表中占據2字節(二進制16位)。所以,FAT16最大可以表示的簇號為0xFFFF(十進制的65535),以32K(最多只支持64個扇區)為簇的大小的話,FAT16可以管理的最大磁盤空間為:32KB×65535=2048MB,這就是為什么FAT16不支持超過2GB分區的原因(DOS下)。
FAT表結構及作用
1、FAT32文件一般有兩份FAT,他們由格式化程序在對分區進行格式化時創建,FAT1是主,FAT2是備份。
2、FAT1跟在DBR之后,其具體地址由DBR的BPB參數中指定,FAT2跟在FAT1的后面。
3、FAT表由FAT表項構成,我們把FAT表項簡稱FAT項,每個FAT項占用4字節。
4、每個FAT項都有一個固定的編號,這個編號從0開始。
5、FAT表項的前兩個FAT項為文件系統保留使用,0號FAT為介質類型,1號FAT為文件系統錯誤標志。
6、分區的數據區中每個簇都會映射到FAT表中的唯一一個FAT項,因為0號FAT和1號FAT被系統占用,用戶的數據從2號FAT開始記錄。
7、如果某個文件占用很多個簇,則第一個FAT項記錄下一個FAT項的編號(既簇號),如果這個文件結束了,則用“0F FF FF FF”表示。
8、分區格式化后,用戶文件以簇為單位存放在數據區中,一個文件至少占用一個簇。
9、FAT的主要作用是標明分區存儲的介質以及簇的使用情況。
定位FAT絕對位置的方法如下:
1、首先從MBR的分區表中得知分區的起始扇區,偏移到此扇區。
2、從DBR的BPB中得知DBR的保留扇區數,FAT表的個數,FAT表的大小。
3、因此FAT1=分區起始扇區+DBR保留扇區,FAT2=分區起始扇區+DBR保留扇區+FAT1。
下圖為FAT1的第一個扇區:
上面是從第0項開始的,第0項和第1項暫時就不用看了,從第2項開始,為0F FF FF FF,表示這是一個小文件,只占用一個簇就結束了,然后第3、4項也是的。
第5簇中存放的數據是6,這又是一個文件或文件夾的首簇。其內容為第6簇,就是說接下來的簇位於第6簇——〉FAT表指引我們到達FAT表的第6簇指向,上面寫的數據是7,就是說接下來的簇位於第7簇——〉FAT表指引我們到達FAT表的第7簇指向……直到根據FAT鏈讀取到扇區相對偏移0×20~0×24,也就是第8簇,上面寫的數據是9,也就是指向第9簇——〉第9簇的內容為”0F FF FF FF”,意即此文件已至尾簇。
下面的同樣的分析方法,我就不一一分析了。
三、分析FAT32文件系統的數據區
數據區的位置在FAT2的后面,具體定位方式如下;
1、通過MBR中的分區表信息得知分區的起始位置。
2、通過分區中DBR得知DBR的保留扇區數以及FAT表的大小,FAT表的個數。
3、通過上面的信息就可以找到數據區的起始位置,數據區 = 隱藏扇區數+DBR保留扇區+(每個FAT表扇區數*2)。
數據區的類容主要由三部分組成:根目錄,子目錄和文件內容。在數據區中是以“簇”為單位進行存儲的,2號簇被分配給根目錄使用。
根據簇號得到在FAT中的扇區號和偏移:
扇區號 = 簇號*4/每個扇區的字節數 + 隱藏扇區數 + 保留扇區數
扇區偏移 = 簇號*4%每個扇區的字節數
根據簇號得到起始扇區號:
簇號起始扇區 = (簇號-2)* 每個簇的扇區數 + 隱藏扇區數 + 保留扇區數 + FAT數*每個FAT占扇區數
下圖為根目錄的第一個扇區:
FAT32文件系統中,分區根目錄下的文件和目錄都放在根目錄區中,子目錄中的文件和目錄都放在子目錄區中,並且每32個字節為一個目錄項(FDT),每個目錄項紀錄着一個目錄或文件(也可能是多個目錄項記錄一個文件或目錄),如上圖所示就是一個目錄項。
在FAT32文件系統中,目錄項可以分為四類:卷標目錄項、“.”和“..”目錄項、短文件名目錄項、長文件名目錄項。
卷標目錄項:卷標就是分區的名字,可以在格式化分區時創建,也可以隨意修改,長度為11字節。
“.”和“..”目錄項:“.”表示當前目錄,“..”表示上一層目錄。這兩個目錄項多存在子目錄中。
短文件名目錄項:所謂短文件名既文件名的“8.3”格式,此格式支持主文件名不能超過8字節,擴展名不能超過3字節。短文件名目錄始終存放在一個目錄項中。
FDT第1字節又表明了該文件的狀態,它有如下四種取值方式:
a. 00H–目錄項的空目錄。
b. E5H–表示該目錄項曾經使用過,但文件已被刪除。
c. 2EH–表示子目錄下的兩個特殊文件 “. “或 “.. “目錄項
d. 其它任何字符–表示一個文件名(或目錄名)的第一個字符的ASCII碼值.
FAT第0xB個字節可以判別是長文件目錄項還是短文件目錄項。
FAT32短文件目錄項32個字節的表示定義如下:
正如上面的第一個FDT就是一個短文件目錄項:
文件名為GAMES
關於時間的表達方式:10111(23) 111000(56) 00001(1*2)時間值:23時56分02秒。
關於日期的表達方式:0011101(29+1980) 1010(10) 10011(19)時間值:2009年10月19日。
長文件名目錄項:由於短文件名“8.3”的格式遠遠不能滿足現實中的需求,所以就出現了長文件名。
FAT32長文件目錄項32個字節的表示定義如下:
根據表中的長文件名組合方法我們可以得到上面根目錄的第一個扇區中第7個FDT的長文件名為:urDrive
如果是目錄的話可以轉到起始簇號在FAT1中的位置,然后轉到相應的扇區分析FDT來枚舉文件信息。
詳解NTFS文件系統
上篇在詳解FAT32文件系統中介紹了FAT32文件系統存儲數據的原理,這篇就來介紹下NTFS文件系統。NTFS、用過Windows系統的人都知道,它是一個很強大的文件系統,支持的功能很多,存儲的原理也很復雜。目前絕大多數Windows用戶都是使用NTFS文件系統,它主要以安全性和穩定性而聞名,下面是它的一些主要特點。
安全性高:NTFS支持基於文件或目錄的ACL,並且支持加密文件系統(EFS)。
可恢復性:NTFS支持基於原子事務概念的文件恢復,比較符合服務器文件系統的要求。
文件壓縮:NTFS支持基於文件或目錄的文件壓縮,可以很方便的節省磁盤空間。
磁盤配額:NTFS支持磁盤配額,可針對系統中每個用戶分配磁盤資源。
一、分析NTFS文件系統的結構
當用戶將硬盤的一個分區格式化為NTFS分區時,就建立了一個NTFS文件系統。NTFS文件系統同FAT32文件系統一樣,也是用“簇”為存儲單位,一個文件總是占用一個或多個簇。
NTFS文件系統使用邏輯簇號(LCN)和虛擬簇號(VCN)對分區進行管理。
邏輯簇號:既對分區內的第一個簇到最后一個簇進行編號,NTFS使用邏輯簇號對簇進行定位。
虛擬簇號:既將文件所占用的簇從開頭到尾進行編號的,虛擬簇號不要求在物理上是連續的。
NTFS文件系統一共由16個“元文件”構成,它們是在分區格式化時寫入到硬盤的隱藏文件(以”$”開頭),也是NTFS文件系統的系統信息。
NTFS的16個元文件介紹:
首先找到該分區的起始扇區,具體可以參考 后面 MBR分區結構、DPT分區表、EBR擴展引導 這篇文章。
二、分析$Boot文件
$Boot元文件由分區的第一個扇區(既DBR)和后面的15個扇區(既NTLDR區域)組成,其中DBR由“跳轉指令”、“OEM代號”、“BPB”、“引導程序”和“結束標志”組成,這里和FAT32文件系統的DBR一樣。下圖是一個NTFS文件系統完整的DBR。
下面我們分析一下DBR中的各參數
EB 58 90:(跳轉指令)本身占2字節它將程序執行流程跳轉到引導程序處。
“EB 58 90″清楚地指明了OS引導代碼的偏移位置。jump 52H加上跳轉指令所需的位移量,即開始於0×55。
4E 54 46 53 20 20 20 20:(OEM代號)這部分占8字節,其內容由創建該文件系統的OEM廠商具體安排。為“NTFS”。
BPB:NTFS文件系統的BPB從DBR的第12個字節開始,占用73字節,記錄了有關該文件系統的重要信息,下表中的內容包含了“跳轉指令”、“OEM代號”以及“BPB”的參數。
對照上面的BPB分析如下:
02 00:每個扇區512個字節
08:每個簇8個扇區
00 00:保留扇區為0
00 00 00:為0
00:不使用
F8:為硬盤
00 00:為0
00 3F:每磁道63個扇區
00 FF:每柱面255個磁頭
00 00 00 3F:隱藏扇區數(MBR到DBR)
00 00 00 00:不使用
80 00 80 00:不使用
00 00 00 00 0C 80 33 FF:扇區總數209728511
00 00 00 00 00 00 00 03:$MFT的開始簇號
00 00 00 00 00 85 57 80:$MFTmirr的開始簇號
00 00 00 F6:每個MFT記錄的簇數
00 00 00 01:每索引的簇數
B8 11 2A 0C B8 11 2A 0C:分區的邏輯序列號
引導程序:DBR的引導程序占用426字節,其負責完成將系統文件NTLDR裝入,對於沒有安裝系統的分區是無效的。
結束標志:DBR的結束標志與MBR,EBR的結束標志相同,為“55 AA”。
三、分析$MFT元文件
在NTFS文件系統中,磁盤上的所有數據都是以文件的形式存儲,其中包括元文件。每個文件都有一個或多個文件記錄,每個文件記錄占用兩個扇區,而$MFT元文件就是專門記錄每個文件的文件記錄。由於NTFS文件系統是通過$MFT來確定文件在磁盤上的位置以及文件的屬性,所以$MFT是非常重要的,$MFT的起始位置在DBR中有描述。$MFT的文件記錄在物理上是連續的,並且從0開始編號。$MFT的前16個文件記錄總是元文件的,並且順序是固定不變的。
四、分析文件記錄
1、文件記錄的結構
文件記錄由兩部分構成,一部分是文件記錄頭,另一部分是屬性列表,最后結尾是四個“FF”。如下是一個完整的文件記錄:
在同一系統中,文件記錄頭的長度和具體偏移位置的數據含義是不變的,而屬性列表是可變的,其不同的屬性有着不同的含義。后文將對屬性進行具體分析,先來看看文件記錄頭的信息。
在NTFS文件系統中所有與文件相關的數據結構均被認為是屬性,包括文件的內容。文件記錄是一個與文件相對應的文件屬性數據庫,它記錄了文件的所有屬性。每個文件記錄中都有多個屬性,他們相對獨立,有各自的類型和名稱。每個屬性都由兩部分組成,既屬性頭和屬性體。屬性頭的前四個字節為屬性的類型。如下是以10H屬性為例的屬性結構。
另外屬性還有常駐與非常駐之分。當一個文件很小時,其所有屬性體都可以存放在文件記錄中,該屬性就稱為常駐屬性。如果某個文件很大,1KB的文件記錄無法記錄所有屬性時,則文件系統會在$MFT元文件之外的區域(也稱數據流)存放該文件的其他文件記錄屬性,這些存放在非$MFT元文件內的記錄就稱為非常駐屬性。
分析屬性的屬性頭
每個屬性都有一個屬性頭,這個屬性頭包含了一些該屬性的重要信息,如屬性類型,屬性大小,名字(並非都有)及是否為常駐屬性等。
常駐屬性的屬性頭分析表:
如下是非常駐屬性的屬性頭分析表:
前面說過了,屬性的種類有很多,因此各屬性體的含義也不同。下表是NTFS文件系統中的所有屬性體的簡介。
接下來來看幾個重要的屬性:
分析10H屬性:
10H類型屬性它包含文件的一些基本信息,如文件的傳統屬性,文件的創建時間和最后修改時間和日期,文件的硬鏈接數等等。如下:是一個10H類型的屬性。
其中偏移0×20處的文件屬性解釋如下:
分析20H屬性
20H類型屬性既屬性列表,當一個文件需要好幾個文件記錄時,才會用到20H屬性。20H屬性記錄了一個文件的下一個文件記錄的位置。如下:是20H屬性的解釋。
分析30H屬性
30H類型屬,該屬性用於存儲文件名 ,它總是常駐屬性。最少68字節,最大578字節,可容納最大Unicode字符的文件名長度。
分析80H屬性
80H屬性是文件數據屬性,該屬性容納着文件的內容,文件的大小一般指的就是未命名數據流的大小。該屬性沒有最大最小限制,最小情況是該屬性為常駐屬性。常駐屬性就不做多的解釋了,上面我標記的是一個非常駐的80H屬性。
其中,Run List是最難理解,也是最重要的。當屬性不能存放完數據,系統就會在NTFS數據區域開辟一個空間存放,這個區域是以簇為單位的。Run List就是記錄這個數據區域的起始簇號和大小,一個Run List例子上所示。這個示例中,Run List的值為“12 41 47 03”,因為后面是00H,所以知道已經是結尾。如何解析這個Run List呢? 第一個字節是壓縮字節,高位和低位相加,1+2=3,表示這個Data Run信息占用三個字節,其中高位表示起始簇號占用多少個字節,低位表示大小占用的字節數。在這里,起始簇號占用1個字節,值為03,大小占用2個字節,值為47 41。解析后,得到這個數據流起始簇號為3,大小為18241簇。
雖然數據不一樣,但是表達的意思是一樣的。
分析90H屬性
90H屬性是索引根屬性,該屬性是實現NTFS的B+樹索引的根節點,它總是常駐屬性。該屬性的結構如下圖:
索引根的結構如表:
索引頭的結構如表:
索引項結構如表:
分析A0H屬性
A0屬性是索引分配屬性,也是一個索引的基本結構,存儲着組成索引的B+樹目錄索引子節點的定位信息。它總是常駐屬性。如下:是一個A0H屬性的實例。
根據上圖A0H屬性的“Run List”可以找到索引區域,偏移到索引區域所在的簇,如下圖:
起始簇:18265
簇大小:3
起始扇區號 = 該分區的其實扇區 + 簇號 * 每個簇的扇區數 也就是
64 + 18265 * 8 = 146124
對了,上面的偏移0×28還要加上0×18 = 0×40.
標准索引頭的解釋如下:
索引項的解釋如下:
到此一些常用屬性基本介紹的差不多了。
下面來說下遍歷一個分區下面文件列表的思路:
1、定位DBR,通過DBR可以得知“$MFT”的起始簇號及簇的大小。
2、定位“$MFT”,找到“$MFT”后,在其中尋找根目錄的文件記錄,一般在5號文件記錄。
3、在90H屬性中得到B+樹索引的根節點文件信息,重點在A0屬性上。通過屬性中的“Run List”定位到其數據流。
4、從“Run List”定位到起始簇后,再分析索引項可以得到文件名等信息。
5、從索引項中可以獲取“$MFT”的參考號,然后進入到“$MFT”找到對應的文件記錄。
6、然后再根據80H屬性中的數據流就可以找到文件真正的數據了。
MBR分區結構、DPT分區表、EBR擴展引導
主引導記錄(Master Boot Record,縮寫:MBR),又叫做主引導扇區,是計算機開機后訪問硬盤時所必須要讀取的首個扇區,它在硬盤上的三維地址為(0柱面,0磁頭,1扇區)。在深入討論主引導扇區內部結構的時候,有時也將其開頭的446字節內容特指為“主引導記錄”(MBR),其后是4個16字節的“磁盤分區表”(DPT),以及2字節的結束標志(55AA)。因此,在使用“主引導記錄”(MBR)這個術語的時候,需要根據具體情況判斷其到底是指整個主引導扇區,還是主引導扇區的前446字節。如下:
對應到我電腦第一個扇區:
啟動代碼
主引導記錄最開頭是第一階段引導代碼。其中的硬盤引導程序的主要作用是檢查分區表是否正確並且在系統硬件完成自檢以后將控制權交給硬盤上的引導程序(如GNU GRUB)。 它不依賴任何操作系統,而且啟動代碼也是可以改變的,從而能夠實現多系統引導。
硬盤分區表
硬盤分區表占據主引導扇區的64個字節(偏移01BEH–偏移01FDH),可以對四個分區的信息進行描述,其中每個分區的信息占據16個字節。具體每個字節的定義可以參見硬盤分區結構信息。
從主引導記錄的結構可以知道,它僅僅包含一個64個字節的硬盤分區表。由於每個分區信息需要16個字節,所以對於采用MBR型分區結構的硬盤,最多只能識別4個主要分區(Primary partition)。所以對於一個采用此種分區結構的硬盤來說,想要得到4個以上的主要分區是不可能的。這里就需要引出擴展分區了。擴展分區也是主要分區的一種,但它與主分區的不同在於理論上可以划分為無數個邏輯分區。
擴展分區中邏輯驅動器的引導記錄是鏈式的。每一個邏輯分區都有一個和MBR結構類似的擴展引導記錄(EBR),其分區表的第一項指向該邏輯分區本身的引導扇區,第二項指向下一個邏輯驅動器的EBR,分區表第三、第四項沒有用到。
Windows系統默認情況下,一般都是只划分一個主分區給系統,剩余的部分全部划入擴展分區。這里有下面幾點需要注意:
- 在MBR分區表中最多4個主分區或者3個主分區+1個擴展分區,也就是說擴展分區只能有一個,然后可以再細分為多個邏輯分區。
- 在Linux系統中,硬盤分區命名為sda1-sda4或者hda1-hda4(其中a表示硬盤編號可能是a、b、c等等)。在MBR硬盤中,分區號1-4是主分區(或者擴展分區),邏輯分區號只能從5開始。
- 在MBR分區表中,一個分區最大的容量為2T,且每個分區的起始柱面必須在這個disk的前2T內。你有一個3T的硬盤,根據要求你至少要把它划分為2個分區,且最后一個分區的起始扇區要位於硬盤的前2T空間內。如果硬盤太大則必須改用GPT。
那么現在來對主引導扇區中的DPT來進行分析:
80 01 01 00 07 FE FF FF 3F 00 00 00 00 34 80 0C
80:表示該分區為活動分區
01 01 00:開始磁頭/開始扇區和開始柱面
07 :文件系統標志位 07表示NTFS文件系統
FE FF FF :結束磁頭/結束扇區和結束柱面
00 00 00 3F :分區起始的相對扇區號
0C 80 34 00:分區總的扇區數
后面三個表項的分析方法同上。
每一分區的第1至第3字節是該分區起始地址。其中第1字節為起始磁頭號(面號);第2字節的低6位為起始扇區號,高2位則為起始柱面號的高2 位;第3字節為起始柱面號的低8位。因此,分區的起始柱面號是用10位二進制數表示的,最大值為2^10 = 1024,因邏輯柱面號從0開始計,故柱面號的顯示最大值為1023。同理,用6位二進制數表示的扇區號不會超過2^6 – 1 = 63;用8位二進制數表示的磁頭號不會超過2^8 – 1 = 255。每一分區的第5至第7字節表示分區的終止地址,各字節的釋義與第1至第3字節相同。這里我們假設一種極端的情況:如果讓第5至第7字節的所有二進制位都取1,就獲得了柱面號、磁頭號和扇區號所能表示的最大值,從而得到最大絕對扇區號為:
1024 × 256 × 63 = 16,515,072
這個扇區之前的所有物理扇區所包含的字節數為:
16,515,072 × 512Bytes ≈ 8.46GB。
由此可知硬盤的容量設計為什么會有8.4GB這一檔,分區表每一分區的第1至第3字節以及第5至第7字節的數據結構已經不能滿足大於 8.46GB的大容量硬盤的需要。考慮到向下兼容的需要,業界並未對從DOS時代就如此定義的硬盤分區表提出更改意見,否則改動所牽涉的面太廣,會造成硬件和軟件發展上的一個斷層,幾乎無法被業界和用戶所接受。硬盤廠商解決這一問題的方法是定義了新的INT 13服務擴展標准。新的INT 13服務擴展標准不再使用操作系統的寄存器傳遞硬盤的尋址參數,而使用存儲在操作系統內存里的地址包。地址包里保存的是64位LBA地址,如果硬盤支持 LBA尋址,就把低28位直接傳遞給ATA接口,如果不支持,操作系統就先把LBA地址轉換為CHS地址,再傳遞給ATA接口。通過這種方式,能實現在 ATA總線基礎上CHS尋址的最大容量是136.9 GB,而LBA尋址的最大容量是137.4GB。新的硬盤傳輸規范ATA 133規范又把28位可用的寄存器空間提高到48位,從而支持更大的硬盤。
分區表每一分區的第8至第11字節表示該分區的起始相對扇區數(即該扇區之前的絕對扇區個數),高位在右,低位在左;第12至第15字節表示該分區實際占用的扇區數,也是高位在右,低位在左;分區表這類數據結構的表達方式與機器中數據的實際存儲方式在順序上是一致的,即低位在前,高位在后。因此,在從16進制向十進制作數值轉換時,需將字段中的16進制數以字節為單位翻轉調位,用4個字節可以表示最大2^32個扇區,即2TB=2048GB。
系統在分區時,各分區都不允許跨柱面,即均以柱面為單位,這就是通常所說的分區粒度。在未超過8.4GB的分區上,C/H/S的表示方法和扇區數的表示方法所表示的分區大小是一致的。超過8.4GB的/H/S/C一般填充為FEH/FFH/FFH,即C/H/S所能表示的最大值;有時候也會用柱面對 1024的模來填充。不過這幾個字節是什么其實都無關緊要了。
從上面可以看到我電腦的DPT只有一個主分區和一個擴展分區。
主分區從63扇區開始,大小為209728512扇區。 約為100GB也就是我的C盤大小。
擴展分區從209728575扇區開始,大小為415408770扇區。 約為198GB也就是我后面兩個盤的大小。
擴展分區中的每個邏輯驅動器都存在一個類似於MBR的擴展引導記錄(Extended Boot Record,EBR)。
擴展引導記錄包括一個擴展分區表和扇區結束標志55AA。一個邏輯驅動器中的引導扇區一般位於相對扇區32或63。如果磁盤上沒有擴展分區,那么就不會有擴展引導記錄和邏輯驅動器。第一個邏輯驅動器的擴展分區表中的第一項指向它自身的引導扇區;第二項指向下一個邏輯驅動器的EBR,如果不存在進一步的邏輯驅動器,第二項就不會使用,而被記錄成一系列零。如果有附加的邏輯驅動器,那么第二個邏輯驅動器的擴展分區表的第一項會指向它本身的引導扇區,第二個邏輯驅動器的擴展分區表的第二項指向下一個邏輯驅動器的EBR。擴展分區表的第三項和第四項永遠都不會被使用。
擴展分區表項中的相對扇區數是從擴展分區開始的扇區到該邏輯驅動器中第一個扇區的扇區數;占用的扇區數是指組成該邏輯驅動器的扇區數目。
有時候在磁盤的末尾會有剩余空間,由於分區是以1柱面的容量為分區粒度的,那么如果磁盤總空間不是整數個柱面的話,不夠一個柱面的剩下的空間就是剩余空間了,這部分空間並不參與分區,所以一般無法利用。
我們來到擴展分區的EBR。
擴展分區第一項:起始相對63扇區,大小為207640062扇區。 約為99G我D盤的大小。
擴展分區第二項(指向下一個邏輯驅動器的EBR)起始相對207640125扇區,大小為207768645扇區。為我最后一個盤的大小。
再來到這個指向的這個邏輯驅動器的EBR。
只有一項:起始相對63扇區,大小為207768582扇區。約為99G我E盤的大小。
當然末尾還有一些剩余空間。625142448-625137345 2M多的剩余空間。
WinHex和我們分析出來的是一樣的。
所以也可以自己寫個程序來分析。
最后附上幾個常見的分區類型。
GDT(全局描述符表)和LDT(局部描述符表)
每個程序都有自己的LDT,但是同一台計算機上的所有程序共享一個GDT。LDT描述局部於每個程序的段,包括其代碼、數據、堆棧等。GDT描述系統段,包括操作系統本身。
①全局描述符表GDT(Global Descriptor Table)在整個系統中,全局描述符表GDT只有一張(一個處理器對應一個GDT),GDT可以被放在內存的任何位置,但CPU必須知道GDT的入口,也就是基地址放在哪里,Intel的設計者門提供了一個寄存器GDTR用來存放GDT的入口地址,程序員將GDT設定在內存中某個位置之后,可以通過LGDT指令將GDT的入口地址裝入此積存器,從此以后,CPU就根據此寄存器中的內容作為GDT的入口來訪問GDT了。GDTR中存放的是GDT在內存中的基地址和其表長界限。
②段選擇子(Selector)由GDTR訪問全局描述符表是通過“段選擇子”(實模式下的段寄存器)來完成的。為了訪問一個段,一個Pentium程序必須把這個段的選擇子裝入機器的6個段寄存器的某一個中。在運行過程中,CS寄存器保存代碼段的選擇子,DS寄存器保存數據段的選擇子。每個選擇子是一個16位數。
選擇子中的一位指出這個段是局部的還是全局的(它是在LDT中還是在GDT中),其他的13位索引是LDT或GDT的表項編號,表示所需要的段的描述符在描述符表的位置,由這個位置再根據在GDTR中存儲的描述符表基址就可以找到相應的描述符,然后用描述符表中的段基址加上邏輯地址(SEL:OFFSET)的OFFSET就可以轉換成線性地址。因此,這些表的長度被限制在最多容納8K個段描述符。
段選擇子中的TI值只有一位0或1,0代表選擇子是在GDT選擇,1代表選擇子是在LDT選擇。請求特權級(RPL)則代表選擇子的特權級,共有4個特權級(0級、1級、2級、3級)。任務中的每一個段都有一個特定的級別。每當一個程序試圖訪問某一個段時,就將該程序所擁有的特權級與要訪問的特權級進行比較,以決定能否訪問該段。系統約定,CPU只能訪問同一特權級或級別較低特權級的段。
例如給出邏輯地址:21h:12345678h轉換為線性地址
a. 選擇子SEL=21h=0000000000100 0 01b 他代表的意思是:選擇子的index=4即100b選擇GDT中的第4個描述符;TI=0代表選擇子是在GDT選擇;左后的01b代表特權級RPL=1
b. OFFSET=12345678h若此時GDT第四個描述符中描述的段基址(Base)為11111111h,則線性地址=11111111h+12345678h=23456789h
③局部描述符表LDT(Local Descriptor Table)局部描述符表可以有若干張,每個任務可以有一張。我們可以這樣理解GDT和LDT:GDT為一級描述符表,LDT為二級描述符表。如圖
LDT和GDT從本質上說是相同的,只是LDT嵌套在GDT之中。LDTR記錄局部描述符表的起始位置,與GDTR不同LDTR的內容是一個段選擇子。由於LDT本身同樣是一段內存,也是一個段,所以它也有個描述符描述它,這個描述符就存儲在GDT中,對應這個表述符也會有一個選擇子,LDTR裝載的就是這樣一個選擇子。LDTR可以在程序中隨時改變,通過使用lldt指令。如上圖,如果裝載的是Selector 2則LDTR指向的是表LDT2。舉個例子:如果我們想在表LDT2中選擇第三個描述符所描述的段的地址12345678h。
1. 首先需要裝載LDTR使它指向LDT2 使用指令lldt將Select2裝載到LDTR
2. 通過邏輯地址(SEL:OFFSET)訪問時SEL的index=3代表選擇第三個描述符;TI=1代表選擇子是在LDT選擇,此時LDTR指向的是LDT2,所以是在LDT2中選擇,此時的SEL值為1Ch(二進制為11 1 00b)。OFFSET=12345678h。邏輯地址為1C:12345678h
3. 由SEL選擇出描述符,由描述符中的基址(Base)加上OFFSET可得到線性地址,例如基址是11111111h,則線性地址=11111111h+12345678h=23456789h
4. 此時若再想訪問LDT1中的第三個描述符,只要使用lldt指令將選擇子Selector 1裝入再執行2、3兩步就可以了(因為此時LDTR又指向了LDT1)
由於每個進程都有自己的一套程序段、數據段、堆棧段,有了局部描述符表則可以將每個進程的程序段、數據段、堆棧段封裝在一起,只要改變LDTR就可以實現對不同進程的段進行訪問。
段描述符:
P,present位,1表示所描述的段存在(有效),為0表示所描述的段無效,使用該描述符會引起異常
DPL,Descriptor privilege,描述符特權級別,說明所描述段的特權級別
DT,描述符類型位,1說明當前描述符為存儲段描述符,0為系統描述符或門描述符.
TYPE:
位0:A(accessed)位,表明描述符是否已被訪問;把選擇子裝入段寄存器時,該位被標記為1
位3:E(EXECUTABLE?)位,0說明所描述段為數據段;1為可執行段(代碼段)
當為數據段時,
位1為W位,說明該數據段是否可寫(0只讀,1可寫)
位2為ED位,說明該段的擴展方向(0向高位擴展,1向低位擴展)
當為可執行段是,
位1為R位,說明該執行段是否可讀(0只執行,1可讀)
位2為C位,0說明該段不是一致碼段(普通代碼段),1為一致碼段
G為粒度位,0說明LIMIT粒度為字節,1為4K字節.
D位:
1.在可執行段中,D為1,表示使用32位地址,32/8位操作數;為0表示使用16位地址,16/8位操作數
2.在由SS尋址的段描述符(堆棧段?)中,D為1表示隱含操作(如PUSH/POP)使用ESP為堆棧指針,
為0使用SP(隱含操作:未明確定義段屬性類型USE16/USE32?66H,67H?)
3.在向低擴展的存儲段中,D為1,表示段的上限為4G;為0上限為64K
存儲段描述符的結構表示:
分段管理可以把虛擬地址轉換成線性地址,而分頁管理可以進一步將線性地址轉換成物理地址。當CR0中的PG位置1時,啟動分頁管理功能,為0時,這禁止啟動分頁管理功能,並且把線性地址作物理地址使用。
虛擬地址轉為線性地址:
線性地址= 段基指 + 偏移地址
32位線性地址轉為物理地址:
32位分為:
頁目錄索引:占最高10位,指示頁目錄表中第幾個頁表描述符
頁表索引:占12位到21位,也是10位。指示這頁表中第幾個頁描述符
頁描述符:線性地址的低12位為頁內偏移量。