术语
页面: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工具,可以下载
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部分代码的衔接部分。内核的代码真是完美呀,扩展性出奇的好
阅读(1670) | 评论(0) | 转发(0) |