Linux flash 文件系統剖析【轉】

簡介: 您之前可能聽說過 Journaling Flash File System(JFFS)和 Yet Another Flash File System(YAFFS),但是您知道使用底層 flash 設備的文件系統意味着什麼嗎?本文將向您介紹 Linux 的 flash 文件系統,並探索它們如何通過平均讀寫(wear leveling)處理底層的可消耗設備(flash 部件),並鑑別各種不同的 flash 文件系統以及它們的基本設計。 

-----------------------------------------------------------------------------------------------------------------------------------------------

       固態驅動器當前非常流行,但是嵌入式系統很久以前就開始使用固態驅動器進行存儲。您可以看到 flash 系統被用於個人數字助理(PDA)、手機、MP3 播放器、數碼相機、USB flash 驅動(UFD),甚至筆記本電腦。很多情況下,商業設備的文件系統可以進行定製並且是專有的,但是它們會遇到以下挑戰。

       基於 Flash 的文件系統形式多種多樣。本文將探討幾種只讀文件系統,並回顧目前可用的各種讀/寫文件系統及其工作原理。但是,讓我們先看看 flash 設備及其所面對的挑戰。

-----------------------------------------------------------------------------------------------------------------------------------------------    

Flash 內存技術

Flash 內存(可以通過幾種不同的技術實現)是一種非揮發性內存,這意味着斷開電源之後其內容仍然保持下來。要了解 flash 內存的輝煌歷史,請參閱 參考資料

兩種最常見的 flash 設備類型爲:NOR 和 NAND。基於 NOR 的 flash 技術比較早,它支持較高的讀性能,但以降低容量爲代價。NAND flash 提供更大容量的同時實現快速的寫擦性能。NAND 還需要更復雜的輸入/輸出(I/O)接口。

Flash 部件通常分爲多個分區,允許同時進行多個操作(擦除某個分區的同時讀取另一個分區)。分區再劃分爲塊(通常大小爲 64KB 或 128KB)。使用分區的固件可以進一步對塊進行獨特的分段 — 例如,一個塊中有 512 字節的分段,但不包括元數據。

Flash 設備有一個常見的限制,即與其他存儲設備(如 RAM 磁盤)相比,它需要進行設備管理。flash 內存設備中惟一允許的 Write 操作是將 1 修改爲 0。如果需要撤銷操作,那麼必須擦除整個塊(將所有數據重置回狀態 1)。這意味着必須刪除該塊中的其他有效數據來實現持久化。NOR flash 內存通常一次可以編寫一個字節,而 NAND flash 內存必須編寫多個字節(通常爲 512 字節)。

這兩種內存類型在擦除塊方面有所不同。每種類型都需要一個特殊的 Erase 操作,該操作可以涵蓋 flash 內存中的一個整塊。NOR 技術需要通過一個準備步驟將所有值清零,然後再開始 Erase 操作。Erase 是針對 flash 設備的特殊操作,非常耗費時間。擦除操作與電有關,它將整個塊的所有單元中的電子放掉。

NOR flash 設備通常需要花費幾秒時間來執行 Erase 操作,而 NAND 設備只需要幾毫秒。flash 設備的一個關鍵特性是可執行的 Erase 操作的數量。在 NOR 設備中,flash 內存中的每個塊可被擦除 10萬次,而在 NAND flash 內存中可達到一百萬次。

-----------------------------------------------------------------------------------------------------------------------------------------------

Flash 內存面臨的挑戰

除了前面提到的一些限制以外,管理 flash 設備還面臨很多挑戰。三個最重大的挑戰分別是垃圾收集、管理壞塊和平均讀寫。

垃圾收集

垃圾收集 是一個回收無效塊的過程(無效塊中包含了一些無效數據)。回收過程包括將有效數據移動到新塊,然後擦除無效塊從而使它變爲可用。如果文件系統的可用空間較少,那麼通常將在後臺執行這一過程(或者根據需要執行)。

管理壞塊

用的時間長了,flash 設備就會出現壞塊,甚至在出廠時就會因出現壞塊而不能使用。如果 flash 操作(例如 Erase)失敗,或者 Write 操作無效(通過無效的錯誤校正代碼發現,Error Correction Code,ECC),那麼說明出現了壞塊。

識別出壞塊後,將在 flash 內部將這些壞塊標記到一個壞塊表中。具體操作取決於設備,但是可以通過一組獨立的預留塊來(不同於普通數據塊管理)實現。對壞塊進行處理的過程 — 不管是出廠時就有還是在使用過程中出現 — 稱爲壞塊管理。在某些情況下,可以通過一個內部微控制器在硬件中實現,因此對於上層文件系統是透明的。

平均讀寫

前面提到 flash 設備屬於耗損品:在變成壞塊以前,可以執行有限次數的反覆的 Erase 操作(因此必須由壞塊管理進行標記)。平均讀寫算法能夠最大化 flash 的壽命。平均讀寫有兩種形式:動態平均讀寫 靜態平均讀寫

動態平均讀寫解決了塊的 Erase 週期的次數限制。動態平均讀寫算法並不是隨機使用可用的塊,而是平均使用塊,因此,每個塊都獲得了相同的使用機會。靜態平均讀寫算法解決了一個更有趣的問題。除了最大化 Erase 週期的次數外,某些 flash 設備在兩個 Erase 週期之間還受到最大化 Read 週期的影響。這意味着如果數據在塊中存儲的時間太長並且被讀了很多次,數據會逐漸消耗直至丟失。靜態平均讀寫算法解決了這一問題,因爲它可以定期將數據移動到新塊。

-----------------------------------------------------------------------------------------------------------------------------------------------

系統架構

到目前爲止,我已經討論了 flash 設備及其面臨的基本挑戰。現在,讓我們看看這些設備如何組合成爲一個分層架構的一部分(參加圖 1)。架構的頂層是虛擬文件系統(VFS),它爲高級應用程序提供通用接口。VFS 下面是 flash 文件系統(將在下節介紹)。接下來是 Flash 轉換層(Flash Translation Layer,FTL),它整體管理 flash 設備包括從底層 flash 設備分配塊、地址轉換、動態平均讀寫和垃圾收集。在某些 flash 設備中,可以在硬件中實現一部分 FTL 。

\"Linux

 圖 1. flash 系統的基本架構

       Linux 內核使用內存技術設備(Memory Technology Device,MTD)接口,這是針對 flash 系統的通用接口。MTD 可以自動檢測 flash 設備總線的寬度以及實現總線寬度所需設備的數量。

-----------------------------------------------------------------------------------------------------------------------------------------------

       MTD(memory technology device內存技術設備)是用於訪問memory設備(ROM、flash)的Linux的子系統。MTD的主要目的是爲了使新的memory設備的驅動更加簡單,爲此它在硬件和上層之間提供了一個抽象的接口。MTD的所有源代碼在/drivers/mtd子目錄下。CFI接口的MTD設備分爲四層(從設備節點直到底層硬件驅動),這四層從上到下依次是:設備節點MTD設備層MTD原始設備層硬件驅動層

-----------------------------------------------------------------------------------------------------------------------------------------------

 Linux文件系統

Linux支持多種文件系統,包括ext2ext3vfatntfsiso9660jffsromfsnfs等,爲了對各類文件系統進行統一管理,Linux引入了虛擬文件系統VFS(Virtual File System),爲各類文件系統提供一個統一的操作界面和應用編程接口。

    Linux下的文件系統結構如下:

\"Linux

       Linux啓動時,第一個必須掛載的是根文件系統;若系統不能從指定設備上掛載根文件系統,則系統會出錯而退出啓動。之後可以自動或手動掛載其他的文件系統。因此,一個系統中可以同時存在不同的文件系統。

    不同的文件系統類型有不同的特點,因而根據存儲設備的硬件特性、系統需求等有不同的應用場合。在嵌入式Linux應用中,主要的存儲設備爲RAM(DRAM, SDRAM)ROM常採用FLASH存儲器,常用的基於存儲設備的文件系統類型包括:jffs2, yaffs, cramfs, romfs, ramdisk, ramfs/tmpfs等。

-----------------------------------------------------------------------------------------------------------------------------------------------

基於FLASH的文件系統Flash 文件系統

     Flash(閃存)作爲嵌入式系統的主要存儲媒介,有其自身的特性。Flash的寫入操作只能把對應位置的1修改爲0,而不能把0修改爲1(擦除Flash就是把對應存儲塊的內容恢復爲1),因此,一般情況下,向Flash寫入內容時,需要先擦除對應的存儲區間,這種擦除是以塊(block)爲單位進行的。

     閃存主要有NORNAND兩種技術(簡單比較見附錄)Flash存儲器的擦寫次數是有限的,NAND閃存還有特殊的硬件接口和讀寫時序。因此,必須針對Flash的硬件特性設計符合應用要求的文件系統;傳統的文件系統如ext2等,用作Flash的文件系統會有諸多弊端。

     在嵌入式Linux下,MTD(Memory Technology Device,存儲技術設備)爲底層硬件(閃存)和上層(文件系統)之間提供一個統一的抽象接口,即Flash的文件系統都是基於MTD驅動層的(參見上面的Linux下的文件系統結構圖)使用MTD驅動程序的主要優點在於,它是專門針對各種非易失性存儲器(以閃存爲主)而設計的因而它對Flash有更好的支持、管理和基於扇區的擦除、讀/寫操作接口

     順便一提,一塊Flash芯片可以被劃分爲多個分區,各分區可以採用不同的文件系統;兩塊Flash芯片也可以合併爲一個分區使用,採用一個文件系統。即文件系統是針對於存儲器分區而言的,而非存儲芯片。

       1、JFFS文件系統----- 日誌閃存文件系統(Journaling Flash File System )

Journaling Flash File System 是針對 Linux 的最早 flash 文件系統之一。 JFFS 是一種專門爲 NOR flash 設備設計的日誌結構文件系統。它非常獨特,能夠解決許多 flash 設備問題,但同時也導致一些新問題。

JFFS 將 flash 設備視爲一種循環的塊日誌。寫入 flash 的數據被寫到了空間的末尾,開始部分的塊則被收回,而兩者之間的空間是空閒的;當空間變少時,將執行垃圾收集。垃圾收集器將有效塊移動到日誌的尾部,跳過無效或廢棄塊,並擦除它們(參見圖 2)。因此這種文件系統可以自動實現靜態和動態平均讀寫。這種架構的主要缺點是過於頻繁地執行擦除操作(而沒有使用最佳擦除策略),從而使設備迅速磨損。
 

\"Linux

 掛載 JFFS 時結構細節將讀取到內存中,這將延緩掛載時間並消耗更多的內存。

  2、 JFFS2 文件系統-----日誌閃存文件系統版本2   (Journalling Flash FileSystem v2)

     JFFS文件系統最早是由瑞典Axis Communications公司基於Linux2.0的內核爲嵌入式系統開發的文件系統。JFFS2是RedHat公司基於JFFS開發的閃存文件系統,最初是針對RedHat公司的嵌入式產品eCos開發的嵌入式文件系統,所以JFFS2也可以用在Linux, uCLinux中。

     Jffs2: 主要用於NOR型閃存,基於MTD驅動層

                 特點是:可讀寫的、支持數據壓縮的、基於哈希表的日誌型文件系統,並提供了崩潰/掉電安全保護,提供“寫平衡”支持等。

                 缺點是:主要是當文件系統已滿或接近滿時,因爲垃圾收集的關係而使jffs2的運行速度大大放慢。

     目前jffs3正在開發中。關於jffs系列文件系統的使用詳細文檔,可參考MTD補丁包中mtd-jffs-HOWTO.txt。

     jffsx不適合用於NAND閃存主要是因爲NAND閃存的容量一般較大,這樣導致jffs爲維護日誌節點所佔用的內存空間迅速增大另外,jffsx文件系統在掛載時需要掃描整個FLASH的內容,以找出所有的日誌節點,建立文件結構,對於大容量的NAND閃存會耗費大量時間。

            儘管 JFFS 在早期非常有用,但是它的平均讀寫算法容易縮短 NOR flash 設備的壽命。因此重新設計了底層算法,去掉了循環日誌。JFFS2 算法專門爲 NAND flash 設備設計,並且改善壓縮性能。

            在 JFFS2 中,flash 中的每個塊都是單獨處理的。JFFS2 通過維護塊列表來充分地對設備執行平均讀寫。clean 列表表示設備中的塊全部爲有效節點。dirty 列表中的塊至少包含有一個廢棄節點。最後,free 列表包含曾經執行過擦除操作並且可以使用的塊。

            垃圾收集算法通過合理的方法智能地判斷應該回收的塊。目前,這個算法根據概率從 clean 或 dirty 列表中選擇。dirty 列表的選擇概率爲 99%(將有效內容移到另一個塊),而 clean 列表的選擇概率爲 1%(將內容移到新的塊)。在這兩種情況中,對選擇的塊執行擦除操作,然後將其置於 free 列表(參見圖 3)。這允許垃圾收集器重用廢棄的塊,但是仍然圍繞 flash 移動數據,以支持靜態平均讀寫。

\"Linux

 圖 3. JFFS2 中的塊管理和垃圾收集

3、yaffs- ---- Yet Another Flash File System

YAFFS 是針對 NAND flash 開發的另一種 flash 文件系統。最早的版本(YAFFS)支持 512 字節頁面的 flash 設備,但是較新的版本(YAFFS2)支持頁面更大的新設備以及更大的 Write 限制。 jffs2相比,它減少了一些功能(例如不支持數據壓縮),所以速度更快,掛載時間很短,對內存的佔用較小。另外,它還是跨平臺的文件系統,除了LinuxeCos,還支持WinCE, pSOSThreadX

大多數 flash 文件系統會對廢yaffs/yaffs2自帶NAND芯片的驅動,並且爲嵌入式系統提供了直接訪問文件系統的API,用戶可以不使用Linux中的MTDVFS,直接對文件系統操作。當然,yaffs也可與MTD驅動程序配合使用。

     yaffsyaffs2的主要區別在於前者僅支持小頁(512 Bytes) NAND閃存後者則可支持大頁(2KB) NAND閃存同時,yaffs2在內存空間佔用、垃圾回收速度、讀/寫速度等方面均有大幅提升。

大多數 flash 文件系統會對廢棄塊進行標記,但是 YAFFS2 使用單調遞增數字序列號額外地標記塊。在掛載期間掃描文件系統時,可以快速標識有效的 inode。YAFFS 保留在 RAM 中的樹以表示 flash 設備的塊結構,包括通過檢查點(checkpointing)實現快速掛載 — 這個過程將在正常卸載時將 RAM 樹結構保存到 flash 設備,以在掛載時快速讀取和恢復到 RAM(參見圖 4)。與其他 flash 文件系統相比,YAFFS2 的掛載時性能是它的最大優勢。

\"Linux

 圖 4. YAFFS2 中的塊管理和垃圾收集 

4、 只讀式壓縮文件系統Compressed ROM File System)

     (1)、Cramfs Compressed ROM File System )

     Cramfs是Linux的創始人 Linus Torvalds參與開發的一種只讀的壓縮文件系統。它也基於MTD驅動程序。

     在cramfs文件系統中,每一頁(4KB)被單獨壓縮,可以隨機頁訪問,其壓縮比高達2:1,爲嵌入式系統節省大量的Flash存儲空間,使系統可通過更低容量的FLASH存儲相同的文件,從而降低系統成本。

     Cramfs文件系統以壓縮方式存儲,在運行時解壓縮,所以不支持應用程序以XIP方式運行,所有的應用程序要求被拷到RAM裏去運行,但這並不代表比Ramfs需求的RAM空間要大一點,因爲Cramfs是採用分頁壓縮的方式存放檔案,在讀取檔案時,不會一下子就耗用過多的內存空間,只針對目前實際讀取的部分分配內存,尚沒有讀取的部分不分配內存空間,當我們讀取的檔案不在內存時,Cramfs文件系統自動計算壓縮後的資料所存的位置,再即時解壓縮到RAM中。    

 A、cramfs 的主要特點是:簡單和較高的空間利用率。這種文件系統用於內存佔用較小的嵌入式設計。

 B、另外,它的速度快,效率高,其只讀的特點有利於保護文件系統免受破壞,提高了系統的可靠性

 C、雖然 cramfs 元數據沒有經過壓縮,但是 cramfs 針對每個頁面使用 zlib 壓縮,從而允許隨機的頁面訪問(訪問時對頁面進行解壓縮)。

     由於以上特性,Cramfs在嵌入式系統中應用廣泛。

     但是它的只讀屬性同時又是它的一大缺陷,使得用戶無法對其內容對進擴充

     Cramfs映像通常是放在Flash中,但是也能放在別的文件系統裏,使用loopback 設備可以把它安裝別的文件系統裏。您可以通過 mkcramfs實用工具和 loopback 設備嘗試使用 cramfs。

 (2)、SquashFS

SquashFS 是另一種可用於 flash 設備的壓縮式 Linux 只讀文件系統。您可以在很多 Live CD Linux 發行版中找到 SquashFS。除了支持 zlib 壓縮外,SquashFS 還使用 Lembel-Ziv-Markov chain Algorithm (LZMA) 改善壓縮並提高速度。

和 cramfs 一樣,您可以通過 mksquashfs和 loopback 設備在標準 Linux 系統上使用 SquashFS。

5、 Romfs

     傳統型的Romfs文件系統是一種簡單的、緊湊的、只讀的文件系統,不支持動態擦寫保存,按順序存放數據,因而支持應用程序以XIP(eXecute In Place,片內運行)方式運行,在系統運行時,節省RAM空間。uClinux系統通常採用Romfs文件系統。

     其他文件系統:fat/fat32也可用於實際嵌入式系統的擴展存儲器(例如PDA, Smartphone, 數碼相機等的SD卡),這主要是爲了更好的與最流行的Windows桌面操作系統相兼容。ext2也可以作爲嵌入式Linux的文件系統,不過將它用於FLASH閃存會有諸多弊端。

-----------------------------------------------------------------------------------------------------------------------------------------------

 基於RAM的文件系統

(1) Ramdisk

     Ramdisk是將一部分固定大小的內存當作分區來使用。它並非一個實際的文件系統,而是一種將實際的文件系統裝入內存的機制,並且可以作爲根文件系統。將一些經常被訪問而又不會更改的文件(如只讀的根文件系統)通過Ramdisk放在內存中,可以明顯地提高系統的性能。

     Linux的啓動階段,initrd提供了一套機制,可以將內核映像和根文件系統一起載入內存。


     (2)ramfs/tmpfs

     RamfsLinus Torvalds開發的一種基於內存的文件系統,工作於虛擬文件系統(VFS)層,不能格式化,可以創建多個,在創建時可以指定其最大能使用的內存大小。(實際上,VFS本質上可看成一種內存文件系統,它統一了文件在內核中的表示方式,並對磁盤文件系統進行緩衝。)

     Ramfs/tmpfs文件系統把所有的文件都放在RAM中,所以讀/寫操作發生在RAM中,可以用ramfs/tmpfs來存儲一些臨時性或經常要修改的數據,例如/tmp/var目錄,這樣既避免了對Flash存儲器的讀寫損耗,也提高了數據讀寫速度。

     Ramfs/tmpfs相對於傳統的Ramdisk的不同之處主要在於:不能格式化,文件系統大小可隨所含文件內容大小變化。

     Tmpfs的一個缺點是當系統重新引導時會丟失所有數據。

-----------------------------------------------------------------------------------------------------------------------------------------------

網絡文件系統NFS (Network File System)

     NFS是由Sun開發並發展起來的一項在不同機器、不同操作系統之間通過網絡共享文件的技術。在嵌入式Linux系統的開發調試階段,可以利用該技術在主機上建立基於NFS的根文件系統,掛載到嵌入式設備,可以很方便地修改根文件系統的內容。


     以上討論的都是基於存儲設備的文件系統(memory-based file system),它們都可用作Linux的根文件系統。實際上,Linux還支持邏輯的或僞文件系統(logical or pseudo file system),例如procfs(proc文件系統),用於獲取系統信息,以及devfs(設備文件系統)sysfs,用於維護設備文件。

-----------------------------------------------------------------------------------------------------------------------------------------------

附錄:NOR閃存與NAND閃存比較

NOR FLASH

NAND FLASH

接口時序同SRAM,易使用

地址/數據線複用,數據位較窄

讀取速度較快

讀取速度較慢

擦除速度慢,以64-128KB的塊爲單位

擦除速度快,以832KB的塊爲單位

寫入速度慢(因爲一般要先擦除)

寫入速度快

隨機存取速度較快,支持XIP(eXecute In Place,芯片內執行),適用於代碼存儲。在嵌入式系統中,常用於存放引導程序、根文件系統等。

順序讀取速度較快,隨機存取速度慢,適用於數據存儲(如大容量的多媒體應用)。在嵌入式系統中,常用於存放用戶文件系統等。

單片容量較小,132MB

單片容量較大,8128MB,提高了單元密度

最大擦寫次數10萬次

最大擦寫次數100萬-1000萬次

參考文件來源:http://www.ibm.com/developerworks/cn/linux/l-flash-filesystems/

參考文件來源:http://www.cnitblog.com/zouzheng/archive/2008/02/29/40307.html

 

發佈了92 篇原創文章 · 獲贊 4 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章