What are Programming NAND Flash Images in Linux-Embedded Linux Training In Hyderabad

Programming NAND Flash Images
Erasing, writing, and reading back kernel images on raw NAND from U-Boot
Free Embedded Linux Course
Chapter 3: Bootloaders
Lecture 17
free embedded systems course
free linux development course
free linux device drivers course
free linux kernel development course
u-boot nand flash

Plenty of embedded boards have no SD card slot at all — the kernel lives permanently in raw NAND flash soldered
onto the board. Getting an image there safely means more than a simple copy, because NAND has quirks that ordinary
storage doesn’t: it must be erased in blocks before it can be rewritten, and it can develop bad blocks over its
lifetime. This lecture in our free embedded Linux course covers U-Boot’s nand command
family and how to use it correctly.

What You Will Learn

  • Why NAND flash requires erase-before-write
  • Erasing, writing, and reading NAND regions from U-Boot
  • Where ECC fits into the write/read path
  • Planning a NAND partition layout for boot images
  • Recovering from a bad or interrupted NAND write

Prerequisites

This lecture assumes you already have a wrapped, verified kernel image sitting in RAM — either loaded via
fatload or tftp as covered in the previous lecture in this free linux kernel
development course
.

Why NAND Is Different

Unlike an SD card, which presents a clean block-device abstraction to whoever’s using it, raw NAND flash exposes
its physical quirks directly to the software talking to it. Two properties matter most for boot images:

  • Erase granularity — NAND can only be erased in large blocks (commonly 128KB-256KB), even though it can be programmed in much smaller pages. You cannot overwrite existing data directly; the containing block must be erased first.
  • Bit errors and bad blocks — NAND cells wear out and occasionally flip bits even on healthy blocks, so error-correcting code (ECC) is applied on every write and checked on every read, and blocks that fail permanently get marked bad and skipped.

Enabling ECC

Before writing anything meaningful, make sure hardware or software ECC is active — writing without it risks
silent corruption that only surfaces later as a boot failure:

U-Boot# nandecc hw

Most modern SoCs implement ECC in a hardware NAND controller, so hw is typically correct; older or
simpler controllers may require U-Boot’s software ECC implementation instead.

Erasing a Region

Erase takes an offset and a size, both interpreted in the NAND’s own address space, not the RAM address space:

U-Boot# nand erase 0x280000 0x600000

NAND erase: device 0 offset 0x280000, size 0x600000
Erasing at 0x860000 -- 100% complete.
OK

The size must be a multiple of the NAND’s erase block size, and both offset and size are typically given in hex.
It’s common practice to erase a region somewhat larger than the current image, leaving headroom for the image to
grow across future builds without needing a layout change.

Writing the Image

With the target region freshly erased, write the image already sitting in RAM out to NAND:

U-Boot# nand write ${ep_kernel_addr} 0x280000 0x600000

NAND write: device 0 offset 0x280000, size 0x600000
6291456 bytes written: OK

Note that the write size here is the full erased region, not just the actual image size — U-Boot pads the
remainder, which is one reason the earlier erase size should comfortably exceed the image’s actual byte count.

Reading It Back

To boot from this image later (or just to verify the write immediately), read it from NAND back into RAM:

U-Boot# nand read ${ep_kernel_addr} 0x280000 0x600000

NAND read: device 0 offset 0x280000, size 0x600000
6291456 bytes read: OK
U-Boot# iminfo ${ep_kernel_addr}

Running iminfo right after a NAND write-then-read cycle is the fastest way to confirm the image
survived the round trip intact, using the same header checksum mechanism covered in the mkimage lecture.

NAND Write/Read Cycle for a Boot Image
RAM (loaded image)
|
| nand erase 0x280000 0x600000
v
+——————————–+
| NAND flash region (erased) |
+——————————–+
|
| nand write <ram_addr> 0x280000 0x600000
v
+——————————–+
| NAND flash region (programmed) |
| [ECC computed per page] |
+——————————–+
|
| nand read <ram_addr> 0x280000 0x600000
v
RAM (verified via iminfo)

Planning a NAND Layout

A board’s NAND is normally divided into fixed regions at design time — one for U-Boot itself, one for its
environment (often duplicated, as covered in the environment variables lecture), one for the kernel image, and one
for the root filesystem. These offsets get baked into both the board’s U-Boot configuration and its Linux MTD
partition table, so the two must always agree:

Region Typical Purpose
0x000000 – 0x100000 U-Boot (SPL + proper)
0x100000 – 0x180000 Environment (primary + redundant copy)
0x280000 – 0x880000 Kernel / FIT image
0x880000 onward Root filesystem (UBIFS, JFFS2, or similar)

These offsets are illustrative — always confirm the actual layout from your board’s device tree or U-Boot config
rather than assuming.

Common Mistakes and Troubleshooting

Symptom Likely Cause Fix
“NAND write: attempt to write to bad block” warnings A block in the target range is factory-marked bad Expected behavior — U-Boot skips it automatically; don’t disable bad-block handling
iminfo checksum fails after read-back ECC not enabled, or write interrupted by power loss Confirm nandecc hw was set before writing; retry the full erase/write cycle
Erase fails partway through Erase size not block-aligned Round the erase size up to a multiple of the NAND erase block size
Board unbootable after a bad flash Old image partially overwritten, new image incomplete Recover via network/JTAG boot if available; always keep a known-good fallback path during bring-up

Best Practices

  • Never power-cycle a board mid-erase or mid-write — NAND operations are not safely interruptible.
  • Leave headroom in your erase size for image growth across builds.
  • Keep U-Boot itself and the environment in a separate, rarely-touched region from the kernel/rootfs you iterate on.
  • Always verify with iminfo immediately after writing, while the board is still up and easy to recover.

Performance Considerations

NAND erase is significantly slower than write, which is itself slower than read — a full chip erase can take
tens of seconds, so erasing only the region you actually need (rather than the whole device) matters for iteration
speed during development.

Summary and Key Takeaways

  • NAND requires erase-before-write, and erases operate on whole blocks, not arbitrary byte ranges.
  • nandecc hw, nand erase, nand write, and nand read form the core workflow.
  • Bad block handling is automatic but should never be disabled.
  • NAND layout must stay consistent between U-Boot’s configuration and Linux’s MTD partition table.

Conclusion

With a kernel image safely written to NAND and verified, everything is finally in place to actually start Linux.
The last lecture in this chapter of our free linux device drivers course covers the command that
does exactly that — bootm.

FAQ

Can I write directly to NAND without erasing first?

No, NAND cells can only transition from erased to programmed, not back, so any region must be erased before it
can hold new data.

What happens if a block is marked bad?

U-Boot’s NAND driver automatically skips bad blocks during erase, write, and read operations — this is expected
and does not indicate a failed operation.

Is software ECC as reliable as hardware ECC?

Software ECC works but is slower and typically corrects fewer bit errors per page than a dedicated hardware
controller, so hardware ECC is preferred whenever the SoC supports it.

Why does nand write report a size equal to the erased region, not the image size?

U-Boot writes the full requested byte range, padding beyond the actual image, which is why choosing an
appropriately sized (not oversized) erase region matters.

What’s the safest way to recover from a bad NAND flash mid-development?

Keep a network or JTAG-based recovery boot path available so you can re-flash without depending on the
partially-written NAND contents.

Continue the Free Embedded Linux Bootloader Course

 

Leave a Reply

Your email address will not be published. Required fields are marked *