开发板是一块2G的MLC的NandFlash,页大小8k+512,为其移植u-boot到yaffs2这了。以前在Mini2440上移植过2k+64的slc的NandFlash的Yaffs2支持,当然也是走马观花式的。等于对Yaffs2的概念还不是太清晰,不过这次也本不想去深入了解Yaffs2,想快点到Yaffs2+硬件ECC校验。但是这个Yaffs支持8k的页大小吗?网上现有的都是2k/Pagesize的。为此我又静下心看看Google和书。

        关于Yaffs2几个疑点,这里的Yaffs2中的“2”和它支持的pagesize 2k中的"2",可以不要搞混淆了。不要以为对于4k or 8k/pagesize大小上的会出现yaffs4 yaffs8。没有的事。Yaffs2是一种文件系统的格式,与Yaffs1的区别中确实是关于pagesize的关系,但是如果你NandFlash再大,目前的Yaffs2也是能够管理的。当然说话是要有根据的,我在Yaffs2邮件列表中可以看到证据( 这里);这里还要说明的是如果你直接去Yaffs2的官网,还在宣传它支持2k pagesize,这我个人认为是其文档太老的原因。
        转到的8k+512上来说,要想支持Yaffs2,就要在u-boot中移植这个功能,这个移植很成熟了,找一本书或者Google一下就能找到答案。然后依葫芦画瓢,添加之。但是为了这个Yaffs2移植的完整性,我要先在2k+64的pagesize中实验,因为slc不开启硬件ecc都可以无误支持,这个移植好后,可以直接来烧一个Yaffs2镜像直接启动挂载,只有正确挂载了说明才完全成功了。如果Yaffs2成功了,再一步步实现Yaffs2+HWECC。

         思路分析完了,就开始着手了,Yaffs2的添加直接参考《
u-boot for tiny210 ver4.0 (by liukun321 咕唧咕唧)》。本以为没有什么问题。可是问题就出来了。添加完之后,用nand dump e00000看是没有问题的。然后用它烧写后的Yaffs2不能正确挂载,开始着急了,本来烧写的慢,我硬着头皮试到深夜也不行。(现在看来应该是要先冷静下来,想想怎么解决这个问题)

         就扔下了,过了几天后,确实冷静了,想了几个调试的点。1.我只看了第1页的内容,没有查看后期的,后边查看一下说不定会有新发现。2.(其实没有第2,3了,说说没有冷静的想法,当时想我的和参考的u-boot不是一个版本,我真该直接用它的,现在用的版本就是shi。还觉得会是某些位烧写反转了,检查起来会非常麻烦,所以也恐惧)。真下用第一种方法去调试的时候,问题就解决了。下面说一下我调试的过程。
         1.先不去测试挂载,只看烧写的内容是,找到错在哪里了。所以我只需做一个最小的文件系统一个目录,里边一个helloworld.c内容为helloworld程序。用mkyaffs2img-128工具制作成镜像名字为yaffs2.img。这样方便测试。不耽误时间。
         2.查看第2页及以后的页和oob的内容查看规律。
         yaffs2.img只占了3页内容,看了这3页内容,我就找到了问题所在:


        3页原本不现的oob区内容,现在与源镜像比较发现都是第一个oob区中的内容。但是数据没有出现这个情况。为此请教了一个老手,描述了这个情况。他大概说了page oob中的内容是怎么进到NandFlash中的,mtd驱动就先将这个Yaffs2镜像,在内存中摆弄,摆弄成data1| data2| data3|  oob1| oob2|  oob3|。就好比你把碗中的花椒和你要吃的饭放开,这样你就在享受美味的同时一个花椒坏了你的心情。主要是方便。如果出现只有都是第页的oob区的内容,那就看看是它在整理这些数据的时候出现了问题还是怎么回事。这个整理在driver/mtd/nand/nand_base.c的nand_write这个函数中。 +#define NAND_YAFFS2_DEBUG 
+#ifdef NAND_YAFFS2_DEBUG
+  int j = 0;
+#endif
   uint8_t oobtemp[oobsize];
   int datapages = 0;
 
   datapages = len/(datasize);
   for(i=0;i<(datapages);i++) {
     memcpy((void *)oobtemp, (void *)(buf+datasize*(i+1)),oobsize);
     memmove((void *)(buf+datasize*(i+1)),(void *)(buf+datasize*(i+1)+oobsize),(datapages-(i+1))*(datasize)+(datapages-1)*oobsize);
     memcpy((void *)(buf+(datapages)*(datasize+oobsize)-oobsize),(void *)(oobtemp),oobsize);
+#ifdef NAND_YAFFS2_DEBUG 
+    printf("\noob %d:\n", i);
+    for(j=0; j<(oobsize); j++)
+      printf("%02X ", buf[((datapages)*(datasize+oobsize)-oobsize)+j]);
+#endif
   }
然后发现不这里是没有问题的,如下,和源文件是一样的,没有出现是整理出错的问题。
[Ver130726-TINY210v2]# nand write.yaffs 21000000 e00000 $filesize

NAND write: device 0 offset 0xe00000, size 0x18c0
Writing at 0xe00000 -- 
oobtemp 0:
FF FF 0 10 0 0 1 0 0 0 0 0 0 0 FF FF 0 0 30 BF F2 BF 5 0 0 0 5 0 0 0 3 0 0 0 D0 BF F2 BF 3 0 AA 9A A7 A6 95 AB FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 
oobtemp 1:
FF FF 0 10 0 0 1 1 0 0 0 0 0 0 FF FF 0 0 25 0 0 0 0 0 0 0 FF FF FF FF 0 0 0 0 34 BF F2 BF 1 0 FC C 3 F3 30 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 
oobtemp 2:
FF FF 0 10 0 0 1 1 0 0 1 0 0 0 47 0 0 0 3 BB F2 BF 8 0 0 0 8 0 0 0 A8 BF F2 BF 1 0 0 0 5 0 95 9A A7 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 100% is complete. 6144 bytes written: OK
[Ver130726-TINY210v2]# 


再然后是老手告诉我可以看看nand_fill_oob函数的问题,它是负责定位的。如果它定位始终是第1个oob内容,那么说明就是它引起的问题。
@@ -1998,8 +1998,10 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
     }
 
     if (unlikely(oob)) {
+      printf("\noob a:%d\n", oob);
       size_t len = min(oobwritelen, oobmaxlen);
       oob = nand_fill_oob(chip, oob, len, ops);
+      printf("\noob b:%d\n", oob);
       oobwritelen -= len;
     }
 
@@ -2050,23 +2052,31 @@ static int nand_write(struct mtd_info *mtd, loff_t to, size_t len,

打印信息如下,发现经过nand_fill_oob确实是在作怪。之后的页oob指向定位都没有变。
oob 0:
FF FF 00 10 00 00 01 00 00 00 00 00 00 00 FF FF 00 00 30 BF F2 BF 05 00 00 00 05 00 00 00 03 00 00 00 D0 BF F2 BF 03 00 AA 9A A7 A6 95 AB FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 
oob 1:
FF FF 00 10 00 00 01 01 00 00 00 00 00 00 FF FF 00 00 25 00 00 00 00 00 00 00 FF FF FF FF 00 00 00 00 34 BF F2 BF 01 00 FC 0C 03 F3 30 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 
oob 2:
FF FF 00 10 00 00 01 01 00 00 01 00 00 00 47 00 00 00 03 BB F2 BF 08 00 00 00 08 00 00 00 A8 BF F2 BF 01 00 00 00 05 00 95 9A A7 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 
oob a:553654272

oob b:553654336

oob a:553654336

oob b:553654336

oob a:553654336

oob b:553654336
100% is complete. 6144 bytes written: OK


最后定位到:
@@ -1998,11 +2003,18 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
     }
 
     if (unlikely(oob)) {
+#ifdef NAND_YAFFS2_DEBUG 
       printf("\noob a:%d\n", oob);
+      printf("oobwritelen=%d, oobmaxlen=%d\n", oobwritelen, oobmaxlen);
+#endif
       size_t len = min(oobwritelen, oobmaxlen);
       oob = nand_fill_oob(chip, oob, len, ops);
+#ifdef NAND_YAFFS2_DEBUG 
       printf("\noob b:%d\n", oob);
+#endif
+#ifndef CONFIG_CMD_NAND_YAFFS
       oobwritelen -= len;
+#endif
     }
 
     ret = chip->write_page(mtd, chip, wbuf, page, cached,
@@ -2058,7 +2070,7 @@ static int nand_write(struct mtd_info *mtd, loff_t to, size_t len,

解决了问题:
Page 00e00000 dump:
OOB:
ff ff 00 10 00 00 01 00
00 00 00 00 00 00 ff ff
00 00 30 bf f2 bf 05 00
00 00 05 00 00 00 03 00
00 00 d0 bf f2 bf 03 00
aa 9a a7 a6 95 ab ff ff
ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff
[Ver130726-TINY210v2]# nand dump.oob e00800
Page 00e00800 dump:
OOB:
ff ff 00 10 00 00 01 01
00 00 00 00 00 00 ff ff
00 00 25 00 00 00 00 00
00 00 ff ff ff ff 00 00
00 00 34 bf f2 bf 01 00
fc 0c 03 f3 30 ff ff ff
ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff
[Ver130726-TINY210v2]# nand dump.oob e01000
Page 00e01000 dump:
OOB:
ff ff 00 10 00 00 01 01
00 00 01 00 00 00 47 00
00 00 03 bb f2 bf 08 00
00 00 08 00 00 00 a8 bf
f2 bf 01 00 00 00 05 00
95 9a a7 ff ff ff ff ff
ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff ff
[Ver130726-TINY210v2]#

这样问题就解决了。也印证了
最后的改动是小的,但是定位到这个问题的所在才是关键的
这样就可以然后上边的参考文档在mlc中启动挂载文件系统了。
下期报料,下期要实现的是不关闭内核的硬件ECC 就能从NandFlash挂载文件系统。老手说重点在driver/mtd/nand/nand_base.c中的nand_fill_oob中的MTD_OOB_AUTO中的实现。先报料到这里。

关于Yaffs2在u-boot中的支持的更多相关文章

  1. Spring Boot 中如何支持异步方法

    本人免费整理了Java高级资料,涵盖了Java.Redis.MongoDB.MySQL.Zookeeper.Spring Cloud.Dubbo高并发分布式等教程,一共30G,需要自己领取.传送门:h ...

  2. Spring Boot中如何扩展XML请求和响应的支持

    在之前的所有Spring Boot教程中,我们都只提到和用到了针对HTML和JSON格式的请求与响应处理.那么对于XML格式的请求要如何快速的在Controller中包装成对象,以及如何以XML的格式 ...

  3. Spring Boot中扩展XML请求和响应的支持

    在Spring Boot中,我们大多时候都只提到和用到了针对HTML和JSON格式的请求与响应处理.那么对于XML格式的请求要如何快速的在Controller中包装成对象,以及如何以XML的格式返回一 ...

  4. Spring Boot中使用EhCache实现缓存支持

     SpringBoot提供数据缓存功能的支持,提供了一系列的自动化配置,使我们可以非常方便的使用缓存.,相信非常多人已经用过cache了.因为数据库的IO瓶颈.一般情况下我们都会引入非常多的缓存策略, ...

  5. 【原】spring boot source 1.5 中不支持 diamond 运算符

    最近要开发新的项目,就花了几天时间看了下spring boot的相关资料,然后做了一个demo,不得不说开发效率确实很快,几行注解就完成了事务,aop,数据库等相关配置:但由于先前习惯了spring ...

  6. Spring Boot中的缓存支持(一)注解配置与EhCache使用

    Spring Boot中的缓存支持(一)注解配置与EhCache使用 随着时间的积累,应用的使用用户不断增加,数据规模也越来越大,往往数据库查询操作会成为影响用户使用体验的瓶颈,此时使用缓存往往是解决 ...

  7. spring boot(三):Spring Boot中Redis的使用

    spring boot对常用的数据库支持外,对nosql 数据库也进行了封装自动化. redis介绍 Redis是目前业界使用最广泛的内存数据存储.相比memcached,Redis支持更丰富的数据结 ...

  8. maven编译报错 -source 1.5 中不支持 lambda 表达式

    在用maven编译项目是由于项目中用了jdk 1.8, 编译是报错  -source 1.5 中不支持 lambda 表达式,Google找到这篇解决方案,记录一下: 编译时报如下错误: [ERROR ...

  9. 在Spring Boot中使用Https

    本文介绍如何在Spring Boot中,使用Https提供服务,并将Http请求自动重定向到Https. Https证书 巧妇难为无米之炊,开始的开始,要先取得Https证书.你可以向证书机构申请证书 ...

  10. springboot(十一):Spring boot中mongodb的使用

    mongodb是最早热门非关系数据库的之一,使用也比较普遍,一般会用做离线数据分析来使用,放到内网的居多.由于很多公司使用了云服务,服务器默认都开放了外网地址,导致前一阵子大批 MongoDB 因配置 ...

随机推荐

  1. windows core audio apis

    这个播放流程有一次当初不是很理解,做个记录,代码中的中文部分,原文档是有解释的:To move a stream of rendering data through the endpoint buff ...

  2. js时间戳转为日期格式

    转自:http://wyoojune.blog.163.com/blog/static/57093325201131193650725/ 这个在php+mssql(日期类型为datetime)+aja ...

  3. jsp注释方式

    1,HTML的注释方法 <!--...add your comments here...--> 说明:使用该注释方法,其中的注释内容在客户端浏览中是看不见的.但是查看源代码时,客户是可以看 ...

  4. JQuery树形目录制作

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DT ...

  5. pycharm常用快捷键与设置

    pycharm高频率使用的快捷键 Ctrl+Shift+F10 运行当前的页面 Ctrl + / 注释(取消注释)选择的行 Ctrl+Shift+F 高级查找 Shift + Enter 开始新行 T ...

  6. import uno 错误

    安装aeroolib 模块后,提示没有 uno 相关段一些模块, 原因是这些模块是 openoffice 中段,需要先安装 openoffice. 1:清除所有 libreoffice 软件,  su ...

  7. HDU 1207

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1207 四柱汉诺塔问题 当 r = (sqrt(8*n+1)-1)/2 时, 存在 count = (n ...

  8. DevOps - Development And Operations

    简介: 研发运维一体化 相关资料: 关于DevOps你必须知道的11件事 我眼中的DevOps DevOps 门户 docker for dotnet系列 docker4dotnet #1 前世今生 ...

  9. codevs 1078 最小生成树

    题目描述 Description 农民约翰被选为他们镇的镇长!他其中一个竞选承诺就是在镇上建立起互联网,并连接到所有的农场.当然,他需要你的帮助. 约翰已经给他的农场安排了一条高速的网络线路,他想把这 ...

  10. 终端上设置git

    http://blog.163.com/xianfuying@126/blog/static/21960005201181482518631/ 在-/.ssh的位置vi id_rsa.pub 拷贝的时 ...