U-BOOT 支持yaffs2文件系统的烧写。
其实移植这步烧写很简单,只是将打包的文件系统一次写入NAND即可,以页为单位,一次写入2K+64B。
包含main和spare区,其中spare的ECC数据等在yaffs2文件系统制作时就已经写好了。是通过软件ECC
每256B产生3B的规则进行的。所以必须保证mkyaffs2image工具能正确制作YAFFS2文件系统。否则系统是
启动不了。
具体移植步骤:
1.在include/configs/xxxxx.h增加宏
#define CONFIG_MTD_NAND_YAFFS2
2.添加write.yaffs2烧写命令,U-BOOT只需要写命令即可
vim common/cmd_nand.c中
501 #if defined(CONFIG_MTD_NAND_YAFFS2)
502 "nand read.yaffs2 - addr off|partition size\n"
503 "nand write.yaffs2 - addr off|partiton size\n"
504 #endif
添加以上帮助说明信息
增加解析yaffs2命令的函数
344 #if defined(CONFIG_MTD_NAND_YAFFS2)
345 else if(s != NULL && !strcmp(s, ".yaffs2") ) {
346 if (read) {
347 /* nand->rw_oob = 1;
348 nand->skipfirstblk = 1;
349 ret = nand_read_skip_bad(nand,off,&size,(u_ chat *)addr);
350 nand->skipfirstblk = 0;
351 nand->rw_oob = 0;
352 */
353 }
354 else {/* 主要关心写命令 */
355 nand->rw_oob = 1;
356 nand->skipfirstblk = 1;
357 ret = nand_write_skip_bad(nand, off, &size, (u_char *)addr);
358 nand->skipfirstblk = 0;
359 nand->rw_oob = 0;
360 }
361 }
362 #endif
nand->rw_oob 和 nand->skipfirstblk 一个作为烧写YAFFS的标志,文件系统跳过的块,因为YAFFS2文件系统烧写时需要跳过
第一块。这是由于其特性决定的,第一块用于构建BBT(bad block table)
这两个新成员需要添加在include/linux/mtd/mtd.h的mtd_info结构体中
128 #if defined(CONFIG_MTD_NAND_YAFFS2)
129 u_char rw_oob;
130 u_char skipfirstblk;
131 #endif
3.由于写操作会调用nand_write_skip_bad()函数,这里也需要修改,位于nand_util.c
474 #if defined(CONFIG_MTD_NAND_YAFFS2)
475 if (nand->rw_oob == 1) {/* 烧写的YAFFS2文件 */
476
477 size_t oobsize = nand->oobsize;
478 size_t datasize = nand->writesize;
479 int datapages = 0;
480 datapages = (*length)/(datasize+oobsize);/* 注意这里是整个长度 */
481 *length = datapages*datasize; /* 实际main区大小 */
482 left_to_write = *length; /* 在具体烧写时会以left_to_write做参数 */
483 }
484 #endif
传入这个函数的size 是nand命令参数给的,对于YAFFS2为实际大小,即2112的倍数,off也是经由命令行传递来的
而addr是对应内存BUF的地址
466 int nand_write_skip_bad(nand_info_t *nand, ulong offset, size_t *length,
467 u_char *buffer)
这是函数原型
所以以上添加代码的意思是,如注释,也就是从yaffs2文件大小中提取main区的数据大小
在以下代码添加如是宏,避免影响其他烧写
498 #if !defined (CONFIG_MTD_NAND_YAFFS2)
499 if (len_incl_bad == *length) {
500 rval = nand_write (nand, offset, length, buffer);
501 if (rval != 0)
502 printf ("NAND write to offset %x failed %d\n",
503 offset, rval);
504
505 return rval;
506 }
507 #endif
518 #if defined(CONFIG_MTD_NAND_YAFFS2)
519 if (nand->skipfirstblk == 1) {/* 需要跳过第一块 */
520 nand->skipfirstblk = 0;
521 printf("Skip the first good block 0x%08x\n",offset &
522 ~(nand->erasesize - 1));
523 offset += nand->erasesize - block_offset;/* 故偏移地址 + 1block */
524 continue;
525 }
526 #endif
527
542 #if defined(CONFIG_MTD_NAND_YAFFS2)
543 if (nand->rw_oob == 1)
544 p_buffer += write_size+(write_size/nand->writesize*nand->oobsize);
/* 注意因为是一次烧写main和spare 故指向镜像的指针编译量要加上OOB区的大小,一次写入一块,不足一块以页写入*/
545 else
546 p_buffer += write_size;
547 #else
548
549 p_buffer += write_size;
550 #endif
551 }
552
553 return 0;
554 }
4.下面看nand_write()的实现
536 rval = nand_write (nand, offset, &write_size, p_buffer);
这是传递的参数,函数位于nand_base.c中
2011 #if defined(CONFIG_MTD_NAND_YAFFS2)
2012 int oldopsmode = 0;
2013 if (mtd->rw_oob != 1)
2014 chip->ops.oobbuf = NULL;
2015 else {
2016 chip->ops.oobbuf = (uint8_t *)(buf+mtd->writesize);/* oob数据起始地址 */
2017 chip->ops.ooblen = mtd->oobsize; /* 64B */
2018 chip->ops.ooboffs = 0;
2019 oldopsmode = chip->ops.mode;
2020 chip->ops.mode =MTD_OOB_RAW; /* 原始模式,不进行ECC计算 */
2021 }
2022 #else
2023 chip->ops.oobbuf = NULL;
2024 #endif
其实这个函数只是填充nand_chip这个结构体然后调用
2053 ret = nand_do_write_ops(mtd, to, &chip->ops);
函数原型如下
1887 /**
1888 * nand_do_write_ops - [Internal] NAND write with ECC
1889 * @mtd: MTD device structure
1890 * @to: offset to write to
1891 * @ops: oob operations description structure
1892 *
1893 * NAND write with ECC
1894 */
1895 static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
1896 struct mtd_oob_ops *ops)
这个函数功能,选择具体的一片NAND,当然大多情况只有一片,然后会处理OOB区数据
根据chip->ops.mode,这里为原始模式,即不进行处理,则将OOB区数据复制到对应的ops
这是里面添加的内容
然后会调用具体的write_page写一页数据
1972 #if defined(CONFIG_MTD_NAND_YAFFS2)
1973 if (mtd->rw_oob == 1) {
1974 oob = oob + bytes;
1975 buf = buf + ops->ooblen;
1976 }
1977 #endif
每写一次oob和databuf都移动2112B。
1962 ret = chip->write_page(mtd, chip, wbuf, page, cached,
1963