ECC configuration of NAND from Linux (MEMSETOOBSEL)
derosier at gmail.com
Fri Jan 12 18:41:58 PST 2018
On Fri, Jan 12, 2018 at 10:50 AM, Gudjon I. Gudjonsson
<gudjon at gudjon.org> wrote:
> > setting you'll have to erase the whole flash and then change the ECC
> > config in your DT or board file (note that not all drivers support
> > adjusting the ECC strength/step-size).
> I will have to accept that but can you please tell me how to change the
> ECC strength if my driver supports it? My plan is to use swupdate and
> update the system using an SD-card that is already installed but I could
> not find any reference to changing the ECC strength.
> I am using the Atmel SAMA5d36 CPU and Micron mt29F2G08abaeawp
> NAND flash.
I might be wrong, but I don't think there's any mechanism to change
the ECC strength on the fly with that processor and flash combination.
In order to do it, you have to adjust it in your device-tree. I went
through this in an upgrade scenario on a similar system a few years
ago and came to the conclusion that it wasn't viable. As a matter of
background, we had two spots on flash for the kernel (kernel-a,
kernel-b), and two for a rootfs that was a UBIFS (rootfs-a, rootfs-b).
Our upgrade procedure was to run on -a, and flash -b. Next time, run
on -b and flash on -a, etc... To do it, here's what would have had to
1. Change the ECC strength in the DT, which then gets appended to the
the kernel image. Which means when the new kernel boots the new ECC
takes effect and not before. Note that the kernel that is running is
using the whatever ECC it was set for.
2. Change our update script to _not_ write the ECC bits when it
flashes... this is critical.
3. Now, (assuming running on -a partitions), erase kernel-b, rootfs-b.
Then flash the new kernel and new rootfs to the -b partitions
_with_out_ ECC bits!
4. Reboot to -b partitions. Note that you're now running a kernel
supporting the new ECC layout, but without any ECC actually being
5. Now, erase and reflash -a with the same new kernel and rootfs
_with_ ECC bits.
6. Boot to -a. Now you're running with the new ECC layout and with ECC
actually being done.
I'm going from memory, so I might have missed a step or done something
out of order, but you get the point. Now, why all of the above? The
problem is the number of ECC bits that gets flashed is dependent on
the kernel running flashing it. So, having a kernel running 4 bits
trying to flash 8, doesn't work. The solution is by forcing all the
written ECC bits to 0xffs by turing off the ECC bits when flashing
with nandwrite. The kernel will read and ignore ECC, no matter the set
strength, if there's no ECC bits set. So, essentially, you have to
write the new stuff with the enhanced bits with no bits actually
written, in order to boot into it and then write it correctly a second
Additionally, you got to remember to include the boot-loaders, so
bootstrap+uboot also need to be changed, upgraded, etc. And, if
you've got a mix of versions out there, managing them and freely
allowing upgrades and downgrades becomes a headache too. It's easier
if you don't have to boot into the kernel+rootfs and choose an upgrade
process that leverages u-boot, but our system didn't work that way. I
also came up with a number of other options, but they're not worth
detailing here and they were also a pain and risky to implement.
Basically, it's a major pain and since we were already using the
recommended minimum for our MT29Fxxxxxx flash, we left it alone. And
honestly, we haven't had any significant problems with the flash that
could be attributed to ECC strength.
All that said - this was a few years ago, and on a 3.8 kernel, running
bootstrap and u-boot and running the rootfs directly out of flash on
UBIFS. And we were running our own software update program that wasn't
very sophisticated. So, your situation may be different and or there
might be more options available now on newer kernels.
Hopefully that story helps a bit.
Cal-Sierra Consulting LLC
More information about the linux-mtd