Dev.to · 9 min read

Choosing a Root Filesystem Format for Embedded Linux

Choosing a Root Filesystem Format for Embedded Linux

Your storage hardware narrows the choice first: raw NAND requires UBIFS on UBI; ext4 and f2fs are not candidates there. On managed flash such as eMMC, our default is a read-only squashfs root plus a writable data partition, which pairs cleanly with A/B updates and integrity verification. Choose a plain ext4 root instead when your product needs a writable root and your team values familiar recovery tooling over immutability. Every embedded Linux product ships a root filesystem, and its format is often chosen by default — the vendor BSP generated ext4, so the product ships ext4. It is a real decision with long-term consequences for updates, power-cut behaviour and flash wear. This article works through the root filesystem format decision for the four realistic candidates: ext4, f2fs, squashfs with overlayfs, and UBIFS. The context The root filesystem format decision arises early, usually when the build system asks for it — Yocto through IMAGE_FSTYPES, Buildroot through its Filesystem images menu. Both can generate all four formats, so the build system does not constrain you. Five forces do. Storage technology. Raw NAND attached through the kernel's MTD layer exposes eraseblocks that wear out and can go bad; the filesystem stack must manage wear levelling and bad blocks itself. Managed flash — eMMC, SD, UFS — hides all of that behind an internal controller (an FTL) and presents an ordinary block device. Block filesystems such as ext4, f2fs and squashfs require a block device; UBIFS requires UBI on MTD. The hardware choice between raw NAND and managed flash removes half the candidates before any software argument starts. Update strategy. With image-based A/B updates — the model we recommended in Choosing an A/B Update Layout for Your Product — the root filesystem is replaced as one complete image, so a read-only format fits naturally. Package-based updates on the device require a writable root. Power-cut behaviour. Embedded devices lose power without warning. A never-written root cannot be corrupted by an interrupted write; a writable root depends on journaling or log-structured recovery working every time. Write endurance. Flash cells tolerate a finite number of erase cycles; concentrating writes into a small partition and keeping the large root read-only extends device life. Integrity and security. Verified-boot chains extend most cleanly over an immutable root, for example with dm-verity, which we covered in dm-verity: How a Read-Only Rootfs Stays Verified. The options: four root filesystem formats ext4 — the writable default ext4 is the default filesystem of mainstream Linux distributions: journaled, mature, with universal tooling (mkfs.ext4, e2fsck, resize2fs) and decades of production history. For: writable root supports on-device package updates and quick field fixes; journaling gives sound crash recovery; tooling and team familiarity are unmatched. Against: a fully writable root allows configuration drift, so no two field units are provably identical; the whole root partition is exposed to power-cut and wear concerns; immutability must be enforced separately, typically by mounting the root read-only — a weaker guarantee than a structurally read-only format. f2fs — log-structured for managed flash f2fs (Flash-Friendly File System) is designed specifically for NAND-based storage behind an FTL — eMMC, SD, UFS and SSDs. Its log-structured layout writes sequentially, which matches how an FTL prefers to receive writes, and it supports transparent compression with lzo, lz4, zstd and lzo-rle. Mount options such as background_gc and discard tune its garbage collection against the device. For: write patterns aligned with FTL behaviour, which can reduce write amplification on write-heavy workloads; native compression; actively developed for exactly the storage class most products ship. Against: smaller field-recovery ecosystem than ext4; fewer engineers have operated it in production; its advantages show mainly under sustained writes, which a mostly-idle root partition never generates. squashfs + overlayfs — the immutable root squashfs is a compressed, strictly read-only filesystem supporting zlib, lz4, lzo, xz and zstd compression, with a default block size of 128 KiB. Because nothing can write to it, nothing can corrupt it. Writability comes from overlayfs: a writable upper directory on a separate partition is layered over the read-only squashfs lower layer, and the kernel presents the merged view — the overlayfs documentation states explicitly that the lower filesystem does not need to be writable. For: immune to corruption of the root itself; compression substantially reduces the flash space the root image occupies; every unit runs a byte-identical image, which makes field debugging reproducible; fits A/B updates and dm-verity directly. Against: updates must replace the whole image — there is no quick edit of one file on a failed unit in the field; state you forgot to redirect to the writable layer silently disappears on reboot; the two-layer mount adds early-boot complexity, usually an initramfs that selects the update slot and assembles the overlay before switching to the final root. EROFS, a newer read-only filesystem with per-inode compression (lz4, zstd and others) designed for immutable system images, is already supported by Yocto and worth evaluating for new designs; squashfs remains the widely deployed default today. UBIFS — the raw-NAND filesystem UBIFS does not run on block devices at all. It runs on UBI volumes, which sit on MTD devices — raw NAND or NOR flash. The UBI layer provides wear levelling and bad-block management; UBIFS above it keeps its index on the flash, so mounts are fast (unlike JFFS2), uses write-back for good write performance, and compresses data on the fly with lzo or zlib. For: on raw NAND it is the mature, designed-for-purpose option; wear levelling and bad-block handling are built into the stack; compression is built into the filesystem. Against: unusable on eMMC or SD; image creation (mkfs.ubifs plus ubinize) requires flash geometry parameters that must exactly match the device; A/B updates need two UBI volumes and careful sizing. The decision First, the hardware decides. If the product uses raw NAND on MTD, choose UBIFS on UBI. The block filesystems are not candidates there, UBIFS is the mature option for that storage class, and the rest of this section does not apply. On managed flash, our recommendation for a production device is a read-only squashfs root with a separate writable data partition, mounted either directly at the paths that need persistence or through overlayfs. This pairs with image-based A/B updates and extends naturally to dm-verity. For the writable data partition, ext4 is a sound default; choose f2fs there when profiling shows sustained heavy writes, such as continuous logging or a local database, because that is the workload where its log-structured design is justified. Choose a plain writable ext4 root instead when any of these hold: the product updates through packages rather than images; the device is internal or low-volume and field immutability matters less than convenience; or the team is early in its embedded Linux adoption and one familiar writable filesystem is operationally simpler. These are legitimate engineering positions — a writable ext4 root with disciplined configuration management has shipped in many successful products. Consequences Choosing the squashfs route locks the update strategy: you are committed to whole-image updates and to the partition layout that supports them, so make the two decisions together. It also forces an explicit inventory of device state — every file that must survive a reboot has to be deliberately placed on the writable partition. That is real up-front work, but it yields a factory-reset feature almost directly: erase the writable layer and the device returns to a known state. Choosing ext4 defers that work but accumulates it as risk: state spreads through the root filesystem over years of field updates, and reproducing a specific unit's behaviour in the lab becomes harder with each release. Choosing f2fs means budgeting time to learn its tuning and recovery tools. Choosing UBIFS ties your manufacturing and update tooling to flash geometry, so a NAND part change late in the programme touches more than the BSP. Whichever branch you take, the root filesystem format decision is also a training decision: an immutable-root design asks every developer to understand overlay semantics and image-based workflows. Our embedded Linux with Yocto training covers rootfs assembly and image types, and our earlier Yocto vs Buildroot comparison addresses the build-system half of the same decision. Key takeaways Storage hardware decides first: raw NAND on MTD means UBIFS on UBI; managed flash (eMMC/SD/UFS) means block filesystems. On managed flash, default to a read-only squashfs root plus a writable data partition; it aligns with A/B updates, dm-verity and flash endurance. Pick ext4 for the writable partition by default; pick f2fs there only when sustained heavy writes justify it. A plain ext4 root remains the right call for package-updated, low-volume or early-stage products — decide it consciously, not by BSP default. Frequently asked questions Can I use UBIFS on eMMC or an SD card? No. UBIFS runs only on UBI volumes, which exist on raw flash (MTD) devices. eMMC and SD cards contain an internal controller and present a block device, so they take block filesystems such as ext4, f2fs or squashfs. Is f2fs always better than ext4 on eMMC? No. f2fs's log-structured design matches FTL-based flash and can reduce write amplification under sustained writes, but ext4 has broader tooling and more production familiarity. Use f2fs for write-heavy data partitions; ext4 remains a sound default elsewhere. How does a device with a read-only squashfs root store data? Through a separate writable partition. It is either mounted directly at the paths that need persistence, or layered over the squashfs root with overlayfs, whose writable upper directory captures all changes while the lower squashfs layer stays read-only. Do Yocto and Buildroot support all four root filesystem formats? Yes. Yocto's IMAGE_FSTYPES variable accepts ext4, f2fs, squashfs variants, ubi and ubifs among many other types, and Buildroot's Filesystem images menu can generate ext2/3/4, squashfs, ubifs, f2fs and more. Further reading Squashfs — kernel documentation Overlay Filesystem — kernel documentation F2FS — kernel documentation UBIFS — kernel documentation EROFS — kernel documentation IMAGE_FSTYPES — Yocto Project reference manual The Buildroot user manual Originally published at techveda.live.

This is a summary aggregated from Dev.to. Read the complete article on the original site:

Read full article at Dev.to

More Startup & VC News