0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

FATFS文件系統(tǒng)詳解(二)

冬至子 ? 來源:jaffer ? 作者:jaffer ? 2023-06-07 14:44 ? 次閱讀

4.4 訪問FAT條目

FAT區(qū)由一條條FAT條目構(gòu)成,關(guān)于 FAT[N] 對應(yīng)的條目具體位置計算如下:

1.jpg

格外需要注意的是,不同格式,對應(yīng)的FAT條目的長度和格式不一樣:

此外對于FAT32格式,高4位是保留位,只有低28位有效!

具體如下圖所示:

1.jpg

4.5 文件與簇之間的關(guān)系

那么文件和簇之間的相互關(guān)系又是怎樣的呢?我們又是如何準確的找到存放在flash上的文件的呢?接下來讓我們看下文件與簇之間的關(guān)系映射。

在FAT卷上文件通過目錄管理,==目錄是一個32字節(jié)數(shù)組組成的目錄條目結(jié)構(gòu)==,此目錄結(jié)構(gòu)包含:文件名、文件大小、時間戳以及文件所在的第一個簇號。

簇號為0和1的簇被保留,由參數(shù)BPB_RootClus可知,有效簇從第2號簇開始。==FAT2對應(yīng)數(shù)據(jù)區(qū)的第一個簇==。

因此第N個簇的位置計算公式如下:

FirstSectorofCluster = DataStartSector + (N - 2) * BPB_SecPerClus

==每個條目所在的位置,對應(yīng)一個簇。當文件長度大于一個簇長度時,條目內(nèi)的值為下一個條目的索引,直到文件所在的最后一個簇,由此構(gòu)成簇鏈!文件所在的最有一個簇所對應(yīng)的FAT條目內(nèi)的值由一個特殊的值(EOC)組成,它永遠不會匹配任何有效的簇號==,如下:

FAT12: 0xFF8 - 0xFFF (typically 0xFFF)

FAT16: 0xFFF8 - 0xFFFF (typically 0xFFFF)

FAT32: 0x0FFFFFF8 - 0x0FFFFFFF (typically 0x0FFFFFFF)

存在一些特殊的值被用來做損壞簇的標記,如下:

FAT12: 0xFF7

FAT16:0xFFF7

FAT32:0xFFFFFFF7

不過此處需要注意,在FAT12/16系統(tǒng)上,上述特殊值絕不會和任何有效簇匹配,但是在FAT32上有可能,因此為了防止混淆,你在創(chuàng)建FAT32系統(tǒng)的時候應(yīng)該避免這種情況發(fā)生!因此FAT32系統(tǒng)上簇的上限為268435445(大于256M個簇)

FAT條目初始化的時候,F(xiàn)AT[2] 及以后的數(shù)據(jù)應(yīng)被初始化為0,指示未被使用處于空閑狀態(tài),如果值不為0,則意味著簇被損壞或被使用狀態(tài)。在FAT12/16系統(tǒng)上,空閑簇的數(shù)量未被記錄,而在FAT32系統(tǒng)上,F(xiàn)AT32支持FSInfo結(jié)構(gòu)體,里面記錄了空閑簇的數(shù)量。

==關(guān)于FAT[0]和FAT[1]:==

此兩個保留的條目,沒有與任何簇有聯(lián)系;不過具有其他意義,如下:

FAT12: FAT[0] = 0xF??; FAT[1] = 0xFFF;

FAT16: FAT[0] = 0xFF??; FAT[1] = 0xFFFF;

FAT32: FAT[0] = 0xFFFFFF??; FAT[1] = 0xFFFFFFFF;

FAT[0]中的?? 與 BPB_Media 相同;

FAT[1] 記錄了錯誤歷史記錄:卷臟標志(FAT16:bit15、FAT32:bit31),系統(tǒng)在啟動的時候清除此位,正常關(guān)閉的時候恢復(fù)。

如果此位已經(jīng)清除,表明上次未被正常關(guān)閉,可能存在邏輯卷錯誤;硬件錯誤標志(FAT16:bit14、FAT32:bit30)當出現(xiàn)無法恢復(fù)的讀寫錯誤時清除,表明需要進行全面檢查。

==關(guān)于FAT區(qū)域,有兩個重點注意事項:==

第一個是FAT的最后一個扇區(qū)可能沒有被完全使用。在大多數(shù)情況下,F(xiàn)AT在扇區(qū)的中間結(jié)束。FAT驅(qū)動程序不應(yīng)該對未使用的區(qū)域做出任何假設(shè)。在格式化卷時,應(yīng)該用零填充它,并且在此之后不應(yīng)更改它。

另一個是BPB_FATSz16/32可以指示比卷需要的值大的值。換句話說,未使用的扇區(qū)可以跟隨每個FAT。這可能是數(shù)據(jù)區(qū)域?qū)R或其他原因?qū)е碌?。同時,在格式化時這些扇區(qū)也會被用零填充。

下表展示了不同F(xiàn)AT類型中FAT值所對應(yīng)的含義解釋:

1.jpg

4.6 FSInfo扇區(qū)結(jié)構(gòu)及備份引導(dǎo)扇區(qū)

此部分內(nèi)容只在FAT32系統(tǒng)上存在,對于FAT12系統(tǒng)FAT區(qū)域大小最大6KB,對于FAT16系統(tǒng)FAT區(qū)域最大128KB,但是在FAT32系統(tǒng)上FAT區(qū)域通常上達數(shù)MB,這是因為FAT32系統(tǒng)支持FSInfo數(shù)據(jù)結(jié)構(gòu)。

在FAT32系統(tǒng)上新增FSInfo數(shù)據(jù)結(jié)構(gòu)的原因是:在FAT12/16系統(tǒng)上,想要知道flash上剩余的簇數(shù)需要掃描整個FAT區(qū)才能計算出來,但隨著flash容量的不斷擴大,掃描花費的時長越來越長,為了避免掃描浪費過多的時間,因此在FAT32系統(tǒng)上增加了FSInfo結(jié)構(gòu),用于記錄flash上剩余的簇數(shù)。

FSInfo數(shù)據(jù)結(jié)構(gòu)如下:

| 字段名 | 偏移 | 大小 | 描述 |

| — | — | — | — |

| FSI_LeadSig | 0 | 4 | 固定值為0x41615252,頭部簽名 |

| FSI_Reserved1 | 4 | 480 | 保留區(qū)域,采用0x00覆蓋 |

| FSI_StrucSig | 484 | 4 | 固定值為0x61417272,也是一個簽名 |

| FSI_Free_Count | 488 | 4 | 記錄了空閑的簇數(shù),如果這個值為0xFFFF FFFF,則表示不知道具體的空閑簇數(shù) |

| FSI_Nxt_Free | 492 | 4 | 提示驅(qū)動程序應(yīng)該從此參數(shù)提示的簇開始尋找空閑的簇,通過此參數(shù)便可以不用從FAT區(qū)頭開始尋找下一個空閑簇了,節(jié)省了大量時間;如果此參數(shù)為0xFFFF FFFF,則驅(qū)動程序應(yīng)該從頭部(2號簇)開始尋找空閑簇|

| FSI_Reserved2 |496 | 12 | 保留區(qū)域,采用0x00覆蓋 |

| FSI_TrailSig | 508 | 4 | 固定值0xAA550000,尾部簽名 |

注意:當扇區(qū)大小大于512字節(jié)時, 剩余空間采用0x00填充

4.7 FAT目錄

FAT目錄分為長文件名目錄(LFN)以及短文件名目錄(SFN),長文件目錄是在短文件名目錄上的一個擴展,具體采用長文件名還是短文件名由讀取FAT文件系統(tǒng)的操作系統(tǒng)決定,如windows;設(shè)置長文件名時短文件名也被設(shè)置,具有兼容性。

此外,有一個很重要的概念:在FAT文件系統(tǒng)上目錄也是一個文件,只是此文件的屬性不一樣而已。

在所有目錄中,有一個比較特殊的是根目錄,且根目錄作為頂層目錄必須存在。

在FAT12/16系統(tǒng)中,根目錄不是一個文件,且放在根目錄區(qū),根目錄的最大條目數(shù)由 BPB_RootEntCnt 參數(shù)指示;

在FAT32系統(tǒng)中,根目錄與子目錄沒有什么區(qū)別,且根目錄的起始簇由 BPB_RootClus 參數(shù)指示。

根目錄與子目錄的另外一個區(qū)別是,根目錄不包含 . .. 此兩個點目錄,且它可以包含卷標(具有ATTR_VOLUME_ID屬性的條目)

4.7.1 SFN 短文件名目錄

目錄條目結(jié)構(gòu)如下:

1.jpg

2.jpg

關(guān)于目錄結(jié)構(gòu)的第一個字段 DIR_Name 的第一個元素 DIR_Name[0] 在目錄表中有著特殊作用,如下:

當此值為 0xE5 時,代表此目錄條目未被使用(或已廢棄)

當此值為 0x00 時,也代表此目錄條目未被使用;此外還提示后續(xù)目錄條目也未被使用,因為后續(xù)的目錄條目 DIR_Name[0] 都會是 0x00

如果文件名的第一個字符為 0xE5 這個特殊值,則使用 0x05 替代。

這么設(shè)計的意義是什么呢?將 DIR_Name[0] 用作特殊字符,其目錄在于方便文件刪除!當我們刪除一個文件的時候,文件系統(tǒng)并不會將此文件所對應(yīng)的數(shù)據(jù)全部刪除,因為那樣太費時間了,也沒有必要,而是直接將對應(yīng)文件的目錄項中的 DIR_Name[0] 修改為 0xE5 即可!

關(guān)于文件名字段 DIR_Name,在FAT文件系統(tǒng)中還有如下規(guī)定:

DIR_Name 字段的11字節(jié)的文件名分為兩個部分:8 字節(jié)的主文件名 + 3字節(jié)的擴展名;

文件名中主文件名與擴展名中間的 . 被省略,不在此記錄

如果主文件名長度不夠,小于8字節(jié),則使用 0x20 空格填充

用于設(shè)置文件名的字符也有限制,支持的字符有 ==0~9 A~Z ! # $ % & ‘ ( ) - @ ^ _ ` { } ~==

主文件名和擴展名中的(a~z)ASCII字符都會被轉(zhuǎn)化成大寫字符保存

以下為文件名存儲示例:

1.jpg

4.7.2 LFN長文件名

長文件名是文件名的另外一種存儲方式,由于SFN短文件名具有長度、字符等限制,在一些場景下不能很好的滿足需求,因此就需要使用到長文件名,關(guān)于長文件名的具體內(nèi)容如下:

長文件名是一個具有特殊屬性的目錄條目。長文件名目錄屬性 DIR_Attr 字段的值 ATTR_LONG_NAME = (ATTR_READ_ONLY | ATTR_HIDDEN | ATTR_SYSTEM | ATTR_VOLUME_ID) = 0x0F;

1.jpg

關(guān)于長文件名的目錄屬性如下:

| 字段名 | 偏移 | 大小 | 描述 |

| — | — | — | — |

| LDIR_Ord | 0 | 1 | 序號(1-20),用來表示此條目屬于長文件名序列條目中的第幾條。且長文件名序列首條條目的值應(yīng)& 0x40以進行標識! |

| LDIR_Name1 | 1 | 10 | 長文件名 第1 ~ 第5 字符(注意此處一個字符占兩個字節(jié)) |

| LDIR_Attr | 11 | 1 | 長文件名屬性,此值永遠為 ATTR_LONG_NAME 0x0F

| LDIR_Type | 12 | 1 | 類型,必須為0 |

| LDIR_Chksum | 13 | 1 | 和校驗 |

| LDIR_Name2 | 14 | 12 | 長文件名 第6 ~ 第11 字符(注意此處一個字符占兩個字節(jié)) |

| LDIR_FstClusLO | 26 | 2 | 必須為0 |

| LDIR_Name3 | 28 | 4 | 長文件名 第12 ~ 第13 字符(注意此處一個字符占兩個字節(jié)) |

關(guān)于長文件名,有以下幾點重要概念:

一個文件一定有短文名SFN,但不一定有長文件名LFN

長文件名LFN字段中==僅包含文件名信息==,不包含其他內(nèi)容,其他內(nèi)容需要通過短文件名SFN查看

如果一個文件既有長文件名也有短文件名,則長文件名是其主要名字,而短文件名則為附加名字

==長文件名LFN條目在對應(yīng)的短文件名SFN條目前面==

一個文件的長文件名最長255字符,對應(yīng)最多20個長文件名LFN條目

長文件名簡單理解起始就是存儲一個字符串,因此沒有類似SFN的限制,允許有空格、支持大小寫、允許多個.符號等

LFN條目文件名長度不夠,仍然采用0x20填充

下圖是官方關(guān)于一個名為 “MultiMediaCard System Summary.pdf” 的長文件名在flash上的長文件名條目,如下所示,一眼沒看明白也沒關(guān)系,后文有實例說明,對長文件名有概念了就行!

1.jpg

關(guān)于長文件名的checksum字段和計算,算法如下:

uint8_t create_sum (const DIR* entry)

{

int i;

uint8_t sum;

for (i = sum = 0; i < 11; i++) { /* Calculate sum of DIR_Name[] field */

sum = (sum >> 1) + (sum << 7) + entry->DIR_Name[i];

}

return sum;

}

4.7.3 LFN系統(tǒng)對于SFN的兼容

在使用LFN長文件名的系統(tǒng)中,會自動生成SFN短文件名已確保此文件在短文件名的文件系統(tǒng)中可使用。同時為了防止生成的短文件名沖突,SFN的生成采用 名稱+數(shù)字后綴+擴展 的格式,同時采用以下規(guī)則生成SFN:

小寫自動轉(zhuǎn)大寫

如果存在空格,則刪去空格,設(shè)置有損轉(zhuǎn)換標識

已.開頭的文件刪除頭部的.,并設(shè)置有損轉(zhuǎn)換標識

存在多個.的文件名,僅保留最后一個作為文件名與擴展的分隔,并設(shè)置有損轉(zhuǎn)換標識

其他不支持的字符,采用_代替,并設(shè)置有損轉(zhuǎn)換標識

文件名如果是Unicode編碼,則轉(zhuǎn)化為ANSI/OEM編碼;不能轉(zhuǎn)換的字符采用_代替,并設(shè)置有損轉(zhuǎn)換標識

長度超過8字節(jié)的部分,截斷,并設(shè)置有損轉(zhuǎn)換標識

擴展名字段超過3字節(jié)的,截斷,并設(shè)置有損轉(zhuǎn)換標識

有損轉(zhuǎn)轉(zhuǎn)換標識為:~,ASCII值為0x7E,十進制126

示例如下:

1.jpg

至此,F(xiàn)AT文件系統(tǒng)的理論部分已經(jīng)描述完了,接下來我們繼續(xù)使用winhex對數(shù)據(jù)進行分析。

5.分區(qū)分析

繼續(xù)回顧我們一開始的這張布局圖

1.jpg

5.1 保留分區(qū)分析

保留分區(qū)為第一個分區(qū),其中引導(dǎo)扇區(qū)位于保留分區(qū)的第一個扇區(qū)。

根據(jù) 4.3 章節(jié)計算結(jié)果可知,保留分區(qū)起始地址為 0x00,大小 0xC00

保留分區(qū)數(shù)據(jù)如下,保留分區(qū)內(nèi)最重要的內(nèi)容即為引導(dǎo)扇區(qū),除引導(dǎo)扇區(qū)外,其他剩余空間全部保留,采用0x00覆蓋。關(guān)于引導(dǎo)扇區(qū)已在 4.2 章節(jié)詳細分析,此處不再做介紹。

1.jpg

5.2 FAT區(qū)分析

根據(jù) 4.3 章節(jié)描述,F(xiàn)AT區(qū)的起始地址為 ==0xC00==,大小為 ==0x3B400==,此外存在兩個FAT區(qū),F(xiàn)AT1和FAT2,起始地址分別為:==0xC00==、==0x1E600==,對應(yīng)地址數(shù)據(jù)如下:

FAT1 數(shù)據(jù):

1.jpg

FAT2 數(shù)據(jù)如下:

1.jpg

==由于此處采用FAT16格式,所以每個FAT條目占據(jù)兩個字節(jié)!==

根據(jù)上述數(shù)據(jù)進行分析:

確認 FAT2 為 FAT1 的備份;

存在5個FAT條目其中 FAT[0] 和 FAT[1] 為保留條目,F(xiàn)AT[0] 的內(nèi)容與 BPB_Media 媒體類型字段一致,F(xiàn)AT[1] 用來記錄錯誤歷史記錄 (詳見 4.5 章節(jié)描述)

==根據(jù)4.5章節(jié)描述,F(xiàn)AT2對應(yīng)數(shù)據(jù)區(qū)的第一個簇==,又FAT[2]、FAT[3]、FAT[4] 數(shù)據(jù)均為 0xFF,表明存在三個文件,且每個文件的大小小于等于一個簇的空間;且分別存放在數(shù)據(jù)區(qū)第1到第3個簇上!

此處可能大家會由疑問,剛剛格式化的sd卡為什么會存在文件內(nèi),其實這個是系統(tǒng)文件,格式化后自帶的,默認是隱藏的,只有使用winhex才能看到,也就是對應(yīng)的System Volume Information文件夾。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • FlaSh
    +關(guān)注

    關(guān)注

    10

    文章

    1610

    瀏覽量

    147574
  • OEM
    OEM
    +關(guān)注

    關(guān)注

    4

    文章

    400

    瀏覽量

    50192
  • ASCII
    +關(guān)注

    關(guān)注

    5

    文章

    171

    瀏覽量

    34997
  • FAT32
    +關(guān)注

    關(guān)注

    0

    文章

    32

    瀏覽量

    13727
  • SFN
    SFN
    +關(guān)注

    關(guān)注

    0

    文章

    5

    瀏覽量

    9018
收藏 人收藏

    評論

    相關(guān)推薦

    FATFS文件系統(tǒng)移植

    FatFs 是用于小型嵌入式系統(tǒng)的通用 FAT/exFAT 文件系統(tǒng)模塊。FatFs 模塊是按照 ANSI C (C89) 編寫的,與磁盤 I/O 層完全分離。因此它獨立于平臺。它可以
    的頭像 發(fā)表于 06-06 09:28 ?4406次閱讀
    <b class='flag-5'>FATFS</b><b class='flag-5'>文件系統(tǒng)</b>移植

    STM32CubeMx入門教程(10):Fatfs文件系統(tǒng)的應(yīng)用

    導(dǎo)語"fatfs是一個小型的文件系統(tǒng),在小型的嵌入式系統(tǒng)中使用非常的廣泛,STM32CubeMx自帶該文件系統(tǒng),我們通過簡單的配置就能夠使用,將前面的SD卡的讀寫操作進行修改,將
    發(fā)表于 07-12 11:39 ?4651次閱讀
    STM32CubeMx入門教程(10):<b class='flag-5'>Fatfs</b><b class='flag-5'>文件系統(tǒng)</b>的應(yīng)用

    FATFS文件系統(tǒng)移植

    這是本人,整理的FATFS文件系統(tǒng)移植資料,很少的一部分,希望大家把自己搜到的比較好的資料,分享一下,本人正在學(xué)習(xí)fatfs文件系統(tǒng),希望和高手討論,
    發(fā)表于 09-11 16:05

    FATFS文件系統(tǒng)簡介

    FATFS文件系統(tǒng)1.FATFS文件系統(tǒng)簡介2. 硬件設(shè)計3. 軟件設(shè)計3.1 STM32CubeMX設(shè)置3.2 MDK-ARM編程4. 下載驗證
    發(fā)表于 08-10 08:14

    FatFs文件系統(tǒng)的原理是什么?如何對FATFS進行移植?

    FatFs文件系統(tǒng)的原理是什么?FatFs文件系統(tǒng)的移植方法是什么?如何實現(xiàn)eMMC卡中文件的讀寫及其它操作?
    發(fā)表于 11-25 07:52

    stm32+sdio+fatfs文件系統(tǒng)_源碼分析

    stm32+sdio+fatfs文件系統(tǒng)介紹,通俗易懂。
    發(fā)表于 11-06 09:52 ?25次下載

    FatFs文件系統(tǒng)使用

    STM系列FatFs文件系統(tǒng)使用文件,希望對大家有幫助。
    發(fā)表于 11-06 18:10 ?8次下載

    基于SD卡的FATFS文件系統(tǒng)的研究與應(yīng)用_崔鵬偉

    基于SD卡的FATFS文件系統(tǒng)的研究與應(yīng)用_崔鵬偉。
    發(fā)表于 04-14 16:46 ?40次下載

    FatFs通用FAT文件系統(tǒng)模塊_中文手冊

    FatFs通用FAT文件系統(tǒng)_0.09A中文手冊,學(xué)習(xí)嵌入式的肯定要用到它。FatFs 是一個為小型嵌入式系統(tǒng)設(shè)計的通用FAT(File Allocation Table)
    發(fā)表于 07-13 15:40 ?92次下載

    CH579 SPIFLASH W25Q64 FATFS文件系統(tǒng)

    CH579 SPIFLASH W25Q64 FATFS文件系統(tǒng)(arm嵌入式開發(fā)平臺PB)-W25Qxx的SPIFlash掛載文件系統(tǒng),實現(xiàn)掛載fatfs
    發(fā)表于 08-04 11:44 ?78次下載
    CH579 SPIFLASH W25Q64 <b class='flag-5'>FATFS</b><b class='flag-5'>文件系統(tǒng)</b>

    Fatfs文件系統(tǒng)的移植)

    Fatfs文件系統(tǒng)的移植)一、文件系統(tǒng)介紹、移植條件、說明1、FatFs模塊在可移植性方面設(shè)定了以下條件:2、數(shù)據(jù)類型說明3、
    發(fā)表于 11-15 18:51 ?22次下載
    <b class='flag-5'>Fatfs</b>(<b class='flag-5'>文件系統(tǒng)</b>的移植)

    FATFS文件系統(tǒng)詳解

    采用的獨特的文件系統(tǒng)結(jié)構(gòu)CDFS:CDFS是大部分的光盤的文件系統(tǒng)exFATFATFS文件系統(tǒng)FATFS是一個完全免費開源的FAT 文件系統(tǒng)
    發(fā)表于 11-29 09:51 ?29次下載
    <b class='flag-5'>FATFS</b><b class='flag-5'>文件系統(tǒng)</b><b class='flag-5'>詳解</b>

    文件系統(tǒng)FatFs文件系統(tǒng)在嵌入式芯片LPC18XX上的移植

    文件系統(tǒng)FatFs文件系統(tǒng)在嵌入式芯片LPC18XX上的移植
    發(fā)表于 12-04 10:51 ?12次下載
    【<b class='flag-5'>文件系統(tǒng)</b>】<b class='flag-5'>FatFs</b><b class='flag-5'>文件系統(tǒng)</b>在嵌入式芯片LPC18XX上的移植

    FATFS文件系統(tǒng)原版文件下載

    FATFS文件系統(tǒng)原版文件下載
    發(fā)表于 06-25 09:02 ?0次下載

    文件系統(tǒng)FatFs的移植

    FATFS是一個完全免費開源的FAT文件系統(tǒng)模塊,專門為小型的嵌入式系統(tǒng)而設(shè)計。它完全用標準C語言編寫,所以具有良好的硬件平臺獨立性,甚至可以移植到8位的單片機上而只需做簡單的修改。
    的頭像 發(fā)表于 03-01 14:38 ?1785次閱讀
    <b class='flag-5'>文件系統(tǒng)</b><b class='flag-5'>FatFs</b>的移植