前段时间因为移植QT,板子上的RAMDISK已经显得力不从心了。添加yaffs文件系统支持成为必需。可能是自己点比较悖,YAFFS的移植过程挺曲折的。费了三天时间终算搞定了。
像大多数人一样,一开始基本是按照网上牛人们的文章操作。包括准备源码包,修改内核编译选项,修改内核代码,编译工具软件。这些东西重复起来也没意思。。这里只是说说遇到的问题及解决方法:
首先我的内核版本是2.6.18,YAFFS源码包编译是通不过的。YAFFS2的可以。而yaffs下面却有个重要的工具mkyaffs,在yaffs2的包里面是没有的,很有用的一个软件,交叉编译后运行于开发板上,可以将一个nand分区格式化为yaffs文件格式。另一个工具mkyaffs2image可以将一个文件夹的内容制作成yaffs2文件系统的镜像,不过我没有发现有什么用处,yaffs2文件系统的镜像包含了ECC部分,用一般的烧写软件只当全部数据都写到数据块中。因此,制作完的镜像毫无用武之地,网上有人用mkyaffs将yaffs镜像载入nand分区:mkyaffs /dev/mtd1 yaffs.bin ,我尝试过,效果与mkyaffs /dev/mtd1一样。。。但是那样用肯定也是有根据的,第一mkyaffsimgage工具就是用来生成文件系统镜像的。第二根据mkyaffs.c源码也可以看到确实提供了加载镜像文件的功能:
见mkyaffs.c源码128行:
if( argc > (optcnt + 1) &&
(img = open(argv[optcnt + 1],O_RDONLY)) == -1) {
perror("opening image file");
exit(1);
}其中optcnt=1,也就是说如果参数>2,第三个参数就是镜像文件的路径。可惜我没试验成功,也没有提示什么opening image file错误。。。
我用的方法是先用RAMDISK启动,用mkyaffs格式化nand分区,然后挂载nand分区,将RAMDISK根文件系统内容拷贝到nand分区中。最后修改uboot启动参数为nand启动即可。当然,这里面也遇到些问题。时间久了,有些忘了。不过都是些小问题。
下载yaffs2源码的页面:http://www.aleph1.co.uk/cgi-bin/viewcvs.cgi/yaffs2/ 注意这个下载页面其实包含许多版本的,在左下角Show files using tag处可以选择。其中Main是最新版本,可以看到里面有部分文件修改日期在几天之前。一开始没注意这个,下载了最新版本,修改nand 驱动中ECC检验为ECC_NONE,而在内核编译时选择了Lets Yaffs do its own ECC [y] .其余内核选项就不多说了,网上都有介绍,主要是mtd驱动和yaffs2两部分的选项。编译完的内核仍旧是用RAMDISK启动,启动后先创建mtd设备节点:
# mknod /dev/mtd3 c 90 6
# mknod /dev/mtdblock3 b 31 3
注意同一nand分区字符设备与块设备的子设备号是2倍关系。使用mkyaffs格式/dev/mtd3 :
# mkyaffs /dev/mtd3
# mount /dev/mtdblock3 /mnt
挂载正常,可以创建新文件,新文件夹,一开始挺开心。。。后来执行cp时出现个问题:
#cp /bin/busybox /mnt/bin
到最后的时候显示:
Writing -2048 bytes to chunk!!!!!!!!!
然后就死机了。。
重启机器后发现分区中已经有busybox这个文件了,只是大小不对,少几百字节。查看源代码,问题出现在yaffs_guts.c中的yaffs_WriteChunkDataToObject函数中:
if(nBytes < 1 || nBytes > dev->totalBytesPerChunk){
T(YAFFS_TRACE_ERROR,
(TSTR("Writing %d bytes to chunk!!!!!!!!!" TENDSTR), nBytes));
while(1){}
}
网上一搜,目前无人遇到这个问题。。。真蒙。差点就放弃了,所以常常是成功离自己只差一步,再坚持一下,再换个思路去想问题说不定就豁然开朗,柳暗花明了。
后来发现yaffs_guts.c在这个版本中是7天前修改的,本身有BUG也是可能的。于是重新下载一个旧点的版本。我选择的是更新时间11个月的一个版本。重新编译内核,启动后挂载时显示了一大堆的坏块信息:block XXXX is bad ,在网上找到一个解决方法:
使用nand驱动的软件ECC检验,而不是ECC_NONE。而yaffs2的选项中下面几个不选:
Use older-style on-NAND data format with pageStatus byte [N]
Lets Yaffs do its own ECC [N]
Use the same ecc byte order as Steven Hill''''''''s nand_ecc.c [N]
Force chunk erase check [N]
再次编译,格式化后挂载,没有问题。。终于解决了问题。