We’ve spent this free embedded linux course series looking at raw flash access, block emulation, and crash logging. Now we zoom out. First, a quick look at MMC/eMMC — flash storage that behaves like a normal disk because the wear leveling is hidden inside the chip. Then we get to the real destination: what a Flash Translation Layer actually has to do, and where in the software stack that job can live.
What You Will Learn
- How MMC/SD and eMMC storage is accessed on Linux, and why it looks like an ordinary disk
- The four core jobs a Flash Translation Layer (FTL) has to perform on raw flash
- The three places in the stack an FTL can live, and the tradeoffs of each
- Why “managed flash” trades visibility for simplicity
Prerequisites
- MTD character and block devices, covered earlier in this free linux device drivers course series
- Basic understanding of NAND bad blocks and erase-before-write behavior
The MMC Block Driver
MMC/SD cards and eMMC chips are handled very differently from raw NAND/NOR chips at the Linux level. They’re accessed through the mmcblk block driver, and from user space they behave like an ordinary disk: you partition them with fdisk or a similar tool exactly the way you would a hard drive, and any general-purpose filesystem mounts on them without special handling.
To talk to the card at all, you need a host controller driver matching the specific MMC/SD interface on your board — that’s part of your board support package, sitting underneath the generic mmcblk layer.
$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
mmcblk0 179:0 0 29.7G 0 disk
├─mmcblk0p1 179:1 0 256M 0 part /boot
└─mmcblk0p2 179:2 0 29.4G 0 part /
$ fdisk -l /dev/mmcblk0
Disk /dev/mmcblk0: 29.7 GiB, ...
Why does this feel so much simpler than raw NAND? Because the wear leveling, bad-block management, and garbage collection are all handled internally by the controller built into the eMMC/SD chip itself. From the kernel’s point of view, it’s just a disk. That simplicity is also exactly the tradeoff we’re about to unpack.
Why Flash Needs a Translation Layer at All
Whether it’s hidden inside an eMMC chip or implemented in the open by a Linux filesystem, every piece of flash storage needs something performing the same underlying job: reconciling how filesystems want to work with how flash physically works. That job is the Flash Translation Layer, or FTL, and it breaks down into four distinct responsibilities.
| FTL Responsibility | The Problem It Solves |
|---|---|
| Sub-allocation | Filesystems want small allocation units (traditionally 512 bytes); flash erase blocks are 128 KiB or larger, so erase blocks must be subdivided to avoid waste |
| Garbage collection | Sub-allocation leaves erase blocks holding a mix of live and stale data; a background process coalesces live data and frees whole blocks |
| Wear leveling | Each block tolerates a limited number of erase cycles; data must be moved around so no single block wears out early |
| Bad block handling | NAND blocks can be bad from the factory or go bad over time; the FTL must avoid them and remap around new failures |
There’s also a robustness angle that cuts across all four: embedded devices get powered off or reset without warning far more often than a desktop ever does, so whatever implements the FTL has to tolerate a mid-write power loss without corrupting the whole filesystem — usually by keeping a journal or transaction log.
Where the FTL Can Live
The four jobs above have to happen somewhere, but “somewhere” isn’t fixed — it can sit at any of three layers in the stack, and each choice has real consequences for visibility and control.
| Location | Example | Code Visibility | Tradeoff |
|---|---|---|---|
| In the filesystem | JFFS2, UBIFS | Open source, in-kernel | Full visibility, improves over time with the kernel |
| In the block device driver | UBI (which UBIFS sits on top of) | Open source, in-kernel | Handles translation below the filesystem layer |
| In the device controller | Managed flash — eMMC, most SD/microSD cards | Hidden, proprietary firmware | Simple to use, but unverifiable and can’t see which sectors the filesystem has deleted |
That last column matters more than it looks. When the FTL lives inside the filesystem or a kernel block driver, it’s part of the open-source kernel — you can read exactly how it works, and you benefit as it’s improved over time. When the FTL is buried inside a managed flash device’s firmware, none of that visibility exists. You also lose something more subtle: a controller-side FTL has no way to know which sectors belong to files the filesystem has already deleted, so it can end up preserving and shuffling around data that’s actually garbage — a gap that commands like TRIM exist specifically to close, though the underlying visibility problem never fully goes away.
If you’re building on managed flash — which is what MMC/eMMC effectively is — the practical takeaway is simple: you’re trusting the manufacturer’s firmware with jobs you can’t inspect, so choosing a reputable manufacturer isn’t optional, it’s the entire safety net.
Real-World Use Cases
- Choosing eMMC over raw NAND for a product where engineering time for flash management is scarce, accepting the visibility tradeoff
- Choosing raw NAND with UBIFS when you need an auditable, open FTL for a safety- or reliability-critical product
- Diagnosing a field device that’s wearing out early by checking whether wear leveling is actually happening at the layer you expect
Common Mistakes and Troubleshooting
- Assuming eMMC needs no wear consideration at all — the controller handles it, but heavy, poorly-batched writes can still shorten its life faster than expected.
- Expecting mtdblock (from the previous lecture) to behave like an FTL — it implements none of the four responsibilities above; don’t confuse “presents as a block device” with “has a translation layer.”
- Picking managed flash from an unverified source — since the FTL is opaque, a poor-quality controller can silently underperform on wear leveling with no way to audit it.
Best Practices
- Match your storage choice to how much visibility and control the project actually needs — don’t default to raw NAND out of habit if eMMC’s opacity is an acceptable tradeoff
- For raw NAND, prefer UBIFS/UBI so the FTL responsibilities are handled by well-tested, open kernel code
- Treat “which manufacturer” as a real engineering decision when committing to managed flash, not an afterthought
Summary and Key Takeaways
- MMC/eMMC storage looks like an ordinary disk to Linux because the FTL is hidden inside the chip’s controller
- Every FTL, wherever it lives, must handle sub-allocation, garbage collection, wear leveling, and bad block handling — plus stay robust against power loss
- An FTL can live in the filesystem, in a block driver, or in the device controller, and code visibility drops sharply as you move toward managed flash
- Choosing managed flash means choosing to trust a manufacturer’s firmware you cannot inspect
Conclusion
This closes out the conceptual foundation for flash storage on embedded Linux: raw MTD access, its block-device limitations, crash logging, MMC’s simplicity, and now the four jobs every flash translation layer has to do no matter where it lives. With this in hand, the next lectures on JFFS2, UBI/UBIFS, and other flash-aware filesystems will make a lot more sense, because you’ll already know exactly which problem each one is solving.
FAQ
Why does eMMC behave like a normal disk in Linux?
Because the wear leveling, bad-block management, and garbage collection are all handled internally by the eMMC controller’s firmware, so the kernel only ever sees a simple block device.
What are the four core jobs of a Flash Translation Layer?
Sub-allocation, garbage collection, wear leveling, and bad block handling, plus general robustness against unexpected power loss.
Where can a Flash Translation Layer live in the software stack?
In the filesystem itself (like JFFS2 or UBIFS), in a block device driver (like UBI), or inside the flash device’s own controller firmware, as with managed flash such as eMMC.
What’s the downside of managed flash with a built-in FTL?
The FTL code is hidden and unverifiable, and it can’t see which sectors the filesystem has already deleted, so you have to trust the manufacturer’s implementation.
Does mtdblock count as a Flash Translation Layer?
No — mtdblock only presents flash as a block device; it implements none of the four FTL responsibilities and should not be treated as one.
Continue the Free Embedded Linux Course
Next: flash-aware filesystems for NOR and NAND — JFFS2, YAFFS2, and UBIFS compared, and how each implements the FTL responsibilities covered here.
Next Lecture Browse Full Course
2 Comments