FAT 檔案系統

最後更新: 2025-04-10 18:45:27 +0800 +0800
原文以英文撰寫。您正在閱讀AI翻譯版本。

檔案配置表(File Allocation Table,FAT)家族起源於小型 Microsoft 系統,後來成為 DOS 與 IBM PC 媒體的交換格式。簡單的資料結構使 FAT 適用於開機韌體與受限的作業系統。同一設計不包含日誌記錄、擁有權與交易語意,因此它持續被使用的原因是互通性,而不是故障隔離。

磁碟區配置 #

FAT 磁碟區由以邏輯磁區計量的區域組成:

  1. 保留區域以磁碟區開機磁區及其 BIOS 參數區塊(BPB)開始。FAT32 也可以在此放置 FSInfo 磁區,並通常放置備份開機磁區。
  2. 一個或多個 FAT 副本包含固定寬度的配置項目。慣例上使用兩個副本,但實際數量由 BPB 指定。
  3. 在 FAT12 與 FAT16 中,根目錄區域具有固定位置與項目數量。
  4. 資料區域包含編號後的叢集。在 FAT32 中,根目錄不是固定區域,而是此區域中的一般叢集鏈結。

BPB 提供每磁區位元組數、每叢集磁區數、保留磁區數、FAT 數量、總磁區數與 FAT 大小。讀取器會根據這些欄位推導區域邊界,而不是搜尋目錄簽章。必須檢查算術運算是否溢位,因為損毀的 BPB 值可能使讀取範圍超出磁碟區。

叢集與 FAT 分類 #

叢集是檔案系統的配置單位。在 Microsoft 定義的 FAT 格式中,一個叢集包含數量為 2 的冪次的磁區。叢集編號 0 與 1 為保留編號;資料叢集從 2 開始。資料叢集數量由 BPB 推導如下:

text
root_dir_sectors =
  ceil(root_entry_count × 32 / bytes_per_sector)

first_data_sector =
  reserved_sectors + fat_count × sectors_per_fat + root_dir_sectors

data_clusters =
  floor((total_sectors - first_data_sector) / sectors_per_cluster)

磁碟區的分類依據是叢集數量,而不是標籤字串或分割區類型位元組:

分類資料叢集數量項目表示方式
FAT12少於 4,085封裝的 12 位元項目
FAT164,085 至 65,52416 位元項目
FAT3265,525 或以上32 位元項目,低 28 位元有效

實際可用的上限還取決於叢集大小、實作策略與 BPB 中的欄位。較寬的項目可以表示更多叢集,但每個 FAT 副本會消耗更多磁區。

配置項目與叢集鏈結 #

每個 FAT 項目描述對應的叢集。其值代表:

  • 表示空閒叢集的零值;
  • 表示鏈結中下一個連結的其他叢集編號;
  • 保留叢集或損壞叢集標記;
  • 位於鏈結結尾範圍內的值。

檔案的短目錄項目儲存其第一個叢集與位元組長度。讀取檔案時從該處開始,沿著 FAT 連結讀取,直到取得足夠位元組或遇到結尾標記。最後一個叢集可能包含超出邏輯長度的閒置位元組。FAT32 中的目錄,以及所有非根目錄,都使用相同的叢集鏈結機制。

鏈結配置讓檔案無需找到一個連續的範圍即可成長,但分散的鏈結需要額外的 FAT 查找與非循序 I/O。此表也是共用的故障點。迴圈、超出範圍的連結、過早出現的結尾標記,或同一叢集被兩個檔案宣告使用,都會使目錄中繼資料與配置狀態不一致。

多個 FAT 副本不構成日誌。寫入者可能在更新其中一個副本、目錄項目或鏈結的一部分後失敗。修復軟體必須在過時的副本與推導出的擁有權之間做出選擇;兩個副本逐位元組一致,也無法證明目錄項目正確。FAT32 的 FSInfo 可用空間計數與下一個可用叢集提示也可能過時,因此讀取器必須將它們視為提示。

目錄項目與時間戳記 #

標準目錄槽為 32 位元組。短名稱項目包含 8.3 名稱、屬性旗標、時間戳記欄位、起始叢集與檔案大小。FAT32 將起始叢集分割為高位字與低位字。第一個位元組的特殊值表示未使用的槽或已刪除的項目,而目錄屬性則區分子目錄與一般檔案。

傳統 FAT 時間戳記編碼的是本地民用時間,而不是 UTC 時刻:

  • 修改時間的解析度為兩秒;
  • 修改日期與建立日期使用打包的年、月、日欄位;
  • 建立時間可以包含十分之一秒欄位;
  • 最後存取時間只儲存日期,不儲存當天時間。

時區與日光節約時間的解讀屬於實作範圍。因此,在不同系統之間複製磁碟區可能會改變顯示的時刻,而不改變磁碟上的位元。驗證時必須拒絕不可能的日期,而不能直接將打包值傳給行事曆 API。

VFAT 長檔名 #

VFAT 將長檔名(LFN)項目放在關聯短項目之前,以維持與 8.3 讀取器的相容性。LFN 槽:

  • 使用屬性值 0x0F,舊版 FAT 讀取器不會將其視為一般檔案;
  • 在不連續的欄位中儲存最多 13 個 UTF-16 程式碼單位;
  • 包含表示其位置以及是否為最後槽的序號;
  • 重複儲存由短 8.3 名稱導出的檢查碼。

槽在磁碟上按照序號反向排列,之後接著短項目。只有當序號、屬性與檢查碼一致時,讀取器才會重建名稱。否則,短名稱仍是安全的識別身分。UTF-16 程式碼單位可能包含代理對,而 FAT 禁止的字元與結尾空白規則仍是獨立的驗證問題。

開機磁區幾何資訊與分割區中繼資料 #

由於 FAT 隨 BIOS CHS 開機與分割磁碟演進,BPB 仍保留每磁軌磁區數、磁頭數、媒體描述元與隱藏磁區等欄位。現代系統透過 LBA 對磁碟區定址,因此幾何值可能是合成值。這些值描述的是開機時相容性,而不是實體碟片配置。

磁碟區開機磁區屬於 FAT,而位於磁碟區外部的 MBR 或 GPT 項目則負責定位它。分割區的起始位置與長度必須與根據 BPB 推導出的邊界一致,但一種結構不會取代另一種結構。UEFI 韌體在額外的 UEFI 要求下,會為 EFI System Partition 使用 FAT 檔案系統;沒有適當的分割區中繼資料與開機路徑,任意 FAT 磁碟區都不會成為 EFI System Partition。

作業上的影響 #

FAT 仍適合可移除媒體、韌體可見的磁碟區與受限裝置,因為獨立實作可以用少量機制解析它。應用程式仍應在移除媒體前刷新資料,讀取不受信任的映像時驗證所有位移與鏈結長度,並在嘗試修復前保留映像。沒有日誌便無法區分已完成的更新與斷電留下的中間狀態。

參考資料 #

評論

在 GitHub 上閱讀或評論(發表評論需要登入)