In the previous lecture of this free embedded Linux course, we worked directly with the MTD character device. Now we’ll look at three practical tools built around it: the block-device emulation layer that lets you mount flash like a disk (with real caveats), a mechanism for capturing kernel crashes onto flash so they survive a reboot, and a way to test NAND-aware code without owning a single physical chip.
What You Will Learn
- Why the MTD block device (mtdblock) exists and where its limitations make it unsuitable for general filesystems
- The one filesystem scenario where mtdblock is actually the right tool
- How to configure the kernel to log oops and panic messages to a flash partition so they survive a reboot
- How the NAND simulator lets you exercise bad-block and bit-flip handling without real hardware
Prerequisites
- Comfortable with kernel configuration (
menuconfigor editing.configdirectly) - MTD character devices from the previous lecture in this free linux kernel development course
- Basic familiarity with reading kernel boot log messages (
dmesg)
The MTD Block Device: mtdblock
It’s tempting to think you can just wrap flash in a block device and mount any ordinary filesystem on it, the same way you would on a hard disk or SD card. The mtdblock driver does exactly that — it presents an MTD partition as a block device so you can format and mount it. The problem is what it deliberately doesn’t do.
mtdblock has no flash translation layer. It doesn’t remap around bad blocks on NAND, it performs no wear leveling, and it doesn’t reconcile the mismatch between small filesystem blocks and large flash erase blocks. Point an ordinary journaling filesystem at it on NAND flash and you’re one bad block away from silent corruption, with no wear leveling protecting the chip’s lifespan either.
There’s exactly one scenario where mtdblock earns its keep: mounting a read-only filesystem, such as Squashfs, on top of reliable NOR flash. Read-only means no wear leveling is needed because nothing is ever rewritten, and NOR’s low bad-block rate means the missing bad-block handling rarely matters in practice.
| Scenario | Use mtdblock? | Why |
|---|---|---|
| Read-only Squashfs on NOR | Yes | No writes, no wear leveling needed, NOR bad blocks are rare |
| Writable filesystem on NAND | No | No bad-block handling, no wear leveling — data loss risk |
| Writable filesystem on NOR | No | Still no wear leveling; use a flash-aware filesystem instead |
If you want a read-only filesystem specifically on NAND flash — where bad-block handling genuinely matters — the right layer is the UBI driver, which we’ll get to when we cover flash translation layers.
Logging Kernel Oops Messages to MTD
Kernel oops and panic messages are normally captured by logging daemons into an in-memory ring buffer or a log file. Both of those survive fine for a graceful shutdown, but embedded devices rarely fail gracefully — a crash that corrupts the filesystem, or a hard reset triggered by a watchdog, can wipe out exactly the log entry you needed to diagnose the failure.
The kernel solves this with an MTD-backed oops logger. Instead of relying on RAM or a filesystem write that might never complete, it writes oops and panic text directly into a dedicated MTD partition, treating it as a circular log buffer. Because the write happens as part of the crash path itself and lands on non-volatile flash, the message is still there after the next boot.
Enabling it takes two steps: turn on the kernel option that provides the MTD oops writer, and point the kernel console subsystem at the target partition through the boot command line, where the partition number identifies which MTD device to use.
# Kernel configuration (menuconfig path shown for reference)
Device Drivers --->
Memory Technology Device (MTD) support --->
[*] Log panic/oops to an MTD buffer
# Kernel command line addition (N = MTD device number for the log partition)
console=ttyMTD2 root=/dev/mtdblock0 rootfstype=squashfs
After a crash and reboot, you read the captured message back out with a plain dump of the log partition:
$ cat /dev/mtd2 | strings | tail -40
<4>[ 12.884install] Unable to handle kernel NULL pointer dereference
<4>[ 12.884601] Call trace:
<4>[ 12.884610] ep_demo_probe+0x44/0x120
<4>[ 12.884622] platform_probe+0x68/0xd0
That single dump can be the difference between reproducing a field failure in an afternoon and never seeing it again.
Simulating NAND Without Real Hardware
Bad blocks, bit flips, and other NAND failure modes are exactly the kind of thing you don’t want to wait around for in the lab — and you can’t reliably trigger them on demand on a real chip anyway. The kernel’s NAND simulator solves this by emulating a NAND chip entirely in system RAM, letting you configure it to inject bad blocks and bit errors on command so you can exercise your bad-block-handling and ECC code paths deterministically.
This is invaluable when you’re developing or debugging a NAND-aware filesystem or driver: you get repeatable, scriptable failure injection instead of hoping a real chip degrades in the right way during testing.
# Enable the NAND simulator in kernel config
Device Drivers --->
Memory Technology Device (MTD) support --->
NAND Device Support --->
[*] Support for NAND Flash / SmartMedia Simulator
# After boot, the simulated chip appears as a normal MTD device
$ ls /dev/mtd*
/dev/mtd0 /dev/mtd0ro
$ ep_mtdinfo /dev/mtd0
Device : /dev/mtd0
Total size : 33554432 bytes
Erase size : 131072 bytes
(ep_mtdinfo here is the small inspector tool we built in the previous lecture — the simulator behaves exactly like a real MTD device from user space, which is the whole point.)
Real-World Use Cases
- Shipping a read-only Squashfs recovery partition on NOR flash via mtdblock
- Enabling MTD oops logging on production boards so field crash reports include an actual kernel backtrace
- Using the NAND simulator in CI to regression-test a custom flash filesystem’s bad-block handling without physical hardware in the loop
Common Mistakes and Troubleshooting
- Mounting a writable filesystem on mtdblock over NAND — works fine in the lab, then corrupts silently in the field once the first bad block appears.
- Forgetting to size the oops partition — too small a partition means only the most recent crash survives; size it to hold several oops cycles.
- Expecting the NAND simulator’s data to persist across reboots — it lives in RAM, so it’s for testing behavior, not for persistent storage.
Best Practices
- Reserve mtdblock strictly for read-only images on reliable NOR flash
- Always pair a writable NAND filesystem with a real flash translation layer, never mtdblock
- Enable MTD oops logging on any board where field debugging access is limited
- Use the NAND simulator as part of automated testing for any code that has to survive real-world bad blocks
Summary and Key Takeaways
- mtdblock presents flash as a block device but provides no flash translation layer at all
- Its one safe use case is read-only filesystems on reliable NOR flash
- MTD oops logging writes crash data to non-volatile flash so it survives a reboot
- The NAND simulator lets you test bad-block and error-injection code paths without physical NAND hardware
Conclusion
mtdblock, oops logging, and the NAND simulator are three small, focused tools that solve very different problems — but each one only pays off when you understand exactly where its boundaries are. Use mtdblock outside a read-only NOR context and you’ve traded convenience for silent corruption. Next, we’ll finish the storage picture by looking at how MMC/eMMC storage is handled, and then dive into flash translation layers properly.
FAQ
Is it ever safe to use mtdblock on NAND flash?
Only for a strictly read-only filesystem, and even then NOR is the safer choice because NAND’s bad-block rate is much higher and mtdblock does nothing to handle it.
Why doesn’t mtdblock do wear leveling?
It was designed as a thin block-device shim over MTD, not a flash translation layer. Wear leveling and bad-block remapping are deliberately left to dedicated drivers like UBI.
What triggers the MTD oops logger to write?
Any kernel oops or panic, once the feature is enabled and the console is pointed at the correct MTD partition on the kernel command line.
Does the NAND simulator require physical flash hardware?
No — it emulates a NAND chip entirely using system RAM, which is exactly what makes it useful for repeatable testing.
Can I inject bad blocks on demand with the NAND simulator?
Yes, its configuration options let you simulate bad blocks and bit flips so you can exercise error-handling code paths deterministically.
Continue the Free Embedded Linux Course
Next: the MMC block driver and a deep dive into flash translation layers — sub-allocation, garbage collection, and wear leveling explained from first principles.
Next Lecture Browse Full Course
2 Comments