本文轉自:http://blog.csdn.net/mjx91282041/article/details/8904705
說明:
MBR :Master Boot Record ( 主開機記錄)
DBR :DOS Boot Record ( 引導扇區)
FAT :File Allocation Table ( 檔案分配表)
硬體:本文SD卡為Kingston 4GB,FAT32格式,簇大小4KB,每扇區512位元組。
第一章 硬碟結構與SD卡結構
1.1 硬碟介紹
1.1硬碟結構
如果你熟悉硬碟結構跳過本節。下圖是硬碟的結構,如果你只是為了學習SD卡FAT32檔案系統的話,這裡你只需要注意硬碟排序結構:主開機記錄(MBR)—引導扇區—資料—引導扇區—資料。
圖1
1.2 MBR分析
MBR(Main Boot Record 主開機記錄區)放置在硬碟實體地址0的地方。總共512位元組的主引導扇區中,MBR只佔用了其中的446個位元組,另外64個位元組交給了 DPT(Disk Partition Table硬碟分割槽表),最後兩個位元組“55,AA”是分割槽的結束標誌。DPT由4個分割槽表組成,每個16位元組。下圖中以以硬碟的MBR圖,粉紅色為硬碟分割槽表。
圖2
對於我們來說,更關注硬碟分割槽表表中紅色區域:下圖為硬碟分割槽表詳細說明 。如果要對SD卡、U盤等分多個區,DPT的內容就表示各個區的偏移地址和大小。
起始地址 |
位元組數 |
描述 |
0x1BE |
1 |
可引導標誌,0x00不可引導,0x80可引導 |
0x1BF~0x1C1 |
3 |
分割槽起始CHS地址(CHS=磁頭、柱面、扇區),起始地址 |
0x1C2 |
1 |
分割槽型別 |
0x1C3~0x1C5 |
3 |
分割槽結束CHS地址 |
0x1C6 |
4 |
從磁碟開始到該分割槽開始的偏移量(分割槽起始LBA地址Little-endian順序) |
0x1CA |
4 |
總扇區數(Little-endian順序) |
圖3
SD結構
SD卡沒有分割槽,預設就是一個分割槽。首先用WinHex檔案開啟SD所在的碟符,顯示如下圖:
圖4
① 非分割槽空間(紅線所示): 起始扇區0,我認為這個分割槽就是硬碟上的MBR所在區域,
開啟後如下圖所示,也可以稱為SD卡的MBR區域。
圖5
根據表1知道:
紅線區域(00002000)為下個分割槽的扇區地址,即第8192扇區,見圖3分割槽1的起始扇區。
藍線區域(00760C00)為SD卡總的扇區個數,我們可以計算一下:
0x760C00 *512(每扇區位元組)= 3960995840 (位元組),與實際大小基本一樣。
② 分割槽1(藍線所示):起始扇區8192.
③ 剩餘扇區 : 才疏學淺,我不知道幹嘛的,呵呵
1.3 SD卡儲存結構
由此可知SD卡檔案系統並不是處在整個SD卡最開始的地方,它處在MBR所處的保留區之後,於是我們可以對使用FAT32檔案系統的SD卡整體佈局給出如下圖示。
圖6
第二章 FAT32檔案系統介紹
2.1 FAT檔案系統簡介
FAT(File Allocation Table,檔案分配表)檔案系統是windows作業系統所使用的一種檔案系統,它的發展過程經歷了FAT12、FAT16、FAT32三個階段。FAT檔案系統用“簇”作為資料單元。一個“簇”由一組連續的扇區組成,簇所含的扇區數必須是2的整數次冪。簇的最大值為64個扇區,即32KB。所有簇從2開始進行編號,每個簇都有一個自己的地址編號。使用者檔案和目錄都儲存在簇中。 本文每簇4KB大小。
FAT檔案系統的資料結構中有兩個重要的結構:檔案分配表和目錄項:
檔案分配表:檔案和資料夾內容儲存在簇中,如果一個檔案或資料夾需要多餘一個簇的空間,則用FAT表來描述,如何找到另外的簇。FAT結構用於指出檔案的下一個簇,同時也說明了簇的分配狀態。FAT12、FAT16、FAT32這三種檔案系統之間的主要區別在與FAT項的大小不同。
目錄項:FAT檔案系統的每一個檔案和資料夾都被分配到一個目錄項,目錄項中記錄著檔名、大小、檔案內容起始地址以及其他一些後設資料。
在FAT檔案系統中,檔案系統的資料記錄在“引導扇區中(DBR)”中。引導扇區位於整個檔案系統的0號扇區,是檔案系統隱藏區域(也稱為保留區)的一部分,我們稱其為DBR(DOS Boot Recorder——DOS引導記錄)扇區,DBR中記錄著檔案系統的起始位置、大小、FAT表個數及大小等相關資訊。在FAT檔案系統中,同時使用“扇區地址”和“簇地址”兩種地址管理方式。這是因為只有儲存使用者
資料的資料區使用簇進行管理(FAT12和FAT16的根目錄除外),所有簇都位於資料區。其他檔案系統管理資料區域是不以簇進行管理的,這部分割槽域使用扇區地址進行管理。檔案系統的起始扇區為0號扇區。
2.2 FAT32檔案系統結構
FAT檔案系統整體分佈如上圖 儲存器檔案結構圖 所示,有:
【1深綠色】保留區含有一個重要的資料結構——系統引導扇區(DBR)。FAT12、FAT16的保留區通常只有一個扇區,而FAT32的保留扇區要多一些,除0號扇區外,還有其他一些扇區,其中包括了DBR的備份扇區。
【2黃色】 FAT區由來年各個大小相等的FAT表組成——FAT1、FAT2,FAT2緊跟在FAT1之後。
【3灰色】 FAT12、FAT16的根目錄雖然也屬於資料區,但是他們並不由簇進行管理。也就是說FAT12、FAT16的根目錄是沒有簇號的,他們的2號簇從根目錄之後開始。而FAT32的根目錄通常位於2號簇。
2.2.1 保留區(深綠色區域)
FAT32檔案系統的開始部分有一個由若干個扇區組成的保留區,保留區的大小會記錄在DBR扇區中,比較常見的為32、34或38個扇區。如上圖:由DBR中)0x0e和0x0f兩個地址的數值決定,記得是小端模式,即N的值。
2.2.1.1 引導扇區(DBR)
【大小】:512位元組;
對讀寫FAT檔案系統來說常用的就圖中紅色劃線部分,48個位元組。其他的均為一些標註資訊。想了解具體的定義請看附錄表。
圖7
【1】0x00~0x02:3位元組,跳轉指令。
【2】0x03~0x0A:8位元組,檔案系統標誌和版本號,這裡為MSDOC5.0。
【3】0x0B~0x0C:2位元組,每扇區位元組數,512(0X02 00)。
【4】0x0D~0x0D:1位元組,每簇扇區數,8(0x08)。
【5】0x0E~0x0F:2位元組,保留扇區數,38(0x00 26),符合FAT1起始地址為38扇區。
【6】0x10~0x10:1位元組,FAT表個數,2。
【7】0x11~0x12:2位元組,FAT32必須等於0,FAT12/FAT16為根目錄中目錄的個數;
【8】0x13~0x14:2位元組,FAT32必須等於0,FAT12/FAT16為扇區總數。
【9】0x15~0x15:1位元組,哪種儲存介質,0xF8標準值,可移動儲存介質,常用的 0xF0。
【10】0x16~0x17:2位元組,FAT32必須為0,FAT12/FAT16為一個FAT 表所佔的扇區數。
【11】0x18~0x19:2位元組,每磁軌扇區數,只對於有“特殊形狀”(由磁頭和柱面每 分割為若干磁軌)的儲存介質有效,63(0x00 3F)。
【12】0x1A~0x1B:2位元組,磁頭數,只對特殊的介質才有效,255(0x00 FF)。
【13】0x1C~0x1F:4位元組,EBR分割槽之前所隱藏的扇區數,8192(0x00 00 20 00),與MBR中地址0x1C6開始的4個位元組數值相等。
【14】0x20~0x23:4位元組,檔案系統總扇區數,7736320(0x 00 76 0C 00),7736320 * 512 = 3960995840 ≈ 3.67GB。
【15】0x24~0x27:4位元組,每個FAT表佔用扇區數,7541(0x 00 00 1D 75)。
【16】0x28~0x29:2位元組,標記,此域FAT32 特有。
【17】0x2A~0x2B:2位元組,FAT32版本號0.0,FAT32特有。
【18】0x2C~0x2F:4位元組,根目錄所在第一個簇的簇號,2。(雖然在FAT32檔案系統 下,根目錄可以存放在資料區的任何位置,但是通常情況下還是起始於2號簇)
【19】0x30~0x31:2位元組,FSINFO(檔案系統資訊扇區)扇區號1,該扇區為操作 系統提供關於空簇總數及下一可用簇的資訊。
【20】0x32~0x33:2位元組,備份引導扇區的位置。備份引導扇區總是位於檔案系統 的6號扇區。
【21】0x34~0x3F:12位元組,用於以後FAT 擴充套件使用。
【22】0x40~0x40:1位元組,與FAT12/16 的定義相同,只不過兩者位於啟動扇區不
同的位置而已。
【23】0x41~0x41:1位元組,與FAT12/16 的定義相同,只不過兩者位於啟動扇區不
同的位置而已 。
【24】0x42~0x42:1位元組,擴充套件引導標誌,0x29。與FAT12/16 的定義相同,只不過 兩者位於啟動扇區不同的位置而已
【25】0x43~0x46:4位元組,卷序列號。通常為一個隨機值。
【26】0x47~0x51:11位元組,卷標(ASCII碼),如果建立檔案系統的時候指定了卷 標,會儲存在此。
【27】0x52~0x59:8位元組,檔案系統格式的ASCII碼,FAT32。
★【28】0x5A~0x1FD:90~509共410位元組,未使用。該部分沒有明確的用途。
【29】0x1FE~0x1FF:簽名標誌“55 AA”。
★說明:引導程式碼
FAT檔案系統將引導程式碼與檔案形同資料結構融合在一起,FAT32檔案系統引導扇區的512位元組中,90~509位元組為引導程式碼,而FAT12/16則是62~509位元組為引導程式碼。同時,FAT32還可以利用引導扇區後的扇區空間存放附加的引導程式碼。一個FAT卷即使不是可引導檔案檔案系統,也會存在引導程式碼。
2.2.1.2 FSInfo資訊分割槽
FAT32在保留區中增加了一個FSINFO扇區,用以記錄檔案系統中空閒簇的數量以及下一可用簇的簇號等資訊,以供作業系統作為參考。FSINFO資訊扇區一般位於檔案系統的1號扇區,結構非常簡單。FSINFO資訊扇區結構。
圖8
【1】0x00~0x03: 4個位元組,擴充套件引導標誌“0x52526141”。
【2】0x04~0x1E3:480個位元組,未使用,全部置0。
【3】0x1E4~0x1E7: 4個位元組,FSINFO簽名“0x72724161”。
【4】0x1E8~0x1EB: 4個位元組,檔案系統的空簇數,964466(0x00 0E B7 72)。
【5】0x1EC~0x1EF: 4個位元組,下一可用簇號(0x 00 00 00 15)。
【6】0x1F0~0x1FD: 14個位元組,未使用。
【7】0x1FE~0x1FF: 2個位元組,“55 AA”標誌。
溫馨提示:通常情況下,檔案系統的2號扇區結尾也會被設定“55 AA”標誌。6號扇區也會有一個引導扇區的備份,相應的,7號扇區應該是一個備份FSINFO資訊扇區,8號扇區可以看做是2號扇區的備份。
2.2.2 檔案分割槽FAT表(黃色區域)
緊跟在保留分割槽後面的是FAT區,其由兩個完全相同的FAT(File Allocation Table, 檔案分配表)表單組成,FAT檔案系統的名字也是因此而來。FAT 表(File Alloacation Table)是一組與資料簇號對應的列表。FAT2緊跟在FAT1之後,它的位置可以通過FAT1的位置加上FAT表的大小扇區數計算出來。
2.2.2.1 檔案系統概述
檔案系統分配磁碟空間按簇來分配。因此,檔案佔有磁碟空間時,基本單位不是位元組而是簇,即使某個檔案只有一個位元組,作業系統也會給它分配一個最小單元:即一個簇。對於大檔案,需要分配多個簇。同一個檔案的資料並不一定完整地存放在磁碟中一個連續地區域內,而往往會分若干段,像鏈子一樣存放。這種儲存方式稱為檔案的鏈式儲存。為了實現檔案的鏈式儲存,檔案系統必須準確地記錄哪些簇已經被檔案佔用,還必須為每個已經佔用的簇指明儲存後繼的下一個簇的簇號,對於檔案的最後一簇,則要指明本簇無後繼簇。這些都是由FAT表來儲存的,FAT 表對應表項中記錄著它所代表的簇的有關資訊:諸如是空,是不是壞簇,是否是已經是某個檔案的尾簇等。
v 對於檔案系統來說,FAT表有兩個重要作用:描述簇的分配狀態以及標明檔案或目錄的下一簇的簇號。
v 通常情況下,一個FAT把檔案系統會有兩個FAT表,但有時也允許只有一個FAT表,FAT表的具體個數記錄在引導扇區的偏移0x10位元組處。
v 由於FAT區緊跟在檔案系統保留區後,所以FAT1在檔案系統中的位置可以通過引導記錄中偏移0x0E~0x0F位元組處的“保留扇區數”得到,如儲存器結構體圖中M值。
2.2.2.2 FAT表分析說明
FAT32中每個簇的簇地址是有32bit(4個位元組),FAT表中的所有位元組位置以4位元組為單位進行劃分,並對所有劃分後的位置由0進行地址編號。0號地址與1號地址被系統保留並儲存特殊標誌內容。從2號地址開始,每個地址對應於資料區的簇號,FAT表中的地址編號與資料區中的簇號相同。我們稱FAT表中的這些地址為FAT表項,FAT表項中記錄的值稱為FAT表項值。
當檔案系統被建立,也就是進行格式化操作時,分配給FAT區域的空間將會被清空,在FAT1與FAT2的0號表項與1號表項寫入特定值。由於建立檔案系統的同時也會建立根目錄,也就是為根目錄分配了一個簇空間,通常為2號簇,與之對應的2號FAT表項記錄為2號簇,被寫入一個結束標記。
幾點說明:
Ø 由於簇號起始於2號,所以FAT表項的0號表項與1號表項不與任何簇對應。FAT32的0號表項值總是“F8FFFF0F”。
Ø 1號表項可能被用於記錄髒標誌,以說明檔案系統沒有被正常解除安裝或者磁碟表面存在錯誤。不過這個值並不重要。正常情況下1號表項的值為“FFFFFFFF”或“FFFFFF0F”。
Ø 如果某個簇未被分配使用,它對應的FAT表項內容為0;
Ø 當某個簇已被分配使用,則它對應的FAT表項內的FAT表項值也就是該檔案的下一個儲存位置的簇號。如果該檔案結束於該簇,則在它的FAT表項中記錄的是一個檔案結束標記,對於FAT32而言,代表檔案結束的FAT表項值為0x0FFFFFFF。
Ø 如果某個簇存在壞扇區,則整個簇會用0xFFFFFF7標記為壞簇,這個壞簇標記就記錄在它所對應的FAT表項中。
Ø 在檔案系統中新建檔案時,如果新建的檔案只佔用一個簇,為其分配的簇對應的FAT表項將會寫入結束標記。如果新建的檔案不只佔用一個簇,則在其所佔用的每個簇對應的FAT表項中寫入為其分配的下一簇的簇號,在最後一個簇對應的FAT表象中寫入結束標記。
Ø 新建目錄時,只為其分配一個簇的空間,對應的FAT表項中寫入結束標記。當目錄增大超出一個簇的大小時,將會在空閒空間中繼續為其分配一個簇,並在FAT表中為其建立FAT錶鏈以描述它所佔用的簇情況。
2.2.2.3 FAT表示例
【0號表項】:0x0FFFFFF8;FAT表起始固定標識
【1號表項】:0xFFFFFFFF;不是用,預設值
【2號表項】:0x0FFFFFFF;根目錄所在簇,
紫色的為3號表項,綠色的為4號表項,以此類推。注意:0和1號表項均不與實際的實體地址對應,2號表項開始才與實體地址對應。2號表項實體地址為FAT2表後緊跟著的那個簇!3號在2號表項緊跟著的一個簇。
計算:FAT所佔扇區數 7541(0x1D75);FAT2起始扇區為38+7541=7579;根目錄起始扇區在7579 + 7541 = 15120。記得本文8個扇區為一個簇,即4K(0x1000),簇是系統分配記憶體的最小單元。
如圖表中的起始地址對比,發現根目錄起始地址剛好在15120,所以FAT表中0和1號表項沒有對應實體地址!
圖9
我將SD格式化,新建了一個test.txt的文字檔案,大小為8.2kB。如下圖:
圖10
我們來分析上圖:
在圖中可以看出,test.txt檔案起始簇為15128,這個地址是我們根目錄(2號簇)後的一個簇,所以test.txt檔案起始簇是3號簇,也就是3號表項(FAT表中表項值與簇號對應)。
【1】:2號表項為根目錄,即2號簇。
【2】:3號表項為-0x00 00 00 04,test檔案的下一簇號在4號表項,檢視4號表項。
【3】:4號表項為-0x00 00 00 05,test檔案下一簇號在5號表項,檢視5號表項。
【4】:5號表項為-0x0F FF FF FF,結束符號。說明檔案在5號簇時就儲存完畢。
2.2.3 資料區(灰色區域)
資料區時真正用於存放使用者資料的區域。資料區緊跟在FAT2之後,被劃分成一個個的簇。所有的簇從2開始進行編號,也就是說,2號簇的起始位置就是資料區的起始位置。
2.2.3.1 根目錄
FAT表示例中,根目錄截圖:
圖11
雖然原則上FAT32允許根目錄位於資料區的任何位置,但通常情況下它都位於資料區起始扇區,2號簇,可以在DBR偏移地址0x2C~0x2F檢視。在FAT檔案系統中,先要尋找資料區的第一簇(即2號簇)的位置,它不是位於檔案系統開始處,而是位於資料區。從前面的學習知道,在資料區前面是保留區域和FAT區域,在前面還有MBR區域,這些區域都不使用FAT表進行管理。因此,資料區以前的區域只能使用扇區地址,而無法使用簇地址。
其實在2.2.2.3節,FAT表示例中我們就已經計算過其實地址(15128),注意這個地址不是實體地址哦,只是在FAT檔案區域中一個相對地址!因為在之前還有MBR保留區域!
【保留區域大小(綠色部分)】:DBR偏移地址0x0E~0x0F,38(0x26),
【FAT表個數】:DBR偏移地址0x10開始2位元組,2個,
【每個FAT表扇區數】:DBR偏移地址0x24~0x27,7541(0x 00 00 1D 75),
說明:以上值均參見2.2.1.1節。
【計算公式】:
資料區起始扇區號 = 保留扇區數 + 每個FAT表大小扇區數 × FAT表個數
【示例】: 資料區起始扇區號 = 38 + 7541*2 = 15120
為了避免根目錄被更改,也可以用下面的計算公式計算出根目錄扇區:
根目錄起始扇區=保留扇區數+FAT×2+(根目錄起始簇-2)x每簇的扇區數。
說明:1、如果要得到實體地址,需要加上MBR保留區域大小。
2.2.3.2 根目錄的短檔案目錄項定義
目錄所在的扇區,都是以32 Bytes劃分為一個單位,每個單位稱為一個目錄項(Directory
Entry ),即每個目錄項的長度都是32 Bytes 。根目錄由若干個目錄項組成,一個目錄項佔用32個位元組,可以是長檔名目錄項、檔案目錄項、子目錄項等。32位元組的具體定義如下圖:
圖12
示例:
圖13
特別關注的引數說明:
【1】:檔案或者資料夾儲存的起始簇號,上圖中紫色區域,偏移地址:0x14-0x15(高16為)和0x1A-0x1B(低16位),0x 00 00 00 03 ,表示這個檔案儲存在3號簇的位置,在FAT表中為3號表項。
【2】:檔案大小:偏移地址0x1C-0x1F,0x 00 00 20 EE(8430位元組);
【3】檔案屬性:偏移地址0x0B-0x0B,0x20 ,歸檔。
其他說明:
【0】子目錄儲存在資料區
【1】檔名的第一個位元組,為0xE5,表示該項已被刪除。
【2】名字為0x2E(“.”),表示當前目錄。
圖14
【3】名字為0x2E 0x2E(“. .”),表示上一級目錄。
2.2.3.3 長檔案目錄定義
圖15