373 opts.noecc = 1; /* 不需要计算ECC,yaffs映像中有OOB数据 */
374 opts.writeoob = 1;/* 写OOB区 */
375 opts.blockalign = 1;/* 每个“逻辑上的块”大小为1个“物理块” */
376 opts.quiet = quiet;/* 是否打印提示信息 */
377 opts.skipfirstblk = 1;/* 跳过第一个可用块 */
378 ret = nand_write_opts(nand, &opts);
379 }
380 } else {
……
385 }
386
第354~379行就是针对命令“nand read.yaffs ……”、“nand
write.yaffs ……”增加的代码。有兴趣的读者可以自己分析“if (read)”分支的代码,下面只讲解“else”分支,即“nand
write.yaffs ……”命令的实现。
NAND Flash每一页大小为(512+16)字节(还有其他格式的NAND
Flash,比如每页大小为(256+8)、(2048+64)等),其中的512字节就是一般存储数据的区域,16字节称为OOB(Out Of
Band)区。通常在OOB区存放坏块标记、前面512字节的ECC较验码等。
cramfs、jffs2文件系统映像文件中并没有OOB区的内容,如果将它们烧入NOR
Flash中,则是简单的“平铺”关系;如果将它们烧入NAND Flash中,则NAND
Flash的驱动程序首先根据OOB的标记略过坏块,然后将一页数据(512字节)写入后,还会计算这512字节的ECC较验码,最后将它写入OOB区,
如此循环。cramfs、jffs2文件系统映像文件的大小通常是512的整数倍。
而yaffs文件系统映像文件的格式则跟它们不同,文件本身就包含了OOB区的数据(里面有
坏块标记、ECC较验码、其他yaffs相关的信息)。所以烧写时,不需要再计算ECC值,首先检查是否坏块(是则跳过),然后写入512字节的数据,最
后写入16字节的OOB数据,如此循环。yaffs文件系统映像文件的大小是(512+16)的整数倍。
注意:烧写yaffs文件系统映像时,分区上第一个可用的(不是坏块)块也要跳过。
下面分析上面的代码。
第369~371行设置源地址、目的地址、长度。烧写yaffs文件系统映像前,一般通过网
络将它下载到内存某个地址处(比如0x30000000),然后通过类似“nand write.yaffs 0x30000000
0x00A00000 $(filesize)”的命令烧到NAND
Flash的偏移地址0x00A00000处。对于这个命令,第369行中opts.buffer等于0x30000000,第370行中
opts.length等于$(filesize)的值,就是前面下载的文件的大小,第371行中的opts.offset等于0x00A00000。
这里列出不使用的第372行,是因为opts.forceyaffs这个名字很有欺骗性,它其实是指计算ECC较验码的一种方法。烧写yaffs文件系统映像时,不需要计算ECC较验码。
第373、374行指定烧写数据时不计算ECC较验码、而是烧入文件中的OOB数据。
第375行指定“逻辑块”的大小,“逻辑块”可以由多个“物理块”组成,在yaffs文件系统映像中,它们是1:1的关系。
第377行的opts.skipfirstblk是新加的项,nand_write_options_t结构中没有skipfirstblk成员。它表示烧写时跳过第一个可用的逻辑块——这是由yaffs文件系统的特性决定的。
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-66092-32.html
不惜一战