之前一直使用临时的linux下载并烧录yaffs文件系统,最近闲来无事研究一下uboot直接烧录yaffs的功能。当然参考了网上很多人的经验,自己只是对应实践一下,并附上自己的一些理解。
下载Yaffs:
点击use this URL:
还可以使用linux命令git clone git:// 获取
首先必须清楚工作原理。
mkyaffsimage工具的ecc
uboot的ecc
linux的ecc
如果想让uboot烧录的yaffs文件系统可以被linux识别,那么ecc/oob一定要正确,这就要求我们必须要使mkyaffsimage的
ecc算法以及oob布局与linux的完全一致,uboot的ecc和oob跟我们这个yaffs可以说完全无关,它的算法也跟另外二者差异很大,默认
情况下,uboot会自动计算ecc然后填写oob区域,但是yaffs跟其他的image是有很大差别,它的image文件本身就包含了oob区域,所
以说它会是512+16字节对齐的,所以uboot在烧写yaffs的时候,不需要计算ecc,而是直接将每页数据后面的16字节oob数据直接写进
nand的oob区域即可。
1.修改uboot
uboot本身是不支持yaffs的烧录的,所以我们需要自己来追加命令实现之,需要修改一下几个文件:
common/cmd_nand.c
U_BOOT_CMD()宏中
"nand read[.yaffs] - addr off|partition size\n"
"nand write[.yaffs] - addr off|partition size - read/write `size' bytes starting\n"
在do_nand()中,实现yaffs烧录配置
else if(s != NULL && (!strcmp(s, ".yaffs") ))
{
if(read)
{
/*read*/
nand_read_options_t opts;
memset(&opts, 0, sizeof(opts));
opts.buffer
= (u_char*) addr;
opts.length
= size;
opts.offset
= off;
opts.readoob
=1; /*read oob info*/
opts.quiet = quiet;
ret = nand_read_opts(nand, &opts);
}
else
{
/*write*/
nand_write_options_t opts;
memset(&opts, 0, sizeof(opts));
opts.buffer
= (u_char*) addr;
opts.length
= size;
opts.offset
= off;
opts.writeoob
=1;
opts.pad
= 0; /* ????what;s this*/
opts.noecc
=1; /*yaffs image include oob*/
opts.blockalign = 1;
opts.quiet
= quiet;
opts.skipfirstblk=1; /*first block for yaffs store nand static*/
ret = nand_write_opts(nand, &opts);
}
}
以上我们给nand_write_options_t添加了一个成员skipfirstblk,它是为了跳过nand的第一块,yaffs文件系统会使用第一块来存储整个nand的结构,所以预留之。
include/nand.h
struct nand_write_options结构体
int skipfirstblk;
drivers/nand/nand_util.c
在while (blockstart != (mtdoffset & (~erasesize_blockalign+1))) 循环之后,也就是为了跳过第一块的烧录
int skipfirstblk=opts->skipfirstblk;
if(skipfirstblk)
{
mtdoffset +=erasesize_blockalign;
skipfirstblk=0;
continue;
}
其中配置yaffs的write命令的时候,一定要关闭ecc,这个就是关闭uboot自己的ecc计算,同时需要打开writeoob,就是将数据后面的oob直接写进nand。
2.修改配置linux
linux的ecc根据配置不同,使用的也是不同的,选中Lets Yaffs do its own ECC会使用yaffs自带的fs/yaffs2/yaffs_ecc.c否则会使用nand的drivers/mtd/nand/nand_ecc.c
FileSystem-> Miscellaneous filesystems->Lets Yaffs do its own ECC
目前仅仅勾取了这一个,按照道理来讲也需要勾取Lets Yaffs do
its own ECC的,难道是我关闭了nand ecc校验?以后会做下试验,将此补齐。由于配置内核是没有设置Lets Yaffs do
its own ECC,yaffs文件系统将使用MTD设备层的ECC校验方法,制作映像文件时也应该使用与MTD设备层相同的函数计算ECC码。
如果配置内核时设置了Lets Yaffs do its own
ECC,则yaffs文件系统将使用yaffs2/yaffs_ecc.c文件中的yaffs_ECCCalculate函数来计算ECC码;否则使用
drivers/mtd/nand/nand_ecc.c文件中的nand_calculate函数。至于这个选项勾上与否,要看
mkyaffsimage工具的ecc
oob的计算是与MTD/yaffs哪一个完全吻合,如果mtd和yaffs都一样的话,勾上与否都是可以的,我自己的试验是勾上不勾上都是可以挂载上
的。
关闭nand的ecc的方法是:/drivers/mtd/nand/xxx_nand.c nand_chip->ecc.mode=NAND_ECC_NONE;如果需要自己调试的话建议首先就是把它给关了。
自己将nand的soft_ecc打开,偶尔就会出现问题了。(此时我已经
勾上了Lets Yaffs do its own ECC)可以挂载,但是会丢失部分东西。会出现诸如page 4076 in gc has no
object: 0 0 0 之类的错误,这个其实也就是nand的ecc的问题了,直接取消Lets Yaffs do its own
ECC试试先吧。
最简单的配置就是:1.取消nand的ecc校验,设置成none 2.勾选Lets Yaffs do its own ECC,也会出些问题。所以最保险的做法还是全部关闭掉.这样就相当于使用mtd的no ecc了。
当然最好的做法是,取消MTD的soft ecc然后勾上Lets Yaffs do its own ECC选项,工具保持跟yaffs一致最好。
3.修改mkyaffsimage工具
这里需要注意的就是oob区域的布局了,一定要跟linux一致,linux的oob布局可以从linux/fs/yaffs2/yaffs_mtdif.c中确定
大致研究了下韦东山的工具,他是将linux中的linux/fs/yaffs2/yaffs_packedtags1.c
移植进来了,至于具体的差别,以后再研究,这里还有一个问题就是读写问题,yaffs2中读写不像mkyaffsimage那么直接,而是用到了
oob2spare和spare2oob这样的做法,实在绕,这一部分的制作我的参考的http://blog.chinaunix.net
/space.php?uid=21072109&do=blog&id=1830842
归根到底,这里的oob填充要和linux的MTD或者yaffs符合即
可,如果选择跟MTD匹配(soft ecc最好关闭,如果未关闭而通过最好),就请取消Lets Yaffs do its own
ECC的勾选;如果选择跟yaffs匹配就请勾选Lets Yaffs do its own ECC.
烧录:
烧录 启动到uboot的时候,首先tftp 到sdram,然后再nand write到nand即可
nand erase 350000 400000
tftp 80500000 bufs.img
nand write.yaffs 80500000 350000 $(filesize)
这里一定要注意size大小一定要512+16对齐,yaffs的image文件自身已经528对齐了,所以我们这里使用filesize,烧录其他的
image也是要对齐的,其他的一般都是512对齐,但是其filesize未必会是512对齐的,所以烧录的时候需要稍作注意
参考http://blog.chinaunix.net/space.php?uid=21072109&do=blog&id=1830842
阅读(1469) | 评论(0) | 转发(0) |