With JFFS2’s internals and image workflow covered, this lesson in our free Linux device drivers course turns to YAFFS2 — a filesystem built specifically for NAND flash, with a different set of design trade-offs than JFFS2, and a very different relationship with the mainline kernel.
What You Will Learn
Prerequisites
Before this lesson
Why YAFFS2 Exists
YAFFS was written specifically to target NAND flash chips at a time when JFFS2 — designed originally with NOR in mind — didn’t handle NAND’s larger page sizes and out-of-band metadata area well. The original YAFFS supported only 512-byte NAND pages; as NAND devices moved to 2 KiB and larger pages, the filesystem was revised into YAFFS2 to keep pace. It is, like JFFS2, a log-structured filesystem: writes are appended sequentially, and old versions of data become obsolete rather than being edited in place. The design decisions from there diverge in three notable ways.
How YAFFS2 Differs From JFFS2
| Aspect | JFFS2 | YAFFS2 |
|---|---|---|
| Target media | NOR and NAND | NAND only |
| Compression | Yes, by default | No |
| Mount-time scan | Full log replay (summary nodes help) | Faster, simpler scan by design |
| Garbage collection | More complex, node-granular | Simpler and faster |
| Storage efficiency | Better, due to compression | Lower, since nothing is compressed |
| Mainline kernel status | In-tree | Out-of-tree, requires patching |
| Portability | Linux-focused | Ported to multiple operating systems |
The net effect: YAFFS2 trades compression and some flexibility for faster, simpler mounting and garbage collection. That is a reasonable trade on devices with tight boot-time budgets and NAND-only storage, which is exactly the profile of many camera, set-top-box, and early smartphone designs that adopted it.
Licensing and Mainline Status
YAFFS2 ships under a dual license: GPLv2 for use with Linux, and a separate commercial license for use in non-Linux operating systems, reflecting its broader portability beyond Linux. What matters most for a Linux-focused build, though, is that YAFFS2 has never been merged into the mainline kernel tree. Using it means applying a patch to your kernel source and configuring it in, rather than simply selecting a Kconfig option that already exists upstream — a genuinely different workflow from the in-tree JFFS2 and UBIFS.
Patching a Kernel Tree for YAFFS2
Because YAFFS2 lives outside the mainline tree, getting it into a kernel build means cloning the project source and running its patch script against your kernel tree before configuring and building:
$ git clone git://www.aleph1.co.uk/yaffs2
$ cd yaffs2
$ ./patch-ker.sh c m <path to your kernel source>
Once patched, enable it in the kernel configuration with CONFIG_YAFFS_YAFFS2, then build and install the kernel as usual. This out-of-tree step is worth weighing against UBIFS, which needs no patching at all, when choosing a filesystem for a brand-new design.
Creating a YAFFS2 Filesystem
Formatting an MTD partition for YAFFS2 at runtime looks almost identical to JFFS2, with one important difference: no clean markers are involved, since YAFFS2 doesn’t use them the way JFFS2 does.
\# flash_erase /dev/mtd6 0 0
\# mount -t yaffs2 /dev/mtdblock6 /mnt
To build an offline image from a staging directory — the equivalent of mkfs.jffs2’s job — the community mkyaffs2 tool is the standard choice, taking the NAND page size and spare (out-of-band) area size as arguments:
$ mkyaffs2 -c 2048 -s 64 rootfs rootfs.yaffs2
Here -c 2048 specifies a 2 KiB page size and -s 64 a 64-byte spare area per page — values that must match the target NAND chip’s real geometry, exactly as the erase-block size had to match for mkfs.jffs2 in the previous lecture.
Build and Run: Comparing Mounted Filesystem Statistics
Rather than repeating any code from an old textbook, here is an original, small C utility that reports the statistics statvfs() exposes for any mounted filesystem — useful for comparing a JFFS2 mount against a YAFFS2 mount on the same class of hardware, or just for sanity-checking free space and block size after building a fresh image.
/* ep_fsstat.c - report statvfs() info for a mounted flash filesystem
* Build: gcc -O2 -o ep_fsstat ep_fsstat.c
* Run: ./ep_fsstat /mnt
*/
#include <stdio.h>
#include <sys/statvfs.h>
int main(int argc, char *argv[]) {
if (argc != 2) {
fprintf(stderr, "usage: %s \n", argv[0]);
return 1;
}
struct statvfs vfs;
if (statvfs(argv[1], &vfs) != 0) {
perror("statvfs");
return 1;
}
unsigned long total_kb = (vfs.f_blocks * vfs.f_frsize) / 1024;
unsigned long free_kb = (vfs.f_bfree * vfs.f_frsize) / 1024;
printf("Mountpoint : %s\n", argv[1]);
printf("Block size : %lu bytes\n", (unsigned long)vfs.f_frsize);
printf("Total capacity : %lu KB\n", total_kb);
printf("Free space : %lu KB\n", free_kb);
printf("Max filename len : %lu\n", (unsigned long)vfs.f_namemax);
return 0;
}
Expected output when pointed at a mounted JFFS2 or YAFFS2 partition:
$ gcc -O2 -o ep_fsstat ep_fsstat.c
$ ./ep_fsstat /mnt
Mountpoint : /mnt
Block size : 131072 bytes
Total capacity : 16384 KB
Free space : 15872 KB
Max filename len : 255
Running this against both a JFFS2 and a YAFFS2 mount on the same-size partition is a quick, hands-on way to see YAFFS2’s lack of compression show up directly as reduced usable capacity once real files are copied on.
When to Still Choose YAFFS2
For a brand-new design, UBIFS is usually the better default — better mount performance and no out-of-tree patch required. YAFFS2 remains a sensible choice when maintaining an existing product line already built around it, when working with a vendor BSP that ships YAFFS2 support out of the box, or when portability to a non-Linux OS under its commercial license is a genuine requirement.
Common Mistakes and Troubleshooting
Watch out for these
Best Practices, Performance, and Security
Performance: YAFFS2’s faster, simpler garbage collection and mount scan make it a reasonable fit for boot-time-sensitive NAND-only designs, at the cost of the storage efficiency compression would have provided.
Security: as with JFFS2, YAFFS2 has no built-in encryption — combine it with a block-level encryption layer if data at rest needs protection, and treat any patched, out-of-tree kernel module as part of your ongoing security update surface.
Summary and Key Takeaways
This closes out the flash filesystems block of this free Linux device drivers course. Together, the three lectures on JFFS2 design, JFFS2 image creation, and YAFFS2 fundamentals cover every raw-flash filesystem you are likely to meet outside of UBIFS itself.
Frequently Asked Questions
Can YAFFS2 be used on NOR flash?
No. YAFFS2 was designed specifically for NAND flash characteristics and does not target NOR the way JFFS2 does.
Why doesn’t YAFFS2 compress data like JFFS2 does?
It’s a deliberate trade-off favoring read/write speed and simpler garbage collection over storage efficiency; compression adds CPU overhead YAFFS2’s design chooses to avoid.
Is patching the kernel for YAFFS2 risky on a modern kernel version?
It can require manual fixups if the patch script predates your kernel version, since YAFFS2 is maintained out-of-tree and may lag behind the latest kernel internals.
How do I choose page and spare sizes for mkyaffs2?
They must match your target NAND chip’s real geometry exactly — check the chip’s datasheet, not a default value, since a mismatch produces an image that mounts but misreports capacity.
Is YAFFS2 or UBIFS the better choice today?
For a new design, UBIFS is usually preferred: it’s in-tree, needs no kernel patch, and generally mounts faster. YAFFS2 still makes sense for maintaining products already built around it.
Keep Learning Embedded Linux for Free
Continue this free Linux device drivers course with the next lecture on UBIFS and the UBI layer.
Next Lecture Browse Full Course
2 Comments