Yaffs(Yet Another Flash File System)文件系統(tǒng)是專門針對NAND 閃存設計的嵌入式文件系統(tǒng),目前有YAFFS 和
Yaffs 文件系統(tǒng)有些類似于JFFS/JFFS2 文件系統(tǒng),與之不同的是JFFS1/2 文件系統(tǒng)最初是針對NORFLASH的應用場合設計的,而NOR FLASH 和NAND FLASH本質(zhì)上有較大的區(qū)別,所以盡管JFFS1/2 文件系統(tǒng)也能應用于NANDFLASH,但由于它在內(nèi)存占用和啟動時間方面針對NOR 的特性做了一些取舍,所以對NAND來說通常并不是最優(yōu)的方案。
二, yaffs/
yaffs2在2.6.9中的移植
(1),下載YAFFS文件系統(tǒng)代碼,下載網(wǎng)址:
http://www.aleph1.co.uk/cgi-bin/viewcvs.cgi/點擊頁面左下角的Download tarball即可下載全部相關代碼。
(2),將下載的文件yaffs.tar.gz拷貝到你的一個臨時文件夾中,假設是/tmp,并解壓:
# cd /tmp
# tar xzvf yaffs.tar.gz
解壓后得到Development文件夾,該文件夾里有兩個子文件:yaffs和
yaffs2??紤]到現(xiàn)在的NAND FLASH容量越做越大,而且
yaffs2可以自動選擇掛載是yaffs1還是
yaffs2文件系統(tǒng),這里我們移植
yaffs2。當然如果你的NAND FLASH只是512+16B的,可以只移植yaffs,因為即使你移植了
yaffs2,它也會自動選擇掛載yaffs1的。
(3)在要移植的內(nèi)核目錄下建立
yaffs2文件夾,并將需要的文件拷貝過來:
# cd $(linuxdir)/fs
# mkdir
yaffs2 # cd yafs2
# cp /tmp/Development/
yaffs2/*.c .
# cp /tmp/Development/yaffs/*.h .
# cp /tmp/Development/
yaffs2/Makefile-kernel Makefile
# cp /tmp/Development/
yaffs2/Kconfig .
(4),修改$(linuxdir)/fs/
yaffs2中的文件:
在開始未修改該目錄.c文件前,會出現(xiàn)很多的built-in.o的錯誤,要么是提示某些函數(shù)未定義,要么是某些函數(shù)重復定義,花了我很長的時間,終于找到問題所在。部分錯誤提示如下:(這是我開始編譯yaffs時的錯誤,
yaffs2的錯誤更多,但類型差不多)
fs/built-in.o(.text+0x8478c): In function `yaffs_internal_read_super_
mtd':
: undefined reference to `nandmtd_WriteChunkToNAND'
fs/built-in.o(.text+0x84790): In function `yaffs_internal_read_super_
mtd':
: undefined reference to `nandmtd_ReadChunkFromNAND'
fs/built-in.o(.text+0x84794): In function `yaffs_internal_read_super_
mtd':
: undefined reference to `nandmtd_EraseBlockInNAND'
fs/built-in.o(.text+0x84798): In function `yaffs_internal_read_super_
mtd':
: undefined reference to `nandmtd_InitialiseNAND'
查看.c文件,我發(fā)覺有很多是通過Kconfig文件里定義的CONFIG常量來判斷執(zhí)行的,而這些常量在你make menuconfig/xconfig后退出后會將你的選擇保存到<linux/config.h>文件中,但
yaffs2目錄下的有些.c文件中引用了這些常量來判斷,卻并未加入引用config.h文件,從而會出錯。將
yaffs2目錄下所有引用了這些常量的.c文件中加入對config.h的引用即可: #include <linux/config.h>
(5),修改$(linuxdir)/fs/Makefile 和 Kconfig文件。
# cd $(linuxdir)/fs
# vi Makefile (將下面一行添加到Makefile中)
obj-$(CONFIG_YAFFS_FS) +=
yaffs2/
# vi Kconfig (將下面一行添加到Kconfig中)
source "fs/
yaffs2/Kconfig
(6),在編譯內(nèi)核時選擇:
<*>
YAFFS2 file system support
<*> 512 byte / page devices
<*> Lets Yaffs do its own ECC
<*> 2048 byte (or larger) / page devices
<*> Autoselect
yaffs2 format
<*> Disable lazy loading
<*> Turn off wide tnodes
<*> Turn off debug chunk erase check
通過mkyaffsimage 制做出來的image 其OOB 中也包含它自己計算的ECC校驗數(shù)據(jù),其校驗算法有可能和
MTD NAND 驅(qū)動的校驗算法不同,如果在內(nèi)核中由
MTD來處理ECC,會造成
MTD 認為所有的page 都校驗錯誤。所以,這也是我前面說最好把Lets Yaffs do its own ECC 選上的原因,同時,要把
MTD NAND 驅(qū)動中的ECC 校驗關閉。在$(linuxdir)/drivers/
mtd/nand/your_nand.c的初始化函數(shù)中設置this-eccmode = NAND_ECC_NONE.這樣做實際是使用了yaffs的ECC,但在讀寫yaffs分區(qū)時分出現(xiàn)提示說:
Reading data from NAND FLASH without ECC is not recommended
Writing data without ECC to NAND-FLASH is not recommended
個人認為,其實已經(jīng)使用了yaffs的ECC,只是在傳給
MTD時,
MTD沒認可,參考
mtd/nand/nand_base.c文件里的nand_read_ecc函數(shù)以及
yaffs2/yaffs_fs.c文件中在于ECC的定義。這里應該是提示沒用NAND的ECC,而使用的是yaffs的ECC。這可以通過mkyaffsimage制作一個image來驗證。解決方法:要么使用nand的ECC,將yaffs的ECC屏蔽掉;要么將nand_base.c里的相關錯誤信息屏蔽掉。
(7),修改你要移植的芯片中的Makefile,在devices后面添加mtdX和mtdblockX設備,設備個數(shù)視你的nand的分區(qū)個數(shù)而定,這里我的flash在your_nand.c中分成了三個區(qū)。
\
mtd0,c,90,0
mtd1,c,90,1
mtd2,c,90,2 \
\
mtdblock0,b,31,0 mtdblock1,b,31,1 mtdblock2,b,31,2
(8),編譯后將kernel和文件系統(tǒng)下載到板子上,查看結果并掛載。
# cat /proc/
mtd (查看分區(qū)情況)
mtd0: 00400000 00004000 "EV40 flash partition 1"
mtd1: 00400000 00004000 "EV40 flash partition 2"
mtd2: 00800000 00004000 "EV40 flash partition 3"
# cat /proc/filesystems (查看內(nèi)核支持的文件系統(tǒng))
nodev sysfs
nodev rootfs
nodev bdev
nodev proc
nodev sockfs
nodev futexfs
nodev pipefs
nodev eventpollfs
ext2
nodev ramfs
nodev devfs
nodev nfs
nodev jffs2
romfs
yaffs
yaffs2nodev rpc_pipefs
我們發(fā)現(xiàn)系統(tǒng)已經(jīng)支持yaffs和
yaffs2文件系統(tǒng)了。
# eraseall /dev/
mtd0 (在掛載之前可以先將該分區(qū)里的內(nèi)容擦除掉)
# mount –t
yaffs2 /dev/mtdblock0 /mnt (將第1個分區(qū)掛載到/mnt目錄下)
yaffs: dev is 32505856 name is "mtdblock0"
yaffs: Attempting
MTD mount on 31.0, "mtdblock0"
yaffs: auto selecting yaffs1
我們發(fā)現(xiàn)如果你的flash是512+16B / page的,即使你選擇的是
yaffs2文件系統(tǒng),內(nèi)核也會自動選擇掛載yaffs1文件系統(tǒng)。