YAFFS2概述

術語 
頁面
:Nand尋址單位,:block,參出單元,大塊:chunk,YAFFS尋址單位,和頁面的大小相同, YAFFS對象:文件,目錄鏈接和設備等;

概述

YAFFS2佔用更少的RAM和啓動速度快等優點。Yaffs文件系統本身在NAND Flash上並不存在所謂的SuperBlock塊,完全是在文件系統mount的過程中由read_super函數填充的,由於物 理上沒有存儲superblock塊,所以NAND Flash上的yaffs文件系統本身沒有存儲filesystem的魔數(MagicNum),在內存中superblock裏的s_magic參數也是直接賦值的,所以存儲在NAND FLASH上的任何文件系統都能被當作yaffs文件系統mount上來,數據都會被當作錯誤數據放在lost+found目錄中。

YAFFS的文件數據存放再chunk中,chunk和NAND頁面大小相同,每個頁面都標有一個文件id和chunk號,這些標識放在OOB中,chunk號 = 文件位置 / chunk大小。文件頭信息再文件的第一個文件頁面中,通過一個標誌來指定。目錄,設備和鏈接都使用相同的機制。第一個頁面指明瞭對象的類型。

YAFFS2從並不重寫頁面(YAFFS1通過OOB標識Block爲delete)。刪除的動作是把刪除的對象移到一個特殊的隱藏的unlink目錄中。只有當包含該對象的所有頁面被擦除(通過跟蹤系統中每個對象的大塊數目,直到數目爲0)。當需要重寫一個頁面時,會寫入一個新的頁面替換相應大塊,標識和原來的相同。除了這些標誌以外,頁還有一個2-bit序列增加的數用防止在操作中出現斷電等意外處理中斷。通過這個數來仲裁有相同標誌的兩個頁面,那個是有效的。

理論上YAFFS不需要在內存中構建文件系統的所有信息,但是那會非常耗時,所以在boot的是否,完成對flash的一次掃描。和JFFS相同。

YAFFS標誌(YAFFS1):
18-bit:對象ID,文件ID爲0表示無效的或者是刪除的頁面,3FFF也是無效的,也inode同義;
2-bit:序列號;
20-bit:大塊id,id爲0,表示文件的第一塊,包含文件頭信息;文件最大500M;
10-bit:頁面中的有效字節數;
12-bit:ECC;

YAFFS標誌(YAFFS2):
4B: 32-bit大塊ID;
4B:32對象ID;
2B:該塊中的有效字節數;
4B:該擦除快的序列號;
3B:標識部分的ECC;
12B:數據部分的ECC;

頁面分配和垃圾回收
頁面順序的從擦除塊中分配,至少需要保留2-3個擦除塊實現垃圾回收。如果沒有足夠的乾淨塊,那麼找一個髒塊回收,如果沒有髒塊,那麼回收最 不乾淨的塊。

輔助信息

yaffs的格式化很簡單,就是擦除設備。這個利用mtd-util工具擦除一下nand就可以了。

mkyaffs2image和mkyaffsimage區別。一個可以支持2k頁面,一個僅僅512頁面。

編譯

yaffs2的編譯非常簡單,只要下載yaffs2,看看版本支持信息,可以作爲一個模塊編譯,此時只要指定內核的位置,如同編譯其他模塊一樣,會自動使用配置信息。也可以patch到內核中,這樣驅動的時候可以直接作爲內核的一部分。

編譯mtd工具,可以下載 ftp.infradead.org/pub/mtd-utils/ mtd工具,這個工具在編譯jffs2相關應用時需要zlib庫。大部分製作的toolchains庫中沒有這個zlib相關信息。可以自己下載個zlib庫的源碼然後編譯安裝就可以了,我使用zlib-1.2.3。如果使用mtd-utils-1.2.0或者mtd-utils-1.1.0,這個還需要lzo庫,lzo是一種實時壓縮工具,這個l-z-o是三個人的名字首字母,這裏使用lzo-2.03。 j'f'fs2支持壓縮,所有使用這個庫,其他工具不需要。可以編譯這個庫安裝,其實我不需要這些庫,但是考慮以後做安全相關或者vpn可能會用到,所以還是安裝了。編mtd-util時需要ACL,有的沒有這個頭文件,只要在Makefile中添加一個WITHOUT_XATTR=1 屏蔽掉就可以,大夥兒都這麼弄,結果很和諧呀!

使用

在yaffs2的util目錄下有mkyaffsimage工具,運行mkyaffsimage dir imagename可以製作出yaffs1文件系統的鏡像。製作出來的yaffs image文件與通常的文件系統的image文件不同,因爲在image文件裏除了以512字節爲單位的一個page的data數據外,同時緊跟在後還包括了16字節爲單位的NAND備份數據區(OOB)的數據。所以實際上是以528個字節爲單位的。就是因爲包含了這額外的16字節/page的數據,所以基本上常規辦法如dd,或者通常的下載其它類型image的工具就無法正常下載yaffs image了,需要修改你所使用的下載工具的代碼,使得它能將yaffs image中的這些額外數據也寫入NAND FLASH OOB中。通過mkyaffsimage制做出來的image其OOB中也包含它自己計算的ECC校驗數據,其校驗算法有可能和MTD NAND驅動的校驗算法不同,如果在內核中由MTD來處理ECC,會造成MTD認爲所有的page都校驗錯誤。所以把Lets Yaffs do its own ECC選上,要把MTD NAND驅動中的ECC校驗關閉。不知道現在最新的版本怎麼樣。

但是默認的MTD在使用ECC的時候總是不對,可以把ECC設置爲chip->eccmode = NAND_ECC_NONE; 但是並不推薦這種方式。


jffs2使用

使用之前要先用工具flash_erase或者flash_eraseall擦除nandflash,具體使用的步驟如下:

# flash_erase /dev/mtd1

製作jffs2映像

# cd /var/tmp

# mkdir jffs2 (jffs2下的目錄可以任意建)

# mkfs.jffs2 –d jffs2/ -o jffs2.img 這個最好在主機上完成在拷貝到目標系統上。

# cp /var/tmp/jffs2/jffs2.img /dev/mtdblock1 或者flashcp

最後# mount -t jffs2 /dev/mtdblock1 /mnt/mtd即可,使用結束可使用$ umount /mnt/mtd 卸載.

如果只是當作普通的jffs2 來使用dataflash或者nandflash,可不必製作 jffs2映像,只需要最後一步

# mount -t jffs2 /dev/mtdblock1 /mnt/mtd即可。

如果在pc機上使用mkfs.jffs2命令創建image,那麼需要特別注意endianess和擦除塊大小,endian不對的話,系統會自動給予提示,容易看出來。但是如果擦除塊不對的話,就會出現如下問題。

Empty flash at 0x0000fffc ends at 0x00010000
CLEANMARKER node found at 0x00010000, not first node in block (0x00000000)
Empty flash at 0x0002fffc ends at 0x00030000
CLEANMARKER node found at 0x00030000, not first node in block (0x00020000)
Empty flash at 0x0004fffc ends at 0x00050000
CLEANMARKER node found at 0x00050000, not first node in block (0x00040000)
Empty flash at 0x0006fffc ends at 0x00070000
CLEANMARKER node found at 0x00070000, not first node in block (0x00060000)
Empty flash at 0x0008fffc ends at 0x00090000
CLEANMARKER node found at 0x00090000, not first node in block (0x00080000)
Empty flash at 0x000afffc ends at 0x000b0000
CLEANMARKER node found at 0x000b0000, not first node in block (0x000a0000)

收穫

linux內核是極其穩定的,錯有不穩定因素在於mach部分代碼的銜接部分。內核的代碼真是完美呀,擴展性出奇的好。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章