YAFFS: the NAND-specific flash file system - Introductory Article

Written by Charles Manning - Originally published at Linuxdevices.org Sept 20th 2002

PHB Summary

YAFFS stands for "yet another flash file system"(*). As far as I am aware, YAFFS is the only file system, under any operating system, that has been designed specifically for use with NAND flash. YAFFS is thus designed to work within the constraints of, and exploit the features of, NAND flash to maximise performance. YAFFS uses journaling, error correction and verification techniques tuned to the way NAND typically fails, to enhance robustness. The result is a file system that exploits low-cost NAND chips and is both fast and robust. YAFFS is highly portable and runs under Linux, ucLinux and Windows CE. YAFFS is an open source project.

Why NAND flash?

Embedded and mobile systems are increasingly using NAND flash for storage because it has various advantages over other storage technologies. As always though, life is a compromise and those advantages come with some limitations that need to be addressed to provide a robust flash file system. Hard disks are not a viable storage option for many embedded and handheld systems because they are too big, too fragile and use too much power. For some years now, people have been using common-old NOR flash for file system storage. JFFS and JFFS2 do an excellent job of this for Linux. For storage applications NOR flash is not that great because it is not very dense (ie. not much storage per chip), is costly and is slow to write. NAND flash, on the other hand, is low cost, dense and writes fast, but has other limitations. The most common consumer usage of NAND flash is on SmartMedia cards which are just NAND chips bonded to a carrier card. Consumer use of SmartMedia is driving down NAND prices while driving up densities. The standard SmartMedia file system is FAT based and is thus liable to corruptions due to power failures, crashes and other acts of demonic forces. This raises robustness concerns, particularly in embedded systems where a corrupted file system can kill the device. What's really needed is a journaling file system that is able to work around the limitations of NAND and exploit it for best performance.

History

The lead-up to YAFFS started with an investigation into modifying the JFFS2 flash file system to work with NAND flash (**) for some Aleph One customers. It seemed reasonable that the best way to get a file system for NAND flash would be just "tweaking" an existing flash file system. On deeper investigation, it became apparent that designing a new file system specifically for NAND might have some benefits.

NOR (typical, varies a lot)

NAND

Density

Up to 32MB chips

Currently 256MB and growing.

Cost per MB

$1-$2

25c

Access

Random

Page oriented with spare area on each page. Sequential access within a page.

Programmability

Can modify a single bit.

Very limited re-programming.

Read speed

50-100nS

10uS page "seek" + 50nS per byte

Program time

5uS per byte

200uS per page

Erasure time

1s per 64kB block

2ms per 16kB block

Reliability

Relatively immune to corruption. No bad blocks.

Needs error correction. Bad blocks marked when shipped.

Designing an effective flash file system is a difficult task and you need to jump through many hoops of fire to get a useful system. Although both are called "Flash", NOR and NAND flash have very different properties. Thus, a flash file system that works with NOR incorporates various mechanisms that are not required for NAND, and NAND needs extra mechanisms not required for NOR. For example, garbage collection performance is largely determined by the erasure time. NOR erases very slowly and thus an effective NOR garbage collection strategy is relatively complex and limits the design options. In comparison NAND erases very quickly; thus these limitations don't apply. Another major difference is that NAND is shipped with marked bad blocks on the device, while NOR chips are shipped defect free. Thus, one expects to encounter some failures in NAND and should design accordingly. This lead me to believe that it would be worth designing a file system specifically for NAND flash, exploiting the features of NAND to simplify the design and catering to NAND specific limitations directly, rather than trying to "bend" NAND to work with an existing file system architecture, or vice versa. The first conceptual design for YAFFS was drawn up in late December 2001. Once the customers bought in to the idea, things progressed rapidly. The first line of code was cut in January 2002. By May 2002 we had the first publicly available CVS code. We now have at least six different companies using or experimenting with YAFFS in embedded or handheld systems. YAFFS is already very stable and is converging rapidly. We expect to see YAFFS-based products shipped before the end of the year.

Design approach

Rather than develop and debug code inside the Linux kernel, I took the approach of developing the file system "guts" algorithms - the most complex part -- in a user space program. To achieve this, the code is split into four sections:
  • yaffs_guts: The file system algorithms. This code is fully portable C.

  • yaffs_fs.c: Interface layer to the Linux VFS. Can be replaced with a test harness for user space developing of yaffs_guts.c

  • nand interface: wrapper layer between yaffs_guts and the NAND memory access functions. eg. calls Linux mtd layer or RAM emulation layer.

  • Portability functions: wrapper functions for services such as memory allocation etc.

This modular design has provided a lot of flexibility for testing and development. A user space program and DDD is a far more rapid development environment than continually changing the Linux kernel. Also, a RAM-based NAND emulation layer provides an excellent way to debug the file system in-kernel without special hardware. A further spin-off has been that YAFFS is portable to other operating systems. For example, a port of YAFFS for Windows CE was readily achieved by writing a new wrapper layer to hook up to the WinCE file system manager and new NAND access layer. yaffs_guts.c remains 100% portable(***). YAFFS is thus likely to be easily portable to other OSs too.

Results

Removing surplus constraints has lead to a simpler design that has improved performance and robustness as well and reduced development time. YAFFS reads and writes pretty fast. There is no significant hit due to garbage collection (ie. in most situations garbage collection overheads would not impact usage). It is difficult to give meaningful benchmarks given non-standard hardware. However herewith some results achieved on a StrongARM-based board with 128MB of NAND flash. Write speed is approx 800kB per second and read speed is approx 1.5MB per second. In a weekend stress test I wrote, triple-verified then deleted 25gigabytes of file data without a single bit of file data being corrupted. 25GB exceeds the design lifetime of most embedded or handheld devices.

Future

Although YAFFS already performs well, there is still a lot of room for improvement. Development is continuing to enhance performance and robustness as well as add support software such as utilities, bootloader support and analysis tools. I expect to see ports to other OSs too. Increasing the user base of YAFFS is an important way to get more eyes over the code and test it under a wider set of scenarios. The YAFFS development community is growing well with good involvement from people all over the world. YAFFS is realising all the benefits open source projects hope for and will, we expect, continue to grow.

Resources

The YAFFS project home page is http://www.aleph1.co.uk/yaffs/ This provides further YAFFS documentation and instructions for GIT access and the YAFFS mailing list.

Footnotes:

(*)The YAFFS name came from the first concept document proposing yet another flash file system. Some how that name just stuck. (**) NAND support has since been added to JFFS2 by others. The YAFFS, JFFS2 and mtd communities cooperate to provide a rich flexible set of solutions to draw from. As is the nature of open source projects, JFFS2 code was used as a reference for some parts of the YAFFS development, particularly for figuring out the VFS interface. Google for further info on JFFS2 and mtd. (***) Some features were added to the guts to enhance WinCE usage. For example, the string comparison function was made configurable to be either strcmp or scricmp because Windows file names are case insensitive.

Bio

Charles Manning (aka The Embedded Janitor) lives near Christchurch, New Zealand, and has been developing and mopping up embedded systems for twenty years. His hobbies include fly tying and spinning wool. Charles can be reached at charles@aleph1.co.uk.