Choosing The Right Flash Filesystem-Best Embedded Linux Training Online

PREV_LEC | NEXT_LEC

Choosing The Right Flash Filesystem
A practical, no-nonsense guide to picking the correct filesystem for NOR, NAND, and eMMC storage in your embedded Linux project

If you’ve spent any time building embedded Linux systems, you already know that picking a filesystem is not a cosmetic decision — it decides whether your device survives ten years of power cuts in the field or bricks itself after the third one. This lecture is part of our free embedded Linux course, and it exists because most tutorials explain individual filesystems (JFFS2, UBIFS, ext4) in isolation without ever telling you how to actually choose between them for a real board. We’re going to fix that gap here, with a decision framework you can apply to any project, plus a small original tool that automates the first pass of that decision for you.

embedded Linux filesystem selection NAND vs NOR vs eMMC UBIFS squashfs tmpfs free linux device drivers course

What You Will Learn

  • How to classify your storage requirements into three categories before touching any filesystem
  • Which filesystems are viable on NOR, NAND, and eMMC-based boards, and why
  • When squashfs and UBI mtdblock emulation save you real flash space
  • Why tmpfs is the only sane choice for volatile data, and how much RAM it can quietly consume
  • How to build a small original script that inspects your board and recommends a filesystem, based on embedded Linux filesystem selection best practices

Prerequisites

  • Basic familiarity with MTD devices (/proc/mtd, mtdblock) — covered in earlier lectures of this storage course
  • A working embedded Linux target or QEMU setup with a mounted root filesystem
  • Comfort with basic shell scripting

Three Buckets, Not Twenty Filesystems

The mistake most beginners make is trying to memorize every embedded filesystem before deciding anything. That’s backwards. The right first step in any embedded Linux filesystem selection process is to sort your data into exactly three buckets, because the bucket — not the filesystem name — is what actually drives the decision.

Storage Requirement Buckets
[ Your Application Data ] | v +——————-+ +——————-+ +——————-+ | Permanent, R/W | | Permanent, RO | | Volatile | | configs, passwords,| | programs, libs, | | /tmp, caches, | | logs, user data | | rootfs contents | | scratch buffers | +——————-+ +——————-+ +——————-+ | | | v v v UBIFS / JFFS2 / squashfs (+ ro mount tmpfs ext4 / F2FS of any of the above)

Once your data is sorted, the filesystem choice nearly falls out on its own — you just need to know which options your physical storage medium supports.

Matching Filesystems To Physical Media

Raw flash (NOR and NAND) behaves nothing like a block device internally — it has erase blocks, bad blocks, and a limited number of program/erase cycles, which is why it needs a filesystem that understands flash directly, or a translation layer underneath a conventional one. eMMC and modern NAND-based storage often expose a Flash Translation Layer (FTL) in hardware, which is why they can happily run filesystems designed for spinning disks.

Physical MediumRecommended FilesystemsWhy
NOR flashUBIFS, JFFS2Both handle wear leveling and bad-block-free NOR natively; JFFS2 is simpler, UBIFS scales better on larger NOR devices
NAND flashUBIFS, JFFS2, YAFFS2UBIFS is the modern default; YAFFS2 remains common on legacy Android-derived boards; JFFS2 struggles as NAND capacity grows past a few hundred MB
eMMC / managed NANDext4, F2FSThe FTL inside the eMMC package already handles wear leveling and bad blocks, so a conventional block filesystem is appropriate; F2FS is tuned for flash erase-block alignment

Read-Only Root: The squashfs Shortcut

Any of the filesystems above can be mounted with the ro flag if your data is permanent and read-only — but that wastes space, because UBIFS and ext4 both carry journaling and metadata overhead your device will never use if nothing is ever written. squashfs is a purpose-built, heavily compressed, read-only filesystem that avoids all of that overhead, and on NAND it pairs naturally with UBI’s mtdblock emulation, which quietly absorbs bad-block remapping underneath it. For a root filesystem that never changes after manufacturing, squashfs is almost always the right call.

Volatile Data: There’s Only One Right Answer

For temporary storage like /tmp, scratch directories, or PID files, the book’s advice still holds today: use tmpfs. It lives entirely in RAM, costs zero flash write cycles, and disappears cleanly on reboot. The only caveat is that an unbounded tmpfs mount can exhaust your device’s RAM if a runaway process starts writing large files into it — always cap it with a size= mount option in production.

# Mount /tmp as tmpfs, capped at 32 MB, on a resource-constrained target
mount -t tmpfs -o size=32m,mode=1777 tmpfs /tmp

# Verify
mount | grep tmpfs
# tmpfs on /tmp type tmpfs (rw,relatime,size=32768k,mode=1777)

Original Tool: A Filesystem Advisor Script

Rather than repeating the book’s flowchart from memory every time you bring up a new board, here’s a small original helper — ep_fs_advisor.sh — that inspects the running target and prints a filesystem recommendation for each bucket. It’s deliberately simple so you can extend it for your own hardware.

#!/bin/sh
# ep_fs_advisor.sh - suggests a filesystem strategy based on detected storage
# Part of the EmbeddedPathashala free embedded Linux course

echo "== EP Storage Advisor =="

if [ -e /proc/mtd ] && grep -qi "nand" /proc/mtd 2>/dev/null; then
    echo "Detected: raw NAND flash"
    echo " -> Read-write data:  UBIFS (preferred) or JFFS2"
    echo " -> Read-only rootfs: squashfs over UBI mtdblock emulation"
elif [ -e /proc/mtd ]; then
    echo "Detected: raw NOR flash"
    echo " -> Read-write data:  UBIFS or JFFS2"
    echo " -> Read-only rootfs: squashfs"
elif [ -e /dev/mmcblk0 ]; then
    echo "Detected: eMMC / managed NAND"
    echo " -> Read-write data:  ext4 or F2FS"
    echo " -> Read-only rootfs: squashfs (optional, saves space)"
else
    echo "No flash device detected on this run"
fi

echo " -> Volatile data (/tmp, /var/log): tmpfs, always size-capped"
$ chmod +x ep_fs_advisor.sh
$ ./ep_fs_advisor.sh
== EP Storage Advisor ==
Detected: raw NAND flash
 -> Read-write data:  UBIFS (preferred) or JFFS2
 -> Read-only rootfs: squashfs over UBI mtdblock emulation
 -> Volatile data (/tmp, /var/log): tmpfs, always size-capped

Real-World Use Case: An Industrial NAND Gateway

Consider a 512 MB NAND-based industrial gateway that logs sensor readings continuously. Using the bucket model: the bootloader and kernel live on a small UBIFS partition (permanent, rarely written), the application binaries and libraries sit on a squashfs partition (permanent, read-only, saves flash and boot time), sensor logs get written to a UBIFS partition mounted specifically for that purpose with wear-leveling in mind, and /var/log and /tmp are tmpfs so the thousands of daily log-rotation writes never touch flash at all. This single layout, built purely from the three-bucket model, is representative of the pattern used across most production NAND devices today.

Common Mistakes And Troubleshooting

  • Mounting ext4 directly on raw NAND/NOR — ext4 has no wear-leveling logic and no bad-block awareness; it will corrupt raw flash over time. Only use it on eMMC/managed media with a hardware FTL.
  • Forgetting to cap tmpfs size — an uncapped tmpfs can consume all available RAM and trigger the OOM killer under heavy logging.
  • Using JFFS2 on multi-gigabyte NAND — JFFS2’s mount-time scan becomes painfully slow as capacity grows; switch to UBIFS well before you hit that wall.
  • Skipping bad-block handling on raw NAND — always go through UBI/MTD layers; never write a generic block filesystem straight onto raw NAND.

Best Practices

  • Decide the three buckets before you decide any filesystem name.
  • Keep read-only content on squashfs whenever it never changes post-manufacture.
  • Always size-cap tmpfs mounts explicitly.
  • Re-evaluate JFFS2 vs UBIFS as your NAND capacity grows across product revisions.

Performance And Security Considerations

Read-only squashfs partitions also double as a security boundary — if an attacker can’t write to the root filesystem, a large class of persistence techniques simply doesn’t work. On the performance side, UBIFS’s write-back caching (covered in an earlier lecture) usually outperforms JFFS2 significantly on writes, at the cost of slightly higher RAM usage, which matters on very small targets.

Summary And Key Takeaways

  • Classify data first: permanent read-write, permanent read-only, or volatile.
  • NOR and NAND need flash-aware filesystems (UBIFS/JFFS2/YAFFS2); eMMC can use conventional ones (ext4/F2FS).
  • squashfs is almost always correct for a static, read-only root filesystem.
  • tmpfs is the only correct choice for volatile data — just cap it.

Conclusion

Filesystem selection stops being confusing the moment you stop asking “which filesystem is best” and start asking “which bucket does this data belong to, and what medium is it sitting on.” Apply that two-question framework consistently and you’ll make the right call on every future board, regardless of how unfamiliar the flash chip datasheet looks. In the next lecture in this free Linux kernel development course, we move from choosing a filesystem to actually updating it safely in the field.

FAQ

Can I use ext4 on raw NAND flash?

No — not directly. ext4 assumes a reliable block device with no bad blocks and no wear-leveling requirement, neither of which raw NAND provides on its own. Use UBIFS or JFFS2 on raw NAND instead, or put ext4 on top of a proper FTL such as eMMC.

Is squashfs read-only forever, or can it be updated?

squashfs itself is immutable once built — you can’t write into it. Updates are done by building a new squashfs image and swapping the partition or image at update time, which is exactly the atomic image update pattern covered in the next lecture.

Why not just use JFFS2 everywhere and skip the decision?

JFFS2 scans the entire partition at mount time to rebuild its in-memory index, and that scan time grows with capacity. On anything beyond a few hundred megabytes of NAND, mount times become unacceptable, which is exactly why UBIFS exists.

How do I know if my board has raw NAND or eMMC?

Check /proc/mtd — if it lists entries, you have raw flash exposed through MTD. If instead you see /dev/mmcblk0 or similar, you’re on eMMC/SD-style managed storage with its own FTL.

Does tmpfs survive a reboot?

No. tmpfs content lives entirely in RAM and is lost on every reboot or power cycle, which is exactly why it should never be used for anything you need to persist.

What’s the difference between UBIFS and plain UBI?

UBI is the volume-management layer that handles wear leveling and bad-block mapping on raw flash; UBIFS is the actual filesystem that runs on top of a UBI volume. You need both together on NAND/NOR.

Can I mix filesystem types on one board?

Yes, and it’s common — for example squashfs for the root filesystem, UBIFS for a writable data partition, and tmpfs for /tmp, all on the same NAND device using separate UBI volumes or MTD partitions.

Continue Your Free Embedded Linux Course

Next up: atomic firmware updates and A/B partition strategies for field-deployed devices.

Next Lecture Back To Course Index

PREV_LEC | NEXT_LEC

2 Comments

Leave a Reply

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