The problem with MLC NAND flash

Publish date: 2019-04-18
Tags: ntc-chip, NAND, ARM, SBC, Linux

In my efforts to get Slackware working on my CHIP, I came to the conclusion not to really bother with supporting the NAND flash that is included on the board. The reason for this is that the mainline Linux kernel does not support the MLC type NAND flash used by the CHIP. Initially, I did a lot of research to see how NTC had supported it on their kernels, hoping to patch the support back into the newer mainline kernel. In doing so, I learned why the UBIFS developers, which is the driver it used, dropped support for MLC NAND.

To understand why the NAND isn’t supported, you need to learn a little about how NAND flash works and some of its drawbacks. NAND type flash works by setting a charge on a transistor gate. Ideally this charge would be totally isolated and stay charged forever, but in the real world there is a slight current leakage which results in this charge fading over time. This is known as bit rot and means that eventually enough charge will leak out to change a 1 bit to a 0. Furthermore, the method used to read back data also affects it and can introduce corruption.

With MLC, or multi-level cell, NAND this issue is even more pronounced. In an MLC flash, rather than simply being on or off, multiple bits are represented by the charge. So for example, if we had an SLC, or single-level cell, 0 could be 0V and 1 could be anything above a threshold, maybe 0.5V up to a maximum, say 3.3V (yes, I know charge is not measured in volts). With a 2-bit MLC, we need four different thresholds, maybe something like:

Binary Number Voltage
00 0.00 - 0.82
01 0.83 - 1.65
10 1.66 - 2.48
11 2.49 - 3.30

What this means is it now takes less charge bleeding off before it affects our data and therefore it happens in a shorter time frame.

MLC does have benefits. The higher storage density means it is faster and much cheaper to produce than SLC type NAND. However, it is also more complicated to interface with and has more variation between devices in how this is done.

Most of the time we don’t care about any of this. NAND flash is very common and is used to make USB Flash drives, SD Cards, SSDs, and other solid state storage devices. One thing all of these have in common is that there is a storage controller chip contained that handles all of the interfacing to the NAND chip and presents itself to the OS as a block device like any other storage. Among other dutires, it uses error correction algorithms to recover your data when bit rot occurs. It reserves a portion of the memory for itself to use for recovery data.

The NAND on the NTC CHIP is simply a bare NAND flash device with no controller. This is where the UBIFS project comes in. Essentially, it is a software driver that uses your CPU to act as a controller for the NAND flash. They’ve done a good job with SLC type NAND which are much simpler to interface with. They initially supported MLC NAND as well, but it is much more complicated to interface with and has much more variation between vendors and devices in how it is done. Furthermore, good error correction algorithms are not easy to design. Commercial devices use proprietary algorithms to push the limits. All this means it takes a lot of developer time to support MLC NAND, which the UBIFS team simply doesn’t have. They removed the somewhat working MLC support completely as they didn’t feel they could guarantee its quality.

I doubt MLC support will ever make it back into UBIFS. Most devices now use SD Cards on the low end or eMMC/SSDs on the higher end for their storage which both include controllers that do the job of UBIFS and include those fancy error correcting algorithms. The return on investment of very limited open source developer time simply just isn’t there.

This probably all sounds terrible, but fortunately, there’s a workaround. The NTC team did a good job of bringing out I/O lines from the CPU to the headers, and the Allwinner A13/R8 includes the proper hardware support to interface with SD Cards. This means to add SD Card support, all we need to do is wire in an SD Card slot and enable the on-chip interface! We could also use a USB flash drive, but I greatly prefer to have the USB port open for other uses. As a bonus, modern SD cards and USB drives are also MUCH faster and larger than the NAND included with the chip, easier to work with on your PC, and easily replaceable when they fail.

Hopefully you’re convinced that the SD card is a good idea. In the next post, I’ll show you how to turn a Micro SD to SD adapter into a Micro SD card slot for your chip!

NTC CHIP with a Micro SD card slot made from an adapter