|
你遇到的各种问题,总结下来都是对NAND本身不熟,对NAND控制器不熟。有以下几点:
1. ECC 算法不符。
不同CPU的NAND控制器有不同的ECC算法,有些硬件不带ECC的,会使用软件ECC算法。
假定一个full page是刚erase过的,也就是包括oob区域都是ff。
假定此时开启了ECC,那么写入数据时(一个page,不含oob),那么NAND除了将这个page的数据写进去,还会对这个page的数据计算ecc校验码,并将其写入oob区域。
之后,要读取这个page的数据时,nand控制器会将两部分数据都读出来,通过ecc校验码检查page数据有没有出错,如果只有有限个(<=N)bit flip(位翻转),那么它可以将这个错误纠正。
不同的NAND控制器使用不同的ECC算法,因此对于相同数据,它们产生的ECC校验码也都不会相同。
如果你在A芯片上开启ECC后写进去了数据,在B芯片上也开启ECC并读取数据,那么就会出现ECC校验失败(翻转的bit太多),提示不可恢复的ECC错误。
针对你帖子里的描述:
AR9344是属于硬件自带ECC算法的。如果你替换上去的NAND原本使用的ECC算法跟AR9344自带的不同(与AR9344使用相同ECC算法的只有QCA9558,如果是ARM平台,那么99.99%不会相同),那么在breed/原厂uboot/固件mtd里面读取数据都会出现ECC错误。
跟你的机器时大小端序没有关系。
2. AR9344/QCA9558 的NAND控制器的特殊性。
这个NAND控制器有个奇葩的地方,就是会将每4个字节颠倒字节序后写进NAND,读取时也会改变字节序。这个毛病导致通过这个NAND控制器读取NAND的ONFI参数页时,都需要依次对每4个字节进行一次字节序转换。
我没见过有哪几家常用的NAND控制器会干这件事。
估计还是因为这个NAND控制器的IP core是Atheros买的,不是自己的,对接的时候没处理这个细节。
另外AR9344的NAND控制器极不稳定,时不时就不工作了。直到QCA9558这个问题才被修复。
针对AR9344的这个问题,驱动里面会不停对NAND控制器进行复位,对NAND芯片进行复位,以期它能重新正常工作。
因此你在操作NAND时出现读写速度突然变慢的情况,就是控制器出BUG了。
此外你接上TTL,观察机器从NAND启动时的log,就会发现BootROM一旦检测到NAND控制器出现BUG,就会对机器进行复位,重头再来。
这个现象很常见。我接手的两台WNDR3400v1都是相同的毛病,有时候能折腾1分钟才启动到kernel。
3. breed不是编程器软件。
breed的flash命令不支持RAW数据读写,因此你拿breed去读肯定是各种ECC错误。
4. 你如果真要这样做编程器,最好的方法就是读写都关闭ECC后再操作。
你帖子里的做法其实是将OOB留空,也就是关闭ECC后再写数据,OOB里面没有有效的ECC校验码。你这样的NAND拿到一个开了ECC的系统上去读,照样还是ECC错误。
解决方法是找到CPU的NAND控制器使用的ECC算法/或者厂商提供的ECC工具,对要写入的数据计算ECC校验码,并组合成一个包含page+oob的特殊格式的文件,通过写RAW数据+oob区的方式写入,这样才能实现你的目的,也就是写给另一个CPU用。
但是难点在于你很难获取到ECC算法。因为一个ECC算法如果能在相同大小的ECC校验码内纠正更多的位翻转,就说明这个ECC算法的纠错能力更强。强大的ECC算法都属于商业机密,厂商能给你一个编译好的ECC工具就不错了。
因此你这样折腾顶多就只能做成一个不支持ECC的原始编程器。
P.S.
我自己用MT7628的丰富的GPIO做过一个GPIO模拟NAND时序的NAND编程器,比AR9344稳定多了。
|
|