📄 yaffs (yet another flash file system).htm
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- saved from url=(0040)http://www.aleph1.co.uk/yaffs/yaffs.html -->
<HTML><HEAD><TITLE></TITLE>
<META content="text/html; charset=iso-8859-1" http-equiv=CONTENT-TYPE>
<META content="MSHTML 5.00.3700.6699" name=GENERATOR>
<META content=" " name=AUTHOR>
<META content=20011219;22024300 name=CREATED>
<META content=" " name=CHANGEDBY>
<META content=20020128;21063000 name=CHANGED></HEAD>
<BODY>
<H1 align=center>YAFFS (yet another Flash File System)</H1>
<H4 align=left>Version 0.3<BR>Charles Manning (and Wookey), December 2001</H4>
<P align=left><BR><BR></P>
<H2>Revision History</H2>
<TABLE border=1 cellPadding=4 cellSpacing=3 width=548>
<COLGROUP>
<COL width=88>
<COL width=72>
<COL width=350>
<THEAD>
<TR>
<TH vAlign=top width=88>
<P align=left style="FONT-STYLE: normal">V0.0</P></TH>
<TH vAlign=bottom width=72 SDNUM="5129;0;D/MM/YY" SDVAL="37245">
<P align=left style="FONT-STYLE: normal">20/12/01</P></TH>
<TH vAlign=top width=350>
<P align=left style="FONT-STYLE: normal">First draft</P></TH></TR></THEAD>
<TBODY>
<TR>
<TD vAlign=top width=88>
<P align=left style="FONT-STYLE: normal">V0.1</P></TD>
<TD vAlign=bottom width=72 SDNUM="5129;0;D/MM/YY" SDVAL="37267">
<P align=left style="FONT-STYLE: normal">11/01/02</P></TD>
<TD vAlign=top width=350>
<P align=left style="FONT-STYLE: normal">Minor corrections &
cosmetics.<BR>Change use of data status byte.</P></TD></TR>
<TR>
<TD vAlign=top width=88>
<P align=left style="FONT-STYLE: normal">V0.2</P></TD>
<TD vAlign=bottom width=72 SDNUM="5129;0;D/MM/YY" SDVAL="37284">
<P align=right style="FONT-STYLE: normal">28/01/02</P></TD>
<TD vAlign=top width=350>
<P align=left style="FONT-STYLE: normal">Added observations about inodes,
file headers and hard links.</P></TD></TR>
<TR>
<TD vAlign=top width=88>
<P align=left style="FONT-STYLE: normal">V0.3</P></TD>
<TD vAlign=bottom width=72 SDNUM="5129;0;D/MM/YY" SDVAL="37285">
<P align=right style="FONT-STYLE: normal">26/02/02</P></TD>
<TD vAlign=top width=350>
<P align=left style="FONT-STYLE: normal">W:Added some general observations
on compatibility, partitions and bootloading.</P></TD></TR></TBODY></TABLE>
<P align=left><BR><BR></P>
<H2>Scope</H2>
<P>The purpose of this document is to outline a potential NAND-friendly file
system for Linux.</P>
<H2>Background</H2>
<P>There are already various flash-file systems (FFSs) or block drivers for
flash (on top of which a regular FS runs). There are pros and cons with all of
these. </P>
<P>Flash memory has quite a few constraints which will not be addressed here.
Various approaches are available to work around these constraints to provide a
file system. It is important to recognise that "flash" includes both NOR and
NAND flash which have different sets of constraints. It is easy to be mislead by
the generic term "flash" into thinking that approaches appropriate for NOR flash
are immediately suitable for NAND flash.</P>
<P>The NAND block drivers (eg. SmartMedia [currently not available for Linux]
and DiskOnChip NFTL) typically use FAT16 as the file system. This isn't too
robust and nor is it that flash-friendly. These block drivers provide a logical
to physical mapping layer to emulate rewritable blocks that look like disk
sectors. When used with FAT16, these file systems work reasonably well. They
have a low memory footprint and scale well. Like all FAT based systems they are
prone to corruption ("lost clusters etc").</P>
<P>The other approach is to design an entire file system which does not work
through a block driver layer and is flash-friendly. This allows more scope to
work around issues.</P>
<P>Currently, two Linux file systems that support NOR flash very well are JFFS
and its derivative JFFS2. Both of these are based on the principles of
journaling (hence the leading J) which significantly increases robustness - a
particularly important feature in embedded systems. Unfortunately neither of
these file systems scale particularly well in both boot time and RAM usage.
Scaling is particularly relevant when one considers that a 16MB NOR array would
be considered large while a 128MB NAND is available as a single chip.</P>
<P>JFFS requires a RAM-based jffs_node structure for each journalling node in
the flash. Each of these nodes is 48 bytes. JFFS2 makes a significant
improvement here by reducing the equivalent structure (jffs2_raw_node_ref) to 16
bytes. Still, at say an average node-size of 512 bytes, a 128MB NAND might need
250000 of these ... 4MB!</P>
<P>Both JFFS and JFFS2 require scanning the flash array at boot time to find the
journaling nodes and determine the file structures. Since NAND is large, slow,
serially accessed and needs ECC this does not scale well and will take an
unacceptably long boot time for the target systems. As a thumb-suck, the
scanning of a 128MB NAND array might take approx 25 seconds.</P>
<P>The intentions of the design sketched here are:</P>
<UL>
<LI>
<P>Be NAND-flash friendly.</P>
<LI>
<P>Robustness through journaling strategies.</P>
<LI>
<P>Significantly reduce the RAM overheads and boot times associated with
JFFSx.</P></LI></UL>
<P>This FS is intended primarily for internal NAND rather than removable NAND
(SM cards). On removable SM cards Smartmedia compatibility is likely to be
important so SM/FAT will normally be used, although of course YAFFS makes a lot
of sense if reliability is more important than compatibility.</P>
<H2>Overview</H2>
<P>Here follows a simplified overview of YAFFS.</P>
<P>YAFFS uses a physical flash format similar to SmartMedia. This is done for
various reasons:</P>
<UL>
<LI>
<P>Some of the formatting, eg placement of bad block markers is determined by
the NAND manufacturers and can't be changed.</P>
<LI>
<P>Potential to reuse code.</P>
<LI>
<P>If it ain't broke don't fix.</P></LI></UL>
<P>Some of the fields are obviously different to reflect the different usage.
Despite the similarities YAFFS is not actually compatible with SM/FAT. SM cards
need to be reformatted to switch from using SM/FAT to YAFFS or vice versa.</P>
<P>File data is stored in fixed size "chunks" consistent with the size of a page
(ie. 512 bytes). Each page is marked with a file id and chunk number. These tags
are stored in the "spare data" region of the flash. The chunk number is
determined by dividing the file position by the chunk size.</P>
<P>When data in a file is overwritten, the relevant chunks are replaced by
writing new pages to flash containing the new data but the same tags. The
overwritten data is marked as "discarded". </P>
<P>File "headers" are stored as a single page, marked so as to be differentiated
from data pages.</P>
<P>Pages are also marked with a short (2 bit) serial number that increments each
time the page at this position is incremented. The reason for this is that if
power loss/crash/other act of demonic forces happens before the replaced page is
marked as discarded, it is possible to have two pages with the same tags. The
serial number is used to arbitrate.</P>
<P>A block containing only discarded pages (termed a <I>dirty block</I>) is an
obvious candidate for garbage collection. Otherwise valid pages can be copied
off a block thus rendering the whole block discarded and ready for garbage
collection.</P>
<P>In theory you don't need to hold the file structure in RAM... you could just
scan the whole flash looking for pages when you need them. In practice though
you'd want better file access times than that! The mechanism proposed here is to
have a list of __u16 page addresses associated with each file. Since there are
2<SUP>18</SUP> pages in a 128MB NAND, a __u16 is insufficient to uniquely
identify a page but is does identify a group of 4 pages - a small enough region
to search exhaustively. This mechanism is clearly expandable to larger NAND
devices - within reason. The RAM overhead with this approach is approx 2 bytes
per page - 512kB of RAM for a whole 128MB NAND.</P>
<P>Boot-time scanning to build the file structure lists should require just one
pass reading NAND. Since only the the spare data needs to be read, this should
be relatively fast ( approx 3 seconds for 128MB). Improvements can be achieved
by partitioning the NAND. ie. mount the critical partition first then mount the
data partition afterwards.</P>
<P>Various runtime improvements can be achieved by changing the "chunk size" to
1024 bytes or more. However this would likely reduce flash efficiency. As
always, life is a compromise....</P>
<P><BR><BR></P>
<H3>Spare area details</H3>
<P>The following table summarizes the layout of the spare area of each page.</P>
<TABLE border=1 cellPadding=4 cellSpacing=3 width=674>
<COLGROUP>
<COL width=96>
<COL width=249>
<COL width=291>
<THEAD>
<TR vAlign=top>
<TH width=96>
<P>Byte #</P></TH>
<TH width=249>
<P>SmartMedia usage</P></TH>
<TH width=291>
<P>YAFFS usage</P></TH></TR></THEAD>
<TBODY>
<TR vAlign=top>
<TD width=96>
<P>0..511</P></TD>
<TD width=249>
<P>Data</P></TD>
<TD width=291>
<P>Data. either file data or file header depending on tags</P></TD></TR>
<TR vAlign=top>
<TD width=96>
<P>512..515</P></TD>
<TD width=249>
<P>Reserved</P></TD>
<TD width=291>
<P>Tags</P></TD></TR>
<TR>
<TD vAlign=bottom width=96 SDNUM="5129;" SDVAL="516">
<P align=right>516</P></TD>
<TD vAlign=top width=249>
<P>Data status byte. Not used in SM code from Samsung</P></TD>
<TD vAlign=top width=291>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -