Next: , Previous: Flash Commands, Up: Top


14 NAND Flash Commands

Compared to NOR or SPI flash, NAND devices are inexpensive and high density. Today's NAND chips, and multi-chip modules, commonly hold multiple GigaBytes of data.

NAND chips consist of a number of “erase blocks” of a given size (such as 128 KBytes), each of which is divided into a number of pages (of perhaps 512 or 2048 bytes each). Each page of a NAND flash has an “out of band” (OOB) area to hold Error Correcting Code (ECC) and other metadata, usually 16 bytes of OOB for every 512 bytes of page data.

One key characteristic of NAND flash is that its error rate is higher than that of NOR flash. In normal operation, that ECC is used to correct and detect errors. However, NAND blocks can also wear out and become unusable; those blocks are then marked "bad". NAND chips are even shipped from the manufacturer with a few bad blocks. The highest density chips use a technology (MLC) that wears out more quickly, so ECC support is increasingly important as a way to detect blocks that have begun to fail, and help to preserve data integrity with techniques such as wear leveling.

Software is used to manage the ECC. Some controllers don't support ECC directly; in those cases, software ECC is used. Other controllers speed up the ECC calculations with hardware. Single-bit error correction hardware is routine. Controllers geared for newer MLC chips may correct 4 or more errors for every 512 bytes of data.

You will need to make sure that any data you write using OpenOCD includes the apppropriate kind of ECC. For example, that may mean passing the oob_softecc flag when writing NAND data, or ensuring that the correct hardware ECC mode is used.

The basic steps for using NAND devices include:

  1. Declare via the command nand device
    Do this in a board-specific configuration file, passing parameters as needed by the controller.
  2. Configure each device using nand probe.
    Do this only after the associated target is set up, such as in its reset-init script or in procures defined to access that device.
  3. Operate on the flash via nand subcommand
    Often commands to manipulate the flash are typed by a human, or run via a script in some automated way. Common task include writing a boot loader, operating system, or other data needed to initialize or de-brick a board.

NOTE: At the time this text was written, the largest NAND flash fully supported by OpenOCD is 2 GiBytes (16 GiBits). This is because the variables used to hold offsets and lengths are only 32 bits wide. (Larger chips may work in some cases, unless an offset or length is larger than 0xffffffff, the largest 32-bit unsigned integer.) Some larger devices will work, since they are actually multi-chip modules with two smaller chips and individual chipselect lines.

14.1 NAND Configuration Commands

NAND chips must be declared in configuration scripts, plus some additional configuration that's done after OpenOCD has initialized.

— Config Command: nand device controller target [configparams...]

Declares a NAND device, which can be read and written to after it has been configured through nand probe. In OpenOCD, devices are single chips; this is unlike some operating systems, which may manage multiple chips as if they were a single (larger) device. In some cases, configuring a device will activate extra commands; see the controller-specific documentation.

NOTE: This command is not available after OpenOCD initialization has completed. Use it in board specific configuration files, not interactively.

— Command: nand list

Prints a one-line summary of each device declared using nand device, numbered from zero. Note that un-probed devices show no details.

— Command: nand probe num

Probes the specified device to determine key characteristics like its page and block sizes, and how many blocks it has. The num parameter is the value shown by nand list. You must (successfully) probe a device before you can use it with most other NAND commands.

14.2 Erasing, Reading, Writing to NAND Flash

— Command: nand dump num filename offset length [oob_option]

Reads binary data from the NAND device and writes it to the file, starting at the specified offset. The num parameter is the value shown by nand list.

Use a complete path name for filename, so you don't depend on the directory used to start the OpenOCD server.

The offset and length must be exact multiples of the device's page size. They describe a data region; the OOB data associated with each such page may also be accessed.

NOTE: At the time this text was written, no error correction was done on the data that's read, unless raw access was disabled and the underlying NAND controller driver had a read_page method which handled that error correction.

By default, only page data is saved to the specified file. Use an oob_option parameter to save OOB data:

— Command: nand erase num offset length

Erases blocks on the specified NAND device, starting at the specified offset and continuing for length bytes. Both of those values must be exact multiples of the device's block size, and the region they specify must fit entirely in the chip. The num parameter is the value shown by nand list.

NOTE: This command will try to erase bad blocks, when told to do so, which will probably invalidate the manufacturer's bad block marker. For the remainder of the current server session, nand info will still report that the block “is” bad.

— Command: nand write num filename offset [option...]

Writes binary data from the file into the specified NAND device, starting at the specified offset. Those pages should already have been erased; you can't change zero bits to one bits. The num parameter is the value shown by nand list.

Use a complete path name for filename, so you don't depend on the directory used to start the OpenOCD server.

The offset must be an exact multiple of the device's page size. All data in the file will be written, assuming it doesn't run past the end of the device. Only full pages are written, and any extra space in the last page will be filled with 0xff bytes. (That includes OOB data, if that's being written.)

NOTE: At the time this text was written, bad blocks are ignored. That is, this routine will not skip bad blocks, but will instead try to write them. This can cause problems.

Provide at most one option parameter. With some NAND drivers, the meanings of these parameters may change if nand raw_access was used to disable hardware ECC.

14.3 Other NAND commands

— Command: nand check_bad_blocks [offset length]

Checks for manufacturer bad block markers on the specified NAND device. If no parameters are provided, checks the whole device; otherwise, starts at the specified offset and continues for length bytes. Both of those values must be exact multiples of the device's block size, and the region they specify must fit entirely in the chip. The num parameter is the value shown by nand list.

NOTE: Before using this command you should force raw access with nand raw_access enable to ensure that the underlying driver will not try to apply hardware ECC.

— Command: nand info num

The num parameter is the value shown by nand list. This prints the one-line summary from "nand list", plus for devices which have been probed this also prints any known status for each block.

— Command: nand raw_access num (enable|disable)

Sets or clears an flag affecting how page I/O is done. The num parameter is the value shown by nand list.

This flag is cleared (disabled) by default, but changing that value won't affect all NAND devices. The key factor is whether the underlying driver provides read_page or write_page methods. If it doesn't provide those methods, the setting of this flag is irrelevant; all access is effectively “raw”.

When those methods exist, they are normally used when reading data (nand dump or reading bad block markers) or writing it (nand write). However, enabling raw access (setting the flag) prevents use of those methods, bypassing hardware ECC logic. This can be a dangerous option, since writing blocks with the wrong ECC data can cause them to be marked as bad.

14.4 NAND Drivers, Options, and Commands

As noted above, the nand device command allows driver-specific options and behaviors. Some controllers also activate controller-specific commands.

— NAND Driver: davinci

This driver handles the NAND controllers found on DaVinci family chips from Texas Instruments. It takes three extra parameters: address of the NAND chip; hardware ECC mode to use (hwecc1, hwecc4, hwecc4_infix); address of the AEMIF controller on this processor.

          nand device davinci dm355.arm 0x02000000 hwecc4 0x01e10000

All DaVinci processors support the single-bit ECC hardware, and newer ones also support the four-bit ECC hardware. The write_page and read_page methods are used to implement those ECC modes, unless they are disabled using the nand raw_access command.

— NAND Driver: lpc3180

These controllers require an extra nand device parameter: the clock rate used by the controller.

— Command: lpc3180 select num [mlc|slc]

Configures use of the MLC or SLC controller mode. MLC implies use of hardware ECC. The num parameter is the value shown by nand list.

At this writing, this driver includes write_page and read_page methods. Using nand raw_access to disable those methods will prevent use of hardware ECC in the MLC controller mode, but won't change SLC behavior.

— NAND Driver: orion

These controllers require an extra nand device parameter: the address of the controller.

          nand device orion 0xd8000000

These controllers don't define any specialized commands. At this writing, their drivers don't include write_page or read_page methods, so nand raw_access won't change any behavior.

— NAND Driver: s3c2410
— NAND Driver: s3c2412
— NAND Driver: s3c2440
— NAND Driver: s3c2443

These S3C24xx family controllers don't have any special nand device options, and don't define any specialized commands. At this writing, their drivers don't include write_page or read_page methods, so nand raw_access won't change any behavior.