王 江
(上海貝爾股份有限公司N&P,上海201206)
支持閃存的文件系統多種多樣,常見的有JFFS、YAFFS、TrueFFS等,它們各有所長,但卻都不適合管理系統啟動時的配置文件和軟件。為此,筆者開發了一款可靠高效的文件系統——EFFS(Efficient Flash File System,高效閃存文件系統)。
因為這款文件系統的首要服務對象是系統啟動,系統啟動要求快速而穩定,所以它的文件系統必須具有以下特點:
①快速。啟動速度快無疑會給用戶留下美好的印象,所以初始化文件系統、搜索和讀取文件應該盡可能快速。
②可靠。可靠性體現在三個方面。首先,目錄和文件的完整性——通過校驗碼來保證;其次,文件的冗余性,如果一個文件被破壞或者加載失敗,自動后退加載同一功能的另一個文件,不影響系統的啟動;最后,記錄文件和目錄的信息表有備份,破壞后能夠自動恢復。
這是一款以扇區為基礎的文件系統,層次結構如圖1[1]所示,閃存驅動層屏蔽了閃存芯片的具體信息,例如閃存種類、緩存大小、分區大小。因為文件系統必須支持各種類型的閃存,所以該層的一個重要特性是可以識別多種閃存芯片。扇區管理層負責物理扇區和邏輯扇區的映射,實現壞塊管理和磨損均衡。API層提供了豐富的接口給外部應用,可使文件系統內部改變,而不致影響外部應用接口。OS(操作系統)在啟動階段時指啟動程序,例如BIOS、Bootloader,啟動完成后指應用所依賴的Linux、WinCE等操作系統。

圖1 文件系統層次結構
整個文件系統的架構如圖2(a)所示,共分為5個區域:3個目錄(目錄0~目錄2)、2個文件系統信息表。這2個文件系統信息表互為備份,默認使用信息表0。如果信息表0損壞,則使用信息表1,同時把信息表1的數據復制到信息表0,即修復信息表0。每個文件信息表占用閃存的若干個扇區。其存放位置由用戶自定義,一般位于閃存的末尾。
每個目錄由目錄信息表、文件和空閑區域組成。目錄信息表中存放了目錄和文件的屬性,其組織格式如表1所列。信息表的頭部是目錄屬性,定義了目錄名稱、版本、創建日期、長度、空余空間、校驗和等,緊接著目錄屬性,是每個文件的屬性。目錄中有幾個文件,就有幾個文件屬性的表項。
文件屬性定義了文件名稱、版本、校驗和、在目錄中的偏移地址、長度等。因為有些文件可以執行,例如故障診斷軟件和操作系統,所以文件屬性中包含了一項入口地址,對于不可執行文件,這一項設置為0。為了節省閃存空間,目前文件系統支持兩種壓縮格式:gzip和bz2,即文件可以壓縮后存放在閃存中,同時在“文件壓縮類型”記錄對應的壓縮格式。當文件被讀取時,根據“文件壓縮類型”選擇適合的解壓縮算法。

圖2 文件系統架構

表1 目錄信息表格式
物理上的3個目錄在邏輯上分別被定義為當前(C)、先前(P)和原始(O)3個目錄。目錄0在硬件上設置為寫保護,所以原始目錄一般指向目錄0,該目錄中在出廠時存放一個最保險的、能夠讓系統穩定運行的軟件版本。該設計可以使得其他2個目錄都損壞時,系統仍然有一個基本的能正常啟動的軟件備份。當前目錄指向目錄2還是目錄1、先前目錄指向目錄2還是目錄1允許用戶自定義。對于每種類型的文件,在文件系統信息表中均有選擇開關,指示下次啟動加載哪個目錄中的文件。所以文件系統信息表的組織如表2所列,主要定義了3個目錄在閃存中的地址、物理目錄和邏輯目錄的對應關系、各個文件選擇的目錄和實際加載成功的目錄等。

表2 文件系統信息表格式
當文件系統被加載,即文件系統初始化時,程序將首先檢查文件系統信息表的完整性,然后根據信息表,檢查各個目錄的完整性,這些檢查結果都會記錄在內存的一個數據結構中。如果今后文件系統沒有改變,就可以直接使用內存中的數據,無需再次檢查,提高了系統性能。
接著,啟動程序會根據文件系統信息表中的設置將文件加載到相應的器件中。文件是根據邏輯目錄來進行選擇的。如果文件選擇的目錄為當前目錄,則先在當前目錄中查找該文件,如果文件不存在、損壞或者加載失敗,則從先前目錄中查找。如果先前目錄中的文件也不存在、損壞或加載失敗,則從原始目錄加載,原始目錄中的文件肯定是存在的,因為它們是寫保護并且在出廠時就燒錄好的。
如果文件選擇的目錄為先前目錄,則從先前目錄中查找,如果文件不存在、損壞或者加載失敗,則加載原始目錄中的文件。如果文件選擇的目錄為原始目錄,則直接從原始目錄中查找和加載。文件的選擇如圖3所示。所以在使用時,一般將待測的最新版本的軟件存放在當前目錄,而將測試通過的軟件存放在先前目錄,而文件選擇開關通常設置為當前目錄,這樣可以充分利用3個目錄逐級備份的冗余特性,提高系統的可靠性。

圖3 文件的選擇
每個文件加載成功后,系統將在文件系統信息表中記錄加載成功的目錄,用戶可以根據這個信息,結合“文件選擇目錄”信息,判斷出所選擇文件是否運行成功。
啟動程序將配置文件加載到NPU、DSP、FPGA等器件之后,最后的使命是根據文件系統信息表中“操作系統文件”選項加載軟件,該軟件可以是故障診斷程序、Linux或VxWorks等操作系統。這個特征允許同一硬件平臺支持安裝和運行不同的操作系統。
與文件系統密切配合的是簡潔實用的用戶命令,詳見表3,它們方便了用戶查看、增減目錄和文件,選擇啟動軟件等。

表3 文件系統命令列表
命令主要分為三類:一是與目錄操作相關的,包括查看目錄屬性、創建目錄、刪除目錄、升級目錄和目錄碎片整理;二是與文件操作相關的,包括查看文件屬性、新增文件、刪除文件、升級文件;三是其他操作命令,包括設置系統運行的軟件、指定文件首選的目錄、建立邏輯目錄和物理目錄之間的關系,例如選擇哪個目錄為當前目錄,哪個目錄為先前目錄。
其中新增文件命令較為復雜。如果有壓縮要求,它首先對文件進行壓縮,然后根據壓縮后的文件大小在目錄中搜尋空余空間,如果沒有找到,則調用目錄碎片整理程序整理碎片,將分散的不連續小尺寸的碎片組合成連續的大尺寸空間,整理完成后再次搜尋。找到空間后調用閃存驅動將文件寫入,接著計算校驗和,更新目錄信息表中的文件數目,同時寫入文件偏移地址、長度和其他文件屬性。值得注意的是,在多內核或多任務操作系統中,目錄空余空間的搜尋代碼需要用互斥鎖保護起來,否則當一個任務正在搜尋空余空間時,被中斷或被另一個優先級更高的任務所搶占,后者恰巧也調用了搜尋空余空間的函數,則可能導致兩個任務都得到了相同地址的空余空間,導致操作失敗或者目錄損壞。其他需要互斥鎖保護的還有目錄中文件數目選項的更新等。
當多次在同一目錄中執行增加和刪除文件操作后,目錄中可能出現不連續的空余空間,即碎片,系統將碎片整理程序作為一個低優先級的任務或線程在后臺運行,一旦處理器有空閑,則對目錄碎片進行整理,有效提高了下一次寫入文件操作的速度。
JFFS/JFFS2和YAFFS/YAFFS2是業界應用較廣的閃存文件系統,針對系統啟動,加載智能芯片的配置文件方面的應用,與EFFS相比稍遜一籌。表4列舉了3種閃存文件系統在幾個關鍵指標上的對比。

表4 文件系統性能比較
由表可見,在閃存類型方面,JFFS2[2]和YAFFS2[3]各有偏愛,而EFFS都能適用。在文件系統的加載速度上,EFFS處于微秒級水平,且于閃存容量無關,遠快于其他2種文件系統,后者比較慢且與閃存容量成正比。在可靠性方面,EFFS能夠在加載一個文件失敗后,自動尋找并加載同類型的文件,JFFS2和YAFFS2卻無能為力。
本文提出了一種適合系統啟動閃存使用的文件系統。這種文件系統不僅加載速度快,而且可靠性高,易于移植和擴展。經過測試,其性能并且占用內存少,完全能夠幫助用戶實現對智能芯片文件的高效管理并滿足系統的啟動要求。
[1] Numonyx Inc.閃存文件系統概況,2008.
[2] IBM Inc.JFFS2文件系統及新特性介紹,2005.
[3] How Yaffs works[OL] .(2012-06)[2013-06] .http://www.yaffs.net/documents/how-yaffs-works.