kangear / tiny210v2-uboot

u-boot for tiny210v2 (NandFlash:K9GAG08U0F)
Other
17 stars 27 forks source link

关于BL1实现的16bit的ECC校验的讨论 #4

Open kangear opened 11 years ago

kangear commented 11 years ago

1.关于16bit ECC的实现这里有分析:http://www.arm9home.net/read.php?tid-80271-fpage-0-toread--page-1.html 2.感谢网友mhjong发现的BL1代码Bug (原文在这里:http://www.arm9home.net/read.php?tid=80271&page=3#245756) 楼主说oob区翻转会导致出现错误的校正,这与我做的测试不符。 也和手册里的描述不符: The parity codes have self-correctable information including parity code itself.

大致看了下楼主的代码,发现了问题所在。

手册中对翻转位置寄存器的描述如下 MLC ECC Error Byte Location Status Register (NFECCERL0~7, R, Address = 0xB0E2_00C0 ~ 0xB0E2_00DC) ErrByteLoc1 [9:0] Error byte location of 1st bit error 0x000

可以看到手册里描述的 ErrByteLoc 长度是10位,也就是Mask应该是0x3FF, 而楼主代码中用的mask为0x1FF。 这会有什么问题呢?

这个ECC引擎,不仅用来纠正数据错误,也用来纠正ECC错误,如果ECC本身发生翻转,ErrByteLoc 就会指向出错的ECC字节。 楼主用的这个MASK,屏蔽掉了最高1位,当数据长度为512时,导致把指向ECC的位置误认为指向数据的位置。 在ECC出错时错误地纠正了数据,这才出现了楼主描述的这种奇怪的现象。 ErrByteLoc | V 0 1 2 。。。 511 | ECC0 ECC1 。。。 ECCLast DATA ECC 3.我的回复: ErrByteLoc我仔细看了一下,确实应该是10位:

这个没有什么秘密,就是我算错了,算成了9位,悲哀。估计我最后得出那个“递增”的思想就不一定说的准了。估计也不需要递增了!就是没有修正完!

另外你说的“这个ECC引擎,不仅用来纠正数据错误,也用来纠正ECC错误”确实没有注意到,我还以为人工配置一下oob的ECC,才能保证ECC校验码不会出错。解开了我很多谜团。您是第一个用心分析源码的人,向您致敬! 根据你所说的,我可能在代码上要做如下纠正: 1.0x1ff 改为 0x3FF 2.去掉数组递增验证 3.友善的淡定码也有了新的理解,应该是用来标注坏块的。

kangear commented 11 years ago

纠正方案是有了,不过现在没有时间去更新这个Bug,先记录到这里,用空的时候再更新。

wb0330 commented 11 years ago

最后一条ecc是用来校验oob前32个字节的,不是标注坏块的

kangear commented 11 years ago

"最后一条ecc是用来校验oob前32个字节的"这个说法的依据是什么,我曾经做过实验,在改变了oob区的内容的时候,最后一个仍然不会变动的。

wb0330 commented 11 years ago

你在用superboot烧写kernel的时候,oob的前36个字节都是不变的,也改不了。在烧写yaffs2 rootfs的时候,0-3是保留的,其中一个用来标志坏块,第4-35这32个字节是保存的yaffs2的东西,第17条ecc就是校验这32个字节。具体看oob layout

kangear commented 11 years ago

明白了,启动代码"BL1"也可以加上这一条判断了。这样更安全了,做这个项目的时候真心体会到开源和合作的魅力了。kernel和yaffs的烧写都研究清楚了。了不起。