1. 程式人生 > >在NAND FLASH上建立YAFFS2檔案系統

在NAND FLASH上建立YAFFS2檔案系統

針對於flash的檔案系統有很多,據我瞭解有jffs(1,2,3),yaffs(1,2)。還有商業的三星開發的RFS(健壯檔案系統),專門針對三星自己的nand和onenand,從底層驅動到上層檔案系統一條龍服務,而且號稱和fat格式100%相容。當時看得我直流口水,心裡把三星恨的咬牙切齒。 下面主要介紹一下開源的yaffs檔案系統。
Yaffs(Yet Another Flash File System)檔案系統是專門針對NAND快閃記憶體設計的嵌入式檔案系統,目前有YAFFS和YAFFS2兩個版本,一般說來,YAFFS對512byte/page以下都有很好的支援,而更大的頁就需要YAFFS2了,如2K/page。
Yaffs檔案系統有些類似於JFFS/JFFS2檔案系統,與之不同的是JFFS1/2檔案系統最初是針對NOR FLASH的應用場合設計的,而NOR FLASH和NAND FLASH本質上有較大的區別,所以儘管JFFS1/2 檔案系統也能應用於NAND FLASH,但由於它在記憶體佔用和啟動時間方面針對NOR的特性做了一些取捨,所以對NAND來說通常並不是最優的方案。
Yaffs對檔案系統上的所有內容(比如正常檔案,目錄,連結,裝置檔案等等)都統一當作檔案來處理,每個檔案都有一個頁面專門存放檔案頭,檔案頭儲存了檔案的模式、所有者id、組id、長度、檔名、Parent Object ID等資訊。因為需要在一頁內放下這些內容,所以對檔名的長度,符號連結物件的路徑名等長度都有限制。
前面說到對於NAND FLASH上的每一頁資料,都有額外的空間用來儲存附加資訊,通常NAND驅動只使用了這些空間的一部分,YAFFS正是利用了這部分空間中剩餘的部分來儲存檔案系統相關的內容。同時由於支援的page變大,YAFFS2使用更多的spare space來儲存這些資訊。在結構上YAFFS和YAFFS2有一定的不同,具體結構可以去看一看這篇文件
http://www.aleph1.co.uk/node/38

那麼這個檔案系統是如何運作起來呢。
操作檔案系統的第一步自然是取得SuperBlock了,Yaffs檔案系統本身在NAND Flash上並不存在所謂的SuperBlock塊,完全是在檔案系統mount的過程中由read_super函式填充的,不過有意思的一點是,由於物理上沒有儲存superblock塊,所以NAND Flash上的yaffs檔案系統本身沒有儲存filesystem的魔數(MagicNum),在記憶體中superblock裡的s_magic引數也是直接賦值的,所以儲存在NAND FLASH上的任何檔案系統都能被當作yaffs檔案系統mount上來,只是資料都會被當作錯誤資料放在lost+found目錄中,不知道這算不算yaffs檔案系統的一個bug。
通常一個具體的檔案系統在VFS的Super_block結構中除了通用的資料外,還有自己專用的資料,Yaffs檔案系統的專用資料是一個yaffs_DeviceStruct結構,主要用來儲存一些相關軟硬體配置資訊,相關函式指標和統計資訊等。
在mount過程執行read_super的過程中,Yaffs檔案系統還需要將檔案系統的目錄結構在記憶體中建立起來。由於沒有super塊,所以需要掃描Yaffs分割槽,根據從OOB中讀取出的yaffs_tags資訊判斷出是檔案頭page還是資料page。再根據檔案頭page中的內容以及資料page中的ObjectID/ChunkID/serial Number等資訊在記憶體中為每個檔案(Object)建立一個對應的yaffs_object物件。
在yaffs_object結構中,主要包含了:
    如修改時間,使用者ID,組ID等檔案屬性;
    用作yaffs檔案系統維護用的各種標記位如髒(dirty)標記,刪除標記等等;
    用作組織結構的,如指向父目錄的Parent指標,指向同級目錄中其他物件連結串列的     siblings雙向連結串列頭結構
此外根據Object型別的不同(目錄,檔案,連結),對應於某一具體型別的Object,在Yaffs_object中還有其各自專有的資料內容
       普通檔案:檔案尺寸,用於快速查詢檔案資料塊的yaffs_Tnode 樹的指標等
       目錄:目錄項內容雙向連結串列頭(children)
       連結:softlink的alias,hardlink對應的ObjectID
除了對應於儲存在NAND FLASH上的object而建立起來的yaffs_object以外,在read_super執行過程中還會建立一些虛擬物件(Fake Object),這些Fake Object在NAND FLASH上沒有對應的物理實體,比如在建立檔案目錄結構的最初,yaffs會建立四個虛擬目錄(Fake Directory):rootDir, unlinkedDir, deleteDir, lostNfoundDir分別用作根目錄,unlinked物件掛接的目錄,delete物件掛接的目錄,無效或零時資料塊掛接的目錄。
通過建立這些yaffs_object,yaffs檔案系統就能夠將儲存在NAND FLASH上資料系統的組織起來,在記憶體中維護一個完整的檔案系統結構
另外,我在看YAFFS2的原始碼的時候發現,YAFFS2再mount和umount和YAFFS有所區別,增加一個checkpoint機制,每次在umount的時候,YAFFS2會開闢專門幾個block用來存取一些資訊,等待下次mount的時候就不需要掃描整個flash,而只有找出這幾個塊就可以了,這樣可以大大加速mount的時間。不過仔細的原理我也沒有研究過。有興趣的話可以看一看這封郵件
http://www.aleph1.co.uk/pipermail/yaffs/2006q2/002019.html