0 引言
在VxWorks的應(yīng)用系統(tǒng)中,,基于flash的文件系統(tǒng)通常都采用DOS+FAT+FTL的結(jié)構(gòu)。
一般情況下,,磁盤文件系統(tǒng)大多是基于sector的文件系統(tǒng),,磁盤按照物理上分為柱面、磁盤,、扇區(qū),,扇區(qū)是基于塊的文件系統(tǒng)操作的基本存儲(chǔ)單位,磁盤的容量都是根據(jù)這些數(shù)據(jù)計(jì)算出來的,,每個(gè)扇區(qū)大小通常都是512bytes,。
VxWorks文件系統(tǒng)中的DOSFS是MS-DOS兼容的文件系統(tǒng),可基于塊對(duì)物理介質(zhì)進(jìn)行操作,。由于Fish的物理特性,,對(duì)Flash作基于塊(不同于Flash的擦除塊)的操作必須由軟件作封裝實(shí)現(xiàn),這就是TFFS所起的作用,。
1 VxWorks文件系統(tǒng)的總體結(jié)構(gòu)
VxWorks文件系統(tǒng)的總體結(jié)構(gòu)以及TFFS在整個(gè)文件系統(tǒng)的位置如圖l所示,。
Tomado下的TFFS文件系統(tǒng)是Tornado的一個(gè)可選組件,它可為種類繁多的Flash設(shè)備提供一個(gè)統(tǒng)一的塊設(shè)備接口,。在Tornado2.2版本中自帶的TFFS版本為2.0,,在文件系統(tǒng)中,TFFS的功能相當(dāng)于磁盤驅(qū)動(dòng),,通過TFFS可使上層的DOSFS或RTll文件系統(tǒng)像操作普通的標(biāo)準(zhǔn)磁盤一樣來操作Flash,。
2 TFFS文件系統(tǒng)的分層
圖2所示為TFFS文件系統(tǒng)的分層圖。圖中的Core Layer內(nèi)核層可將其他層連接起來協(xié)同工作,;翻譯層主要實(shí)現(xiàn)DOS和TFFS之間的交互,、管理文件系統(tǒng)和Flash各個(gè)物理塊的關(guān)系,同時(shí)支持TFFS的各種功能,,如磨損均衡,、錯(cuò)誤恢復(fù)等;MTD層執(zhí)行底層的程序驅(qū)動(dòng)(map,、read,、write、erase等),;socket層的名稱來源于可以插拔的socket存儲(chǔ)卡,,主要提供與具體的硬件板相關(guān)的驅(qū)動(dòng)。
3 FTL層分析
FTL是TFFS文件系統(tǒng)的核心,它是PCMCIS的一項(xiàng)標(biāo)準(zhǔn),,意思是Flash Translation Laycr Specification,,這種類型的文件系統(tǒng)是目前嵌入式系統(tǒng)中最流行的,很多公司都提供這種文件系統(tǒng)的相關(guān)解決方案,。
PTL為DOS BPB/FAT與Flash之間的中間層,,F(xiàn)TL利用現(xiàn)成的基于塊的文件系統(tǒng)(例如DOSFS)來實(shí)現(xiàn)應(yīng)用層的操作,實(shí)質(zhì)上就是在Flash設(shè)備上模擬磁盤塊設(shè)備的實(shí)現(xiàn),,為基于塊的文件系統(tǒng)提供統(tǒng)一的接口,。FTL通過以下幾步來模擬磁盤驅(qū)動(dòng):首先是在Flash擦除塊之外定義小的讀寫塊(相當(dāng)于磁盤扇區(qū));其次是邏輯扇區(qū)(對(duì)塊文件系統(tǒng)如DOSFS呈現(xiàn)的地址)和物理地址(Flash的實(shí)際地址)之間的轉(zhuǎn)換,;然后管理Flash,,使得能在空閑的地方寫入數(shù)據(jù)。其核心就是將DOS上的扇區(qū)映射到Flash上去,。
為了實(shí)現(xiàn)DOS層從邏輯上看扇區(qū)是連續(xù)的,,可隨時(shí)對(duì)任意bit讀寫操作,F(xiàn)TL必須提供對(duì)Flash芯片的管理,,包括向上層(DOS層)提供可以任意讀寫的操作接口,,向下對(duì)Flash的擦除、寫入,、讀取統(tǒng)一管理,,同時(shí)還必須提供磨損均衡,以防止一個(gè)擦除塊提前損壞,。
3.1 FTL的啟動(dòng)過程分析
在我們調(diào)用函數(shù)tffsDevCreate創(chuàng)建TFFS文件系統(tǒng)時(shí),,會(huì)以參數(shù)FL_MOUNT_VOLUME調(diào)用函數(shù)flcall→mountvolume→flmount→mountFTL,函數(shù)mountFTL是FTL層的加載函數(shù)人口,,處理過程首先是初始化FTL,,然后就可按下列步驟進(jìn)行:
(1)查找第一個(gè)合法的unit頭信息
合法性的判斷依據(jù)是unit header頭上的標(biāo)志CISF..FTL100和部分頭部的flag信息,由于bsp已把FS的相關(guān)信息注冊(cè)到FTL的數(shù)據(jù)結(jié)構(gòu)中,,所以,,F(xiàn)TL層可以找到第一塊unit,并可以向后查,,直到找到合法的unit為止,。
(2)檢驗(yàn)信息合法性
將所有有用的信息都讀出到內(nèi)部數(shù)據(jù)結(jié)構(gòu)中后,即可檢驗(yàn)信息合法性,。由于unit header中的Unit ID和擦除次數(shù)都相同,,所以整個(gè)文件系統(tǒng)的共用信息都可以從首先找到的頭中讀出來。
(3)給Mount每一個(gè)unit建立page表
這是mount最重要的過程,,對(duì)每個(gè)unit調(diào)用mountunit()函數(shù),,并在mountunit()函數(shù)中首先判斷,,如果是非法unit,則作為交換unit,,然后對(duì)每個(gè)BAM選項(xiàng)進(jìn)行處理,,并對(duì)垃圾BAM、空閑BAM進(jìn)行統(tǒng)計(jì),,如果是緩沖的BAM數(shù)據(jù)和交換page的VBM,,則將此page的邏輯扇區(qū)信息記錄到內(nèi)存的page表中,以便后續(xù)映射訪問查詢使用,,而對(duì)于非緩沖的BAM數(shù)據(jù),,則不作處理,另外,,對(duì)于交換page的VBM,則進(jìn)行記錄,??紤]到上述過程,可見其系統(tǒng)中的page VBM和緩沖的數(shù)據(jù)BAM分布在各個(gè)unit的各個(gè)角落,,需要將所有的VBM和緩沖數(shù)據(jù)BAM收集起來建立整個(gè)交換page表,,這是FTL標(biāo)準(zhǔn)層設(shè)計(jì)時(shí)就要決定的。
(4)檢驗(yàn)邏輯unit的完整性
當(dāng)所有的unit都mount完成后,,每個(gè)邏輯unit都應(yīng)存在,,否則mount失敗。
(5)判斷并關(guān)閉交換page
如果系統(tǒng)中已存在交換page,,則對(duì)系統(tǒng)中存在的交換page進(jìn)行關(guān)閉操作,,以便后面檢查page的完整性。
(6)檢查page的完整性
系統(tǒng)中的page表必須是完整的,,這個(gè)表中包含有緩沖的數(shù)據(jù)BAM映射信息和更重要的page映射信息,,因此,缺少任何一個(gè),,都將導(dǎo)致DOS的虛擬扇區(qū)無法映射到相應(yīng)的邏輯扇區(qū),。
從上述過程可見,整個(gè)mount過程是將文件系統(tǒng)信息讀入內(nèi)存數(shù)據(jù)結(jié)構(gòu)并檢驗(yàn)的過程,,這個(gè)Mount PTL過程完成后,,mountvolume ()函數(shù)即將隱蔽的0扇區(qū)和DOS的啟動(dòng)扇區(qū)信息讀入內(nèi)存數(shù)據(jù)結(jié)構(gòu),這樣,,DOS就可以訪問FTL底層扇區(qū)了,。
3.2 TFFS的塊映射
圖3中,F(xiàn)TL層將DOS上連續(xù)的扇區(qū)映射到Flash上某個(gè)R/W block塊中,,同時(shí)在某個(gè)位置記錄一個(gè)映射表(稱為MAP表),,該表中記錄了DOS的扇區(qū)映射到Flash中的哪個(gè)block,,當(dāng)DOS要進(jìn)行讀操作時(shí),F(xiàn)TL首先查詢這個(gè)MAP,,以獲得映射信息,,然后讀取相應(yīng)的block信息并返回給DOS,從而實(shí)現(xiàn)讀映射,。當(dāng)DOS需要寫入操作時(shí),,可能存在將bit0修改為1的情況,于是FTL層將申請(qǐng)一個(gè)新的block塊,,并將新信息寫入,,然后修改map信息,記錄這個(gè)DOS扇區(qū)已經(jīng)重新映射了,,從而實(shí)現(xiàn)寫映射,。所以,從邏輯上看,,F(xiàn)TL層就實(shí)現(xiàn)了DOS扇區(qū)的映射和FLASH的寫入管理,。
3.3 垃圾收集過程
FTL格式化后,可用扇區(qū)將被不斷申請(qǐng)使用,,原有扇區(qū)被不斷的廢棄,,系統(tǒng)中可用的free扇區(qū)越來越少,但這并不是由于上層DOS真的使用了這么多扇區(qū),,而是FTL為了方便管理,、為了不需要每次擦除一塊而付出的管理代價(jià)。所以,,當(dāng)系統(tǒng)中的可用扇區(qū)少于用戶要申請(qǐng)寫入的扇區(qū)時(shí),,F(xiàn)TL層就必須解決這些垃圾問題,這個(gè)過程在FTL中稱為垃圾回收(garbage collect),。
當(dāng)FTL中的可用sector小于用戶要申請(qǐng)的扇區(qū)時(shí),,系統(tǒng)將啟動(dòng)垃圾收集,但系統(tǒng)中有很多個(gè)unit,,到底收集哪個(gè)unit呢?FTL會(huì)考慮磨損均衡,,它將采用一個(gè)偽隨機(jī)的算法來決定收集策略:即用4/256的幾率選擇磨損情況少的塊來收集;252/256的幾率則根據(jù)垃圾最多為第一條件,,當(dāng)垃圾一樣時(shí),,判斷磨損次數(shù)小的優(yōu)先選擇。
3.4 FFL創(chuàng)建的DOS
TFFS的格式化函數(shù)需要調(diào)用tffsDevFormat來格式化,,而不需要調(diào)用dosFsVolFormat來格式化,;另外,在tffsDevFormat格式化參數(shù)中,,需要傳人的參數(shù)含有FAT個(gè)數(shù)參數(shù),,其原因是DOS是FTL層創(chuàng)建的,,而不是在FTL基礎(chǔ)上創(chuàng)建的,下面是TFFS的整個(gè)格式化過程:
tffsDevFormat→flcall(FL_FORMAT_VOLUME)→formatVolume→Format→formatFTL,;
其中,,函數(shù)formatFTL是執(zhí)行FTL層格式化的操作函數(shù),操作時(shí),,首先根據(jù)格式化參數(shù)和BSP參數(shù)對(duì)內(nèi)部數(shù)據(jù)結(jié)構(gòu)初始化,;然后再對(duì)每個(gè)unit進(jìn)行格式化,在擦除后,,即可寫入unitheader信息和控制BAM值,;之后寫入unit No;最后申請(qǐng)每個(gè)page的空間,;
上述formatFTL函數(shù)執(zhí)行完以后,,F(xiàn)TL就已經(jīng)準(zhǔn)備好,可以接受上層的扇區(qū)讀寫函數(shù)了(當(dāng)然還沒有內(nèi)容可以讀寫),。
在函數(shù)formatVolume中,,mount可進(jìn)行卷操作,當(dāng)內(nèi)存的數(shù)據(jù)結(jié)構(gòu)準(zhǔn)備好后,,F(xiàn)TL層即可調(diào)用函數(shù)flDosFormat來創(chuàng)建DOS。其中首先創(chuàng)建隱藏扇區(qū),,以用于記錄該卷的部分信息,,然后分別創(chuàng)建MBR、FAT和ROOT目錄,;這樣,,DOS創(chuàng)建完成后,再執(zhí)行dosFsDevCreat函數(shù),,當(dāng)然就無須格式化,,找到0扇區(qū)自然就找到了MBR,因?yàn)镈OS是FTL創(chuàng)建的,。
從更深層次講,,F(xiàn)TL層之所以創(chuàng)建DOS層,是因?yàn)橹挥蠪TL層才知道有哪些扇區(qū)是可以供DOS使用的,,哪些扇區(qū)是DOS不能使用的(作為FTL層管理使用),,也正是因?yàn)镈OS層不了解FTL層的運(yùn)作情況,所有的扇區(qū)映射關(guān)系都被FTL層隱蔽,,因而導(dǎo)致DOS層無法在上層作出有利于Flash擦寫等優(yōu)化動(dòng)作,,如大文件寫入時(shí)的字節(jié)數(shù)更新,F(xiàn)AT表更新等操作,,都會(huì)嚴(yán)重浪費(fèi)FTL層的映射關(guān)系運(yùn)算,。
4 基于M25P32 SPI Flash的TFFS設(shè)計(jì)
對(duì)于TFFS的實(shí)現(xiàn),,涉及到config.h、sysTffs.c,、tffsConifg.c,、tffsMtd.c、Makefile幾個(gè)文件的配置和修改,,其中編譯是通過建立一個(gè)downloadalbe的tomado工程,,來把這幾個(gè).c源文件編譯進(jìn)去生成.pl文件提供給bsp工程,而后由bsp工程把.pl文件編譯進(jìn)去,,從而生成bootable image,。
4.1 Config.h的相關(guān)配置
要在vxworks映像中加入TFFS文件系統(tǒng),需要加入相關(guān)的組件,,雖然也可以在該文件中直接加入相應(yīng)的配置宏,,但很容易造成遺漏和有些需要依賴的宏沒有定義或者沖突,本文采用的方法是建一個(gè)bootable的tornado工程,,而后在這個(gè)工程中通過加入TFFS和DOSFS的相關(guān)組件來編譯這個(gè)工程,,從而生成一個(gè)prjParams.h文件,該文件里就包含了剛剛加入的組件對(duì)應(yīng)的宏,,因而,,組件與組件之間依賴也是安全的,不會(huì)有任何沖突,,最后再在Config.h中包含這個(gè)文件即可,。
4.2 sysTffs.c文件的修改
該文件用于提供socket層的bsp實(shí)現(xiàn)代碼。如果鏡像文件包含TFFS相關(guān)組件,,那么,,系統(tǒng)啟動(dòng)時(shí)就會(huì)按照如下過程自動(dòng)調(diào)用sysTffsInit()函數(shù):
usrRoot()→tffsDrv()→flInit()→flRegisterComponent ()→sysTffslnit ()
sysTffsInit ()函數(shù)會(huì)依次調(diào)用socket注冊(cè)函數(shù)simmRegisterOfsl (),注冊(cè)函數(shù)數(shù)量視需要構(gòu)建的文件系統(tǒng)數(shù)量而定,,本文構(gòu)建了1個(gè)文件系統(tǒng)ofsl,,并在simmRegisterOfsl()函數(shù)中對(duì)文件系統(tǒng)的基地址進(jìn)行了設(shè)置,同時(shí)對(duì)FLSocket()結(jié)構(gòu)體中的毀掉處理函數(shù)進(jìn)行了掛接,,掛接函數(shù)也在該文件中實(shí)現(xiàn),,如卡上電、斷電,、寫保護(hù)等,。
對(duì)sysTffsFormaOfsl()函數(shù)的格式化參數(shù)可根據(jù)自己的需要進(jìn)行修改。
4.3 tffsConfig.c和tffSMtd.c文件的修改
tffsConfig.c文件的修改就是在mtdTalbe []表中注冊(cè)Flash識(shí)別函數(shù)iUnifiedIdentifyOfsl(),;而tffsConfig.c文件則用于實(shí)現(xiàn)iUnifiedldentifyOfsl()函數(shù),,iUnifiedIdentifyOfsl()函數(shù)對(duì)FLFlash結(jié)構(gòu)體中的回調(diào)函數(shù)進(jìn)行了掛接,如flash的讀,、寫,、擦除等,,掛接函數(shù)的具體實(shí)現(xiàn)可在Dry_MvSFlash.cpp文件中以一個(gè)類的方式提供針對(duì)M25P32 spi Flash操作的所有驅(qū)動(dòng)接口。
4.4 TFFS文件系統(tǒng)的安裝
通過上面的過程,,socket層和mtd層就都準(zhǔn)備好了,,下面便可以安裝tffs文件系統(tǒng)。安裝時(shí),,首先用sysTffsFormatOfsl()函數(shù)按照上面設(shè)定的參數(shù)格式化TFFS文件系統(tǒng),,而后通過usrTffsConfig(0,0,,”ofsl”)函數(shù)接口在已建好的TFFS上掛接DOS文件系統(tǒng),,成功后,即可通過open,、read,、write等來操作Flash上的文件系統(tǒng),也可以通過FTP方式用IE訪問該文件系統(tǒng)中的內(nèi)容,。
4.5 Makefile文件的修改
對(duì)于Makefile的修改非常簡(jiǎn)單,,因?yàn)閹讉€(gè)和TFFS相關(guān)的源文件都是以.pl的方式被鏈人bsp工程的,所以只需要在makefile文件中把這個(gè)文件加入即可,,即在makefile中加了如下的宏定義:
MACH_EXTRA+=../ArmPri/ARMARCH5gnu/ArmBspPrj.pl
5 結(jié)束語
本文對(duì)VxWorks下TFFS文件系統(tǒng)的層次結(jié)構(gòu)和FTL層的啟動(dòng)過程,、塊映射算法、垃圾回收算法以及用FTL創(chuàng)建DOSFS進(jìn)行了分析,,給出了在M25P32 SPI Flash上創(chuàng)建TFFS文件系統(tǒng)和將TFFS掛在DOSFS的實(shí)現(xiàn)方法,。通過對(duì)TFFS核心層FIL的分析給出的TFFS實(shí)現(xiàn)方法,可以從更基礎(chǔ)的層面來認(rèn)識(shí)VxWorks中的TFFS文件系統(tǒng),,從而給TFFS文件系統(tǒng)的問題定位和實(shí)現(xiàn)帶來新的方法。