INSERT INTO `cache_render` VALUES ('entity_view:node:453:rss:[languages:language_interface]=en:[theme]=yaffs:[timezone]=Europe/London:[url.path.is_front]=is_front.0:[user.permissions]=aa7fc4c8fb40c7a8665ccd12fea07926dff0f59b9ee3346bc513c6399bee5b01','a:3:{s:7:\"#markup\";O:25:\"Drupal\\Core\\Render\\Markup\":1:{s:9:\"\0*\0string\";s:145727:\"<span>Yaffs Direct Interface</span>\n<span><span lang=\"\" about=\"/user/admin\" typeof=\"schema:Person\" property=\"schema:name\" datatype=\"\">Admin</span></span>\n<span>23 July, 2012 - 12:37am</span>\n\n      <div class=\"field field--name-upload field--type-file field--label-hidden field--items\">\n              <div class=\"field--item\"><span class=\"file file--mime-application-pdf file--application-pdf icon-before\"><span class=\"file-icon\"><span class=\"icon glyphicon glyphicon-file text-primary\" aria-hidden=\"true\"></span></span><span class=\"file-link\"><a href=\"https://yaffs.net/sites/default/files/downloads/YaffsDirect.pdf\" type=\"application/pdf; length=256079\" title=\"Open file in new window\" target=\"_blank\" data-toggle=\"tooltip\" data-placement=\"bottom\">YaffsDirect.pdf</a></span><span class=\"file-size\">250.08 KB</span></span></div>\n          </div>\n  \n            <div class=\"field field--name-body field--type-text-with-summary field--label-hidden field--item\">\n<p>This document describes the Yaffs Direct Interface (YDI), which allows Yaffs to be simply integrated with embedded systems, with or without an RTOS.</p>\n<p style=\"page-break-before: always\"><br />\n<br />\n</p>\n<h1 class=\"western\" style=\"page-break-before: always\">1 Background</h1>\n<p>The purpose of this document is to describe the interfacing of the Yaffs Direct Interface (YDI) as well as to provide sufficient information to allow a preliminary evaluation of Yaffs. This document tries to focus on the issues important to the system integrator without getting too detailed about how Yaffs works. Other documents provide an in-depth discussion of how Yaffs works.</p>\n<h1 class=\"western\">2 Licensing</h1>\n<p>Yaffs was originally released for Linux under the GNU Public License (GPL). Various embedded developers soon identified that Yaffs would be ideal for their applications, but were not able to use GPL based code in their systems. Aleph One <span style=\"font-style: normal\"><span style=\"font-weight: normal\">has</span></span> alternative licensing arrangements to support such applications.</p>\n<h1 class=\"western\">3 What are Yaffs and Yaffs Direct Interface?</h1>\n<p>Yaffs stands for <i>Yet Another Flash File System</i>. Yaffs was the first file system designed, from the ground up, for NAND storage.</p>\n<p>In 2002 Aleph One set out to identify file system options for using NAND Flash as a file system. Various file systems available at the time were evaluated and all were found lacking in one way or another. The need for a suitable NAND storage file system was identified and Yaffs was designed to fill that need.</p>\n<p>Although Yaffs was originally designed for NAND flash, it has been used successfully with NOR flash systems and even as a RAM file system. This allows high reliability file systems to be constructed using NOR flash, with a future migration path <span style=\"font-weight: normal\">to NAND</span> flash for higher density and performance.</p>\n<p>Yaffs was originally designed for use with the Linux operating system, but was designed in a very modular way. The operating-system-specific code was kept separate from the main Yaffs file system code. This allows Yaffs to be ported quite cleanly to other operating systems through operating system personality modules. One such personality module is the Yaffs Direct Interface (YDI) which allows Yaffs to be simply integrated with embedded systems, with or without an RTOS. </p>\n<p>Yaffs has been used for many products using various operating systems including Windows CE and various RTOSs, including <span style=\"font-weight: normal\">ThreadX, vXworks, pSOS to name just a few.</span></p>\n<p>Note that there is a native port of Yaffs to eCOS that does not use YDI. This is supported and distributed by eCocCentric.(http://www.ecoscentric.com/).</p>\n<p>Yaffs2, a more recent release of Yaffs, supports a wider range of NAND flash components including 2k page devices and devices with multi-level cells (MLC), and produces equivalent or better performance. It include Yaffs1 compatibility code so Yaffs1 images still work and migration is quite simple. Yaffs1 or Yaffs2 mode of operation are simply selected by a run-time parameter.</p>\n<p>As well as providing a NAND file system, YDI also provides a RAM emulation layer to allow Yaffs to operate as a RAM file system too. While the RAM emulation is perhaps not as efficient as a dedicated RAM file system, this does allow one well proven file system to use both RAM and flash.</p>\n<h1 class=\"western\">4 Why use Yaffs?</h1>\n<p>Yaffs is the first, and perhaps only, file system designed specifically for NAND flash. This means that Yaffs has been designed to work around the various limitations and quirks of NAND flash, as well as exploit the various features of NAND to achieve an effective file system.</p>\n<p>Some features to consider:</p>\n<ul>\n<li>\n<p>Yaffs has been well proven and has been used to ship in <span style=\"font-weight: normal\">large volumes in several products using many different operating systems, compilers and processors.</span></p>\n </li>\n<li>\n<p>Yaffs is written in portable C and is endian neutral.</p>\n </li>\n<li>\n<p>Yaffs provides <span style=\"font-weight: normal\">bad</span> <b></b><span style=\"font-weight: normal\">block</span> handling and ECC algorithms to handle deficiencies in NAND flash.</p>\n </li>\n<li>\n<p>Yaffs is a log-structured file system which makes it very robust to corruptions caused by power failures etc.</p>\n </li>\n<li>\n<p>Yaffs has highly optimised and predictable garbage collection strategies. This makes it high performance and very deterministic when compared with similar file systems.</p>\n </li>\n<li>\n<p>Yaffs has a lower memory footprint than most other log-structured flash file systems.</p>\n </li>\n<li>\n<p>Yaffs provides a wide range of POSIX-style file system support including directories, symbolic and hard links etc. through standard file system interface calls.</p>\n </li>\n<li>\n<p><span style=\"font-weight: normal\">Yaffs is h</span>ighly configurable to work with various flash geometries, various ECC options, caching options etc.</p>\n </li>\n<li>\n<p>Yaffs Direct Interface is simple to integrate in a system – only a few interface functions are required.</p>\n </li>\n<li>\n<p>Yaffs can be used with a wide range of memory technologies.</p>\n </li>\n</ul>\n<h1 class=\"western\">5 Source Code and Yaffs Resources </h1>\n<p><span style=\"font-family: Liberation Serif, serif;\">Please note the licensing terms that apply to using the Yaffs code.</span></p>\n<p><a href=\"http://www.yaffs.net/\"><span style=\"font-family: Liberation Serif, serif;\">http://www.yaffs.net</span></a><span style=\"font-family: Liberation Serif, serif;\"><span style=\"font-style: normal\"><span style=\"font-weight: normal\">serves as the hub for all Yaffs information.</span></span></span></p>\n<p><span style=\"font-family: Liberation Serif, serif;\">This document refers to the Yaffs source code extensively.<span style=\"font-style: normal\"><span style=\"font-weight: normal\">and is available via the download link on this site.</span></span></span></p>\n<p><span style=\"font-family: Liberation Serif, serif;\">There are various other documents and a Yaffs mailing list for Yaffs discussions.</span></p>\n<p><span style=\"font-family: Liberation Serif, serif;\">Consulting services are also available.</span></p>\n<h1 class=\"western\">6 System Requirements</h1>\n<p>Determining minimum system requirements is often quite difficult. The following are presented as a guideline only. Contact Aleph One for more detailed analysis if required.</p>\n<ul>\n<li>\n<p>Yaffs is endian-neutral and works fine with little-endian and big-endian processors.</p>\n </li>\n<li>\n<p>Yaffs code has been used successfully with many different 32-bit and 64-bit CPUs including MIPS, 68000, ARM, ColdFire, PowerPC and x86 variants. Yaffs has even been used with various DSP architectures. Yaffs should work with 16-bit CPUs too, but this is generally untested and might need some tuning, depending on compiler options.</p>\n </li>\n<li>\n<p>Because Yaffs is log structured, RAM is required to build up runtime data structures for acceptable performance. As a rule of thumb, budget approximately 2 bytes per <i>chunk</i> of NAND flash, where a <i>chunk</i> is typically one page of NAND. For NAND with 512byte pages, budget approximately 4kbytes of RAM per 1Mbyte of NAND. For 2kbyte page devices budget approximately 1kbyte per 1Mbyte of NAND.</p>\n </li>\n</ul>\n<h1 class=\"western\">7 How to integrate Yaffs with an RTOS/Embedded system</h1>\n<p>Yaffs Direct Interface (YDI) wraps Yaffs in a way that is simple to integrate. You need to provide a few functions for Yaffs to use to talk to your hardware and RTOS. Yaffs provides a set of POSIX-compliant functions for applications to use to talk to it.</p>\n<p>In addition to the Yaffs core file system, the YDI has three parts which are each explained in more detail in further sections:</p>\n<ul>\n<li>\n<p><b>POSIX Application Interface</b>: This is the POSIX-like interface that the application code uses to access the Yaffs file system. (<span style=\"font-family: Times New Roman;\"><i>open, close, read, write, </i></span>etc) </p>\n </li>\n<li>\n<p><b>RTOS Integration Interface</b>: These are the functions that must be provided for Yaffs to access the RTOS system resources. (<span style=\"font-family: Times New Roman;\"><i>initialise, lock, unlock, get time, </i></span><span style=\"font-family: Times New Roman;\"><i>memory allocation,</i></span><span style=\"font-family: Times New Roman;\"><i>set error, </i></span><span style=\"font-family: Times New Roman;\"><i>etc</i></span>). Note that although we use the term RTOS, the same can be done with other OSs or even with no RTOS at all in a bare-metal system.</p>\n </li>\n<li>\n<p><img src=\"data:image/png;base64,[encoded data, 27864 characters]\" width=\"485\" height=\"530\" alt=\"image\" id=\"Object1\" /> <b>Flash Device </b><b>Interface</b>: This interface support is where the flash device and appropriate device drivers are installed to provide an access path from Yaffs to the flash device(s). Multiple different devices and device types can be supported simultaneously.</p>\n </li>\n</ul>\n<h2 class=\"western\">7.1 Source Files</h2>\n<p>The following source files contain the core file system:</p>\n<table cellpadding=\"4\" style=\"width: 100%; border-spacing: 0px;\">\n<col width=\"71*\" /> <col width=\"185*\" />\n<tr valign=\"top\">\n <td style=\"border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0.1cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 28%;\">\n <p>yaffs_allocator.c</p>\n  </td>\n <td style=\"border: 1px solid #000000; padding: 0.1cm; width: 72%;\">\n <p>Allocates Yaffs object and tnode structures.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 28%;\">\n <p><br />\n  </p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 72%;\">\n <p><br />\n  </p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 28%;\">\n <p>yaffs_bitmap.c</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 72%;\">\n <p>Block and chunk bitmap handling code.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 28%;\">\n <p>yaffs_checkpointrw.c</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 72%;\">\n <p>Streamer for writing checkpoint data</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 28%;\">\n <p>yaffs_ecc.c</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 72%;\">\n <p>1-bit Hamming ECC code</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 28%;\">\n <p><br />\n  </p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 72%;\">\n <p><br />\n  </p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 28%;\">\n <p>yaffs_guts.c</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 72%;\">\n <p>The major Yaffs algorithms.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 28%;\">\n <p>yaffs_nameval.c</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 72%;\">\n <p>Name/value code for handling extended attributes (xattr).</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 28%;\">\n <p>yaffs_nand.c</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 72%;\">\n <p>Flash interfacing abstraction.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 28%;\">\n <p>yaffs_packedtags1.c<br />\n  yaffs_packedtags2.c</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 72%;\">\n <p>Tags packing code</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 28%;\">\n <p>yaffs_summary.c</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 72%;\">\n <p>Code for handling block summaries.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 28%;\">\n <p>yaffs_tagscompat.c</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 72%;\">\n <p>Tags compatibility code to support Yaffs1 mode.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 28%;\">\n <p>yaffs_tagsmarshall.c</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 72%;\">\n <p>Tags marshalling code.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 28%;\">\n <p>yaffs_verify.c</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 72%;\">\n <p>Test verification code.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 28%;\">\n <p>yaffs_yaffs1.c</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 72%;\">\n <p>Yaffs1-mode specific code.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 28%;\">\n <p>yaffs_yaffs2.c</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 72%;\">\n <p>Yaffs2-mode specific code.</p>\n  </td>\n</tr>\n</table>\n<p><br />\n<br />\n</p>\n<p>The Yaffs direct interface is in yaffsfs.c, with the interface functions and structures defined in yaffsfd.h.</p>\n<p><br />\n<br />\n</p>\n<table cellpadding=\"4\" style=\"page-break-inside: avoid; width: 100%; border-spacing: 0px;\">\n<col width=\"72*\" /> <col width=\"184*\" />\n<tr valign=\"top\">\n <td style=\"border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0.1cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 28%;\">\n <p>yaffs_attribs.c</p>\n  </td>\n <td style=\"border: 1px solid #000000; padding: 0.1cm; width: 72%;\">\n <p>Attribute handling.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 28%;\">\n <p>yaffs_error.c</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 72%;\">\n <p>Error reporting code.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 28%;\">\n <p>yaffsfs.c</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 72%;\">\n <p>Yaffs Direct Interface wrapper code.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 28%;\">\n <p>yaffs_hweight.c</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 72%;\">\n <p>Counts the number of hot bits in a byte, word etc.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 28%;\">\n <p>yaffs_qsort.c</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 72%;\">\n <p>Qsort used during Yaffs2 scanning</p>\n  </td>\n</tr>\n</table>\n<p><br />\n<br />\n</p>\n<p>Example flash drivers, simulators and configurations used for testing are are in direct/test-framework directory. These include:</p>\n<table cellpadding=\"4\" style=\"page-break-inside: avoid; width: 100%; border-spacing: 0px;\">\n<col width=\"72*\" /> <col width=\"184*\" />\n<tr valign=\"top\">\n <td style=\"border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0.1cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 28%;\">\n <p>nanddrv.c</p>\n  </td>\n <td style=\"border: 1px solid #000000; padding: 0.1cm; width: 72%;\">\n <p>A NAND driver layer that performs the commands to access NAND flash in a rudimentary manner. This code should work on many styles of CPU with little modification.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 28%;\">\n <p>yaffs_nanddrv.c</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 72%;\">\n <p>A wrapper around the NAND driver which plugs it into Yaffs.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 28%;\">\n <p>nandsim.c</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 72%;\">\n <p>A NAND simulator layer that works with a nandstore_xxx backing store. This simulates a NAND chip.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 28%;\">\n <p>nandstore_file.c</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 72%;\">\n <p>A storage backend for a NAND simulator that stores the data to file.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 28%;\">\n <p>nandsim_file.c</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 72%;\">\n <p>A wrapper around nandsim.c and nandstore_file.c which makes a NAND simulator that saves its data in a file.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 28%;\">\n <p>yaffs_nandsim_file.c</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 72%;\">\n <p>A wrapper which creates a nand simulator instance, hooks up the yaffs NAND driver and then adds it to yaffs for use.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 28%;\">\n <p>yaffs_nor_drv.c</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 72%;\">\n <ol>\n </ol>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 28%;\">\n <p>yaffs_m18_drv.c</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 72%;\">\n <p>A driver for Intel M18-style NOR flash.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 28%;\">\n <p>yaffs_osglue.c</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 72%;\">\n <p>An OS glue layer example used in the test harness.</p>\n  </td>\n</tr>\n</table>\n<p><br />\n<br />\n</p>\n<p>Example and testing build files:</p>\n<table cellpadding=\"4\" style=\"width: 100%; border-spacing: 0px;\">\n<col width=\"71*\" /> <col width=\"185*\" />\n<tr valign=\"top\">\n <td style=\"border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0.1cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 28%;\">\n <p>dtest.c</p>\n  </td>\n <td style=\"border: 1px solid #000000; padding: 0.1cm; width: 72%;\">\n <p>A test harness. Also has sample code that can be used for better understanding of how some function calls work.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 28%;\">\n <p>yaffscfg2k.c</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 72%;\">\n <p>A test configuration.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 28%;\">\n <p>yaffs_fileem.c<br />\n  yaffs_fileem2k.c</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 72%;\">\n <p>Nand flash simulation using a file as backing store.</p>\n  </td>\n</tr>\n</table>\n<p><br />\n<br />\n</p>\n<p>Further testing files are in direct/tests and direct/python.</p>\n<h2 class=\"western\" style=\"page-break-before: always\">7.2 Integrating the POSIX Application Interface</h2>\n<p>The application interface is defined in yaffsfs.h. These provide a POSIX file system interface. For the most part, this interface consists of the standard clib function names prefixed with <code class=\"western\">yaffs_</code>. For example, <code class=\"western\">yaffs_open(), yaffs_close()</code> etc.</p>\n<p><br />\n<br />\n</p>\n<p>There is a lot of flexibility in how these functions are used and the system integrator needs to determine the best strategy for the system.</p>\n<p>These functions can be used directly, with the code written using these names. For example</p>\n<p class=\"code-western\"><code class=\"western\">int main(...)<br />\n{<br />\n// initialisation<br />\nf = yaffs_open(...);<br />\nyaffs_read(f,...);<br />\nyaffs_close(f);<br />\n}</code></p>\n<p>The <span style=\"font-family: Times New Roman;\">yaffs</span> functions can also be wrapped in some way to allow existing code to use yaffs without modification. For example:</p>\n<p style=\"margin-bottom: 0cm; orphans: 0; widows: 0; page-break-before: auto; page-break-after: avoid\"><br />\n</p>\n<p class=\"code-western\"><code class=\"western\">#define open(path, oflag, mode) yaffs_open(path, oflag, mode)<br />\n..<br />\n<br />\nint main(...)<br />\n{<br />\n// initialisation<br />\nf = open(...);<br />\nread(f,...);<br />\nclose(f);<br />\n}</code><br />\n<br />\n<br />\n</p>\n<p style=\"margin-bottom: 0cm; orphans: 0; widows: 0; page-break-before: auto\"><br />\n</p>\n<p>A more complex approach that can be used if more than one file-system is used is to provide redirection functions. For example:</p>\n<p style=\"margin-bottom: 0cm; orphans: 0; widows: 0; page-break-before: auto; page-break-after: avoid\"><br />\n</p>\n<p class=\"code-western\"><code class=\"western\">int open(const char *path,...)<br />\n{<br />\n// Determine which file system is being used<br />\n</code><code class=\"western\">i</code><code class=\"western\">f(it_is_a_yaffs_path(path))<br />\nreturn yaffs_open(...);<br />\nelse {<br />\n// Do something else<br />\n}<br />\n}</code></p>\n<p style=\"margin-left: 1.25cm; margin-bottom: 0cm; page-break-inside: avoid; orphans: 0; widows: 0; page-break-before: auto; page-break-after: auto\"><br />\n</p>\n<p><br />\n<br />\n</p>\n<p>Some RTOS\'s provide a flexible way to integrate file systems in which case YDI can typically use these interfaces to access yaffs file systems.</p>\n<h1 class=\"western\" style=\"page-break-before: always\">8 RTOS Integration Interface</h1>\n<p>Before Yaffs can be used, it needs to be integrated with the system and configured so that the correct actions are performed.</p>\n<p>To do this, you need to modify the configuration file. An example configuration file is presented in <span style=\"font-family: Bitstream Vera Sans;\"><span style=\"font-family: Times New Roman;\">yaffscfg.c and yaffscfg2k.c.</span></span></p>\n<p>This is a relatively straight forward process and defines the RTOS access functions.</p>\n<p>The RTOS access functions are:</p>\n<ul>\n<li>\n<p><code class=\"western\">void yaffsfs_SetError(int err)</code>: Called by Yaffs to set the system error.</p>\n </li>\n<li>\n<p><code class=\"western\">void yaffsfs_Lock(void)</code>: Called by Yaffs to lock Yaffs from multi-threaded access.</p>\n </li>\n<li>\n<p><code class=\"western\">void yaffsfs_Unlock(void)</code>: Called by Yaffs to unlock Yaffs.</p>\n </li>\n<li>\n<p><code class=\"western\">u32 yaffsfs_CurrentTime(void)</code>: Get current time from RTOS.</p>\n </li>\n<li>\n<p><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>void *yaffsfs_malloc(size_t size)</b></span></span>: Called to allocate memory.</p>\n </li>\n<li>\n<p><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>void yaffsfs_free(void *ptr)</b></span></span>: Called to free memory.</p>\n </li>\n<li>\n<p><code class=\"western\">void yaffsfs_</code><code class=\"western\">OS</code><code class=\"western\">Initialisation(void)</code>: Called to initialise RTOS context.</p>\n </li>\n<li>\n<p><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>void yaffs_bug_fn(const char *file_name, int line_no)</b></span></span>: Function to report a bug.</p>\n </li>\n<li>\n<p><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>int yaffsfs_CheckMemRegion(const void *addr, size_t size, int writ</b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>e_request</b></span></span>) : Function to check if accesses to a memory region is valid. This function must return zero if the test passes and negative if it fails.</p>\n </li>\n</ul>\n<p><br />\n<br />\n</p>\n<p>If Yaffs is being used in a multi-threaded environment, then typically <code class=\"western\">yaffs_LocalInitialisation()</code> will initialise a suitable RTOS semaphore and <code class=\"western\">yaffs_Lock()</code> and <code class=\"western\">yaffs_Unlock()</code> will call the appropriate functions to lock and release the semaphore.</p>\n<p><code class=\"western\">yaffs_CurrentTime()</code> can be any time increment of use to the system. If this is not required, then it is fine to just use a function that is hard-wired to return zero.</p>\n<p>Before the application code uses Yaffs, the <code class=\"western\">yaffs</code><code class=\"western\">fs</code><code class=\"western\">_</code><code class=\"western\">OSInitialisation</code><code class=\"western\">()</code> function must be called.</p>\n<p><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>yaffsfs_CheckMemRegion()</b></span></span><span style=\"font-family: Liberation Serif, serif;\"><span style=\"font-size: 12pt; font-size: medium; font-size: medium;\"><span style=\"font-weight: normal\">is used to check addresses passed to the various yaffs_xxx functions (yaffs_open(), yaffs_read() etc)). If the function returns -1, then the yaffs_xxx function will return -EFAULT rather than attempt to dereference the address and crash.</span></span></span></p>\n<p style=\"font-weight: normal\"><span style=\"font-family: Liberation Serif, serif;\"><span style=\"font-size: 12pt; font-size: medium; font-size: medium;\">An implementation might do something like:</span></span></p>\n<p style=\"font-weight: normal\"><br />\n<br />\n</p>\n<p class=\"code-western\"><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>int yaffsfs_CheckMemRegion(const void addr, size_t size, <br />\nint write_</b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>request</b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>) <br />\n{<br />\nu32 uaddr</b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>b</b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>= (u32) addr;<br />\n</b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>u32 uaddrt = uaddrb + size -1;<br />\n</b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b><br />\nif( uaddr</b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>b</b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>&gt;= stack_bottom &amp;&amp; uaddr</b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>b</b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>&lt;= stack_top &amp;&amp;<br />\n</b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>uaddrt &gt;= stack_bottom &amp;&amp; uaddrt &lt;= stack_top)<br />\nreturn 0; /* </b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>r/w </b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>access is OK */<br />\n</b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b><br />\nif( uaddr</b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>b</b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>&gt;= </b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>heap</b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>_bottom &amp;&amp; uaddr</b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>b</b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>&lt;= </b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>heap</b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>_top &amp;&amp;<br />\n</b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>uaddrt &gt;= heap_bottom &amp;&amp; uaddrt &lt;= heap_top)<br />\nreturn 0; /* </b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>r/w</b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>access is OK /<br />\n</b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b><br />\nif( !</b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>write_request &amp;&amp;<br />\n</b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>uaddr</b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>b</b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>&gt;= </b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>rom</b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>_bottom &amp;&amp; uaddr</b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>b</b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>&lt;= </b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>rom</b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>_top &amp;&amp;<br />\n</b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>uaddrt &gt;= rom_bottom &amp;&amp; uaddrt &lt;= rom_top)<br />\nreturn 0; / </b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>read </b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>access is OK /</b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b><br />\n<br />\n</b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>return -1; /* Bad access */</b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b><br />\n<br />\n}</b></span></span></p>\n<p class=\"code-western\"><br />\n<br />\n</p>\n<h1 class=\"western\" style=\"page-break-before: always\">9 Yaffs NAND Model</h1>\n<p>Before defining the flash integration interface, it is important to understand the model and corresponding nomenclature used throughout Yaffs and its documentation.</p>\n<p>Yaffs uses a fairly abstract model for NAND flash. This allows a lot of flexibility in the way it can be used.</p>\n<p>Yaffs is designed for NAND flash and makes the following assumptions and definitions:</p>\n<ul>\n<li>\n<p>The flash is arranged in <i><b>blocks</b></i>. Each block is the same size and comprises an integer number of <span style=\"font-style: normal\"><span style=\"font-weight: normal\">chunks</span></span>. Each block is treated as a single erasable item. A block contains a number of chunks.</p>\n </li>\n<li>\n<p>A <i><b>chunk</b></i> equates to the allocation units of flash. For Yaffs1, each chunk equates to a 512-byte or larger NAND page (that is, a 512-byte or larger data portion and a 16-byte spare area). For Yaffs2, a chunk will typically be larger (eg. on 2k page devices, a chunk will typically be a single 2k page: 2kbytes of data and 64 bytes of spare). Yaffs2 is capable of working with smaller chunk sizes by using inband tags.</p>\n </li>\n<li>\n<p>All accesses (reads and writes) are page chunk aligned. Some reads might only read the spare area where the tags are kept.</p>\n </li>\n<li>\n<p>When programming a NAND flash, only the zero bits in the pattern being programmed are relevant, and one bits are &quot;don\'t care&quot;. For example, if a byte already contains the binary pattern b1010, then programming b1001 will result in the pattern which is the logical AND of these two patterns ie. b1000. This is different to NOR flash which would typically abort the attempt to convert a 0 into a 1.</p>\n </li>\n</ul>\n<p><br />\n<br />\n</p>\n<p>Yaffs ide<span style=\"font-weight: normal\">ntifies</span> blocks by their block number and chunks by the chunk Id. A chunk Id is calculated as:</p>\n<p><code class=\"western\">chunkId = block_id * chunks_per_block + chunk_offset_in_block</code></p>\n<p>Yaffs treats a blank (0xFF filled) block as being free or erased. Thus, the equivalent of formatting for a Yaffs partition is to erase all the blocks that are not bad.</p>\n<p>Yaffs2 has a generalised tags interface to provide better flexibility to cater for a wider range of devices with larger pages and stricter programming limitations. Yaffs2 thus handles more abstract constructs than Yaffs1 and, in older versions of Yaffs, more effort was required to interface to the NAND.</p>\n<p>In newer versions of Yaffs, the tags management has been abstracted out of the driver. This makes the driver interface far simpler.</p>\n<h2 class=\"western\">9.1 Formatting</h2>\n<p>Yaffs treats erased blocks as empty. That makes it really easy to “format” a device: just erase it.. Note that this should be done while the partition is not mounted.</p>\n<p>Unmounting will not normally work when the file system is busy (eg. files are open), Some extra non-standard unmount options are provided to enable an unmount to be forced. Note that using these will break any current handles and you will no longer be able to use open files.</p>\n<p><code class=\"western\"><span style=\"font-family: Liberation Serif, serif;\"><span style=\"font-size: 12pt; font-size: medium; font-size: medium;\"><span style=\"font-weight: normal\">There is a </span></span></span></code><code class=\"western\"><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>yaffs_format() </b></span></span></code><code class=\"western\"><span style=\"font-family: Liberation Serif, serif;\"><span style=\"font-size: 12pt; font-size: medium; font-size: medium;\"><span style=\"font-weight: normal\">function that will take care of the details.</span></span></span></code></p>\n<p><br />\n<br />\n</p>\n<h2 class=\"western\">9.2 NAND Model considerations for Yaffs1</h2>\n<p>The historical Yaffs1 tags structure was laid out in accordance with the SmartMedia specification for use with 512-byte pages. There is now much more flexibility in the way things can be configured.</p>\n<p><br />\n<br />\n</p>\n<p>Yaffs1 is capable of being used with a variety of memory layouts so long as the flash supports the ability to overwrite the tags area to set the deletion marker to zero.</p>\n<p>If the yaffs_dev\'s use_nand_ecc field is not set, then yaffs will perform the ECC calculations. If this is set then yaffs will expect the NAND driver to do any required ECC checks. On devices that are not using ECC, for example NOR, set use_nand_ecc=1 and then don\'t do any ECC anyway.</p>\n<p>The Yaffs1 flash model expects an area of 16 spare bytes, some of which are used for tags. The mapping between the spare bytes and the usage of the bytes is specified in yaffs_packedtags1.c</p>\n<p>The Yaffs1 model has been used in many NOR-based systems. One particularly instructive example is in yaffs_nor_drv.c which implements a driver for Yaffs1 mode on CFI-style NOR flash. This does not use ECC but uses checksumming instead.</p>\n<p>The yaffs_dev structure has a yaffs_driver structure which holds the function pointers to the driver. For Yaffs1 mode of operations the following are required:</p>\n<table cellpadding=\"4\" style=\"page-break-inside: avoid; width: 100%; border-spacing: 0px;\">\n<col width=\"77*\" /> <col width=\"179*\" />\n<tr valign=\"top\">\n <td style=\"border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0.1cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 30%;\">\n <p>drv_write_chunk_fn</p>\n  </td>\n <td style=\"border: 1px solid #000000; padding: 0.1cm; width: 70%;\">\n <p>Write a data chunk</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 30%;\">\n <p>drv_read_chunk_fn</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 70%;\">\n <p>Read a data chunk.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 30%;\">\n <p>drv_erase_fn</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 70%;\">\n <p>Erase a block</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 30%;\">\n <p>drv_initialise_fn</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 70%;\">\n <p>Initialisation.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 30%;\">\n <p>drv_deinitialise_fn</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 70%;\">\n <p>De-initialise</p>\n  </td>\n</tr>\n</table>\n<p><br />\n<br />\n</p>\n<p>These functions are described later.</p>\n<h2 class=\"western\">9.3 NAND Model for Yaffs2</h2>\n<p>The Yaffs2 interface is far more flexible than Yaffs1, but that means a bit more effort must be done in the driver. In particular:</p>\n<ul>\n<li>\n<p>There is is no standard spare area/ECC layout. The driver must handle all the layout of the spare area and ECC handling.</p>\n </li>\n<li>\n<p>There is not a standard implementation for bad block markers. Thus, the driver must provide functions for checking and marking bad blocks.</p>\n </li>\n</ul>\n<p>The yaffs_driver structure for Yaffs2 mode requires the following functions:</p>\n<p style=\"margin-bottom: 0cm; orphans: 0; widows: 0; page-break-before: auto\"><br />\n</p>\n<table cellpadding=\"4\" style=\"page-break-inside: avoid; width: 100%; border-spacing: 0px;\">\n<col width=\"77*\" /> <col width=\"179*\" />\n<tr valign=\"top\">\n <td style=\"border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0.1cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 30%;\">\n <p>drv_write_chunk_fn</p>\n  </td>\n <td style=\"border: 1px solid #000000; padding: 0.1cm; width: 70%;\">\n <p>Write a data chunk</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 30%;\">\n <p>drv_read_chunk_fn</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 70%;\">\n <p>Read a data chunk.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 30%;\">\n <p>drv_erase_fn</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 70%;\">\n <p>Erase a block</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 30%;\">\n <p>drv_mark_bad_fn</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 70%;\">\n <p>Mark a block bad</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 30%;\">\n <p>drv_check_bad_fn</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 70%;\">\n <p>Check bad block status of a block.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 30%;\">\n <p>drv_initialise_fn</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 70%;\">\n <p>Initialisation.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 30%;\">\n <p>drv_deinitialise_fn</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 70%;\">\n <p>De-initialise</p>\n  </td>\n</tr>\n</table>\n<p><br />\n<br />\n</p>\n<h2 class=\"western\">9.4 Overview of flash driver function</h2>\n<p>The best way to understand how to write these functions is to look at the example drivers.</p>\n<p><br />\n<br />\n</p>\n<p class=\"code-western\">int (*drv_write_chunk_fn) (struct yaffs_dev *dev, int nand_chunk, </p>\n<p class=\"code-western\">const u8 *data, int data_len, </p>\n<p class=\"code-western\">const u8 *oob, int oob_len)</p>\n<p>This function writes the specified chunk data and oob/spare data to flash.</p>\n<p>This function should return YAFFS_OK on success or YAFFS_FAIL on failure.</p>\n<p>If this is a Yaffs2 device, or Yaffs1 with use_nand_ecc set, then this function must take care of any ECC that is required.</p>\n<p><br />\n<br />\n</p>\n<p class=\"code-western\">int (*drv_read_chunk_fn) (struct yaffs_dev *dev, int nand_chunk, </p>\n<p class=\"code-western\">u8 *data, int data_len, </p>\n<p class=\"code-western\">u8 *oob, int oob_len,</p>\n<p class=\"code-western\">enum yaffs_ecc_result *ecc_result)</p>\n<p>This function reads the specified chunk data and oob/spare data from flash.</p>\n<p>This function should return YAFFS_OK on success or YAFFS_FAIL on failure.</p>\n<p>If this is a Yaffs2 device, or Yaffs1 with use_nand_ecc set, then this function must take care of any ECC that is required and set the ecc_result.</p>\n<p><br />\n<br />\n</p>\n<p class=\"code-western\">int (*drv_erase_fn) (struct yaffs_dev *dev, int block_no) </p>\n<p>This function erases the specified block.</p>\n<p>This function should return YAFFS_OK on success or YAFFS_FAIL on failure.</p>\n<p><br />\n<br />\n</p>\n<p class=\"code-western\">int (*drv_mark_bad_fn) (struct yaffs_dev *dev, int block_no); </p>\n<p class=\"code-western\">int (*drv_check_bad_fn) (struct yaffs_dev *dev, int block_no); </p>\n<p>These functions are only required for Yaffs2 mode. They mark a block bad or check if it is bad.</p>\n<p><br />\n<br />\n</p>\n<p class=\"code-western\">int (*drv_initialise_fn) (struct yaffs_dev *dev); </p>\n<p class=\"code-western\">int (*drv_deinitialise_fn) (struct yaffs_dev *dev); </p>\n<p>These functions provide hooks for initialising or deinitialising the flash driver.</p>\n<p><br />\n<br />\n</p>\n<h1 class=\"western\" style=\"page-break-before: always\">10 Configuration and flash driver installation</h1>\n<p>For an example of how to do the configuration, refer to yaffs_cfg2k.c and one of the drivers such as yaffs_nand_drv.c</p>\n<p>The old mechanism was static and required a table of devices that was installed at start up. This mechanism had shortcomings – in particular it broke modularity and did not allow devices to be added dynamically.</p>\n<p>Things are different now. As any time, a yaffs_dev structure can be configured and then registered with Yaffs by using the yaffs_add_device() function.</p>\n<p>A yaffs_dev structure has two parts which must be configured before yaffs_add_device() is called: the paramers (dev-&gt;param) and the driver (dev-&gt;drv). The driver configuration (plugging in the driver functions) has already been described above, so we will now look at the yaffs parameters.</p>\n<p><br />\n<br />\n</p>\n<p>The yaffs_param structure must be set before the yaffs_dev is added with yaffs_add_device() and should not be modified after that.</p>\n<p>The params are defined in the Yaffs Tuning Document.</p>\n<h1 class=\"western\" style=\"page-break-before: always\">11 Using the POSIX file system interface</h1>\n<p>This section is directed to readers that might not be very familiar with accessing a file system via POSIX and POSIX-like interfaces.</p>\n<h2 class=\"western\">11.1 Difference to Windows POSIX-like interfaces</h2>\n<p>MSDOS and Windows provide a POSIX-lke interface. If you are familiar with this then that will help you. There are are however some slight differences, most importantly:</p>\n<ul>\n<li>\n<p>Windows has no concept of links and has a 1:1 mapping between file names and files.POSIX supports files with zero, one or many names. Refer to the sections on linking and unlinking files. For instance POSIX allows you to unlink a file (ie delete the name for a file) while it is still in use. You can continue to read/write the file but it will be deleted as soon as the last file handle to the file is closed. Windows, on the other hand, does not allow you to unlink a file while it is in use.</p>\n </li>\n<li>\n<p>Windows names drives with a letter. POSIX has no drive letters. The whole POSIX file system is in a single directory tree.</p>\n </li>\n<li>\n<p>Directories and “folders” are the same thing.</p>\n </li>\n</ul>\n<h2 class=\"western\">11.2 Fundamental concepts</h2>\n<table cellpadding=\"4\" style=\"width: 642px; border-spacing: 0px;\">\n<col width=\"126\" /> <col width=\"499\" />\n<tr valign=\"top\">\n <td style=\"border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0.1cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 126px;\">\n <p>File</p>\n  </td>\n <td style=\"border: 1px solid #000000; padding: 0.1cm; width: 499px;\">\n <p>A file is an object that is stored in the file system. yaffs supports the following file types:</p>\n <p>A regular file is a sequence of bytes stored in the file system.</p>\n <p>A directory holds links to other files.</p>\n <p>A symbolic link holds a name to another file.</p>\n <p>A special file holds device ids or similar information.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 126px;\">\n <p>Directory</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 499px;\">\n <p>This is a structure that holds links and allows a file to be found by name. Note that a single file may have many links(ie names) and many be found in many places in the directory structure.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 126px;\">\n <p>Link</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 499px;\">\n <p>This is a name that allows the file to be found. There are two types of link: real links (sometimes called hard links) and symbolic (or soft) links. </p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 126px;\">\n <p>Handle</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 499px;\">\n <p>A file handle provides a context from which a file can be accessed and manipulated. A handle has a current file position pointer which points to where the file is being read or written. Multiple handles can simultaneously access a single file.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 126px;\">\n <p>File mode</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 499px;\">\n <p>The mode is the set of flags that define the type of file as well as the current permissions associated with the file.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 126px;\">\n <p>Path</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 499px;\">\n <p>This is a string that defines the directories and file name. For example:</p>\n <p>“/data/direct-1/file1”</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 126px;\">\n <p>File metadata</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 499px;\">\n <p>This is the information about the file, excluding the file contents. The metadata includes the name, mode, size and other details.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 126px;\">\n <p>Mount,<br />\n  partition,<br />\n  file system</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 499px;\">\n <p>These terms all refer to a single mounted flash area. Each mount is hooked into a common directory structure.<br />\n  The term file system can sometimes be confusing because it is used both for a single mounted partition as well as the the file system code. In other words, we might say that both “/boot” is a file system and might also say that yaffs is a file system.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 126px;\">\n <p>inode number</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 499px;\">\n <p>The inode number is a unique number that identifies the object within the mount. Note that inodes are not unique between two or more mounts. There is no way to reach a file by inode, only via its links.</p>\n  </td>\n</tr>\n</table>\n<p><br />\n<br />\n</p>\n<h2 class=\"western\">11.3 Error code</h2>\n<p>Most functions result in error codes if the function does not execute successfully. In these cases yaffs calls a function called <code class=\"western\">yaffs_SetError()</code> with the error value. This function can be configured to deliver the error into the system\'s error mechanism.</p>\n<p>In the case of functions that return integers, a returned value smaller than 0 indicates an error occurred. Functions returning pointers will return NULL if an error occurred.</p>\n<h2 class=\"western\">11.4 Links – the hard kind (not symbolic links)</h2>\n<p>At first we\'re just considering real links and not symbolic links. Sometimes real links are also called hard links to differentiate them from symbolic links (which are sometimes called soft links).</p>\n<p>The difference between links and files is subtle and can be confusing. Briefly:</p>\n<ul>\n<li>\n<p>a file is the stored object in the file system</p>\n </li>\n<li>\n<p>the link is how it is hooked into the directory structure.</p>\n </li>\n</ul>\n<p><br />\n<br />\n</p>\n<p>The first link to a file is created by using the file creation calls: <code class=\"western\">yaffs_open()</code>, <code class=\"western\">yaffs_mknod()</code>, <code class=\"western\">yaffs_symlink()</code> and <code class=\"western\">yaffs_mkdir()</code>.</p>\n<p>A link can be destroyed by using the <code class=\"western\">yaffs_unlink()</code> function. Directories are destroyed using the <code class=\"western\">yaffs_rmdir()</code> function (oh, and the directory must be empty).</p>\n<p>Once a file is both unused (there are no handles open to it) and there are no links to it it is then deleted.</p>\n<p>A link can be renamed by using the <code class=\"western\">yaffs_rename()</code> function.</p>\n<p>A file may have many links. These may be created using the <code class=\"western\">yaffs_link()</code> function. All the links access the same file and there is no one link that is considered “the real link” and others being “the duplicate link”. All links to a file have the same priority. If you look at the inode number for “a” and for “b” then they will be the same because they are refering to exactly the same file.</p>\n<p>Thus:</p>\n<ol>\n<li>\n<p>If we start with a file called “a” and then call <code class=\"western\">yaffs_link(“a”, “b”)</code> we now have two links to the same file. We can\'t tell them apart.</p>\n </li>\n<li>\n<p>If we now unlink “a”, the file still exists under the link “b”.</p>\n </li>\n<li>\n<p>If we now unlink “b” the file will no longer be linked. If there is a handle open to the file then we can still access the file through the handle and continue to read or modify the file. If there is no link to the file it is deleted.</p>\n </li>\n<li>\n<p>If an unlinked file was kept alive because of a handle being open, the file will not show up in the directory structure (because it has no link) and will be deleted as soon as the handle is closed (or if the file system is unmounted).</p>\n </li>\n</ol>\n<p>There are some limitations in how links are used:</p>\n<ul>\n<li>\n<p>The existing file you are linking to must exist.</p>\n </li>\n<li>\n<p>The file you are linking to must be in the same mount (partition) as the link you are creating.</p>\n </li>\n<li>\n<p>You cannot create a link to a directory because this would allow the creation of recursive loops.</p>\n </li>\n<li>\n<p>The new link name must not exist.</p>\n </li>\n</ul>\n<p><br />\n<br />\n</p>\n<h2 class=\"western\">11.5 Symbolic links</h2>\n<p>Now that you understand how hard links work, we\'ll introduce symbolic (or soft) links.</p>\n<p>A symbolic link holds an alias for a different object. When you use that symbolic link in a path the alias is used instead. To that extent symbolic link and hard links are the same.</p>\n<p>You can remove symbolic links with the <code class=\"western\">yaffs_unlink()</code> function, just like hard links.</p>\n<p>There are, however, some important differences. A symbolic link only does its linking function when the path is being evaluated and thus:</p>\n<ul>\n<li>\n<p>The file you are creating an alias to does not have to exist.</p>\n </li>\n<li>\n<p>The file you are creating an alias to does not have to be in the same mount.</p>\n </li>\n<li>\n<p>You can create symbolic links to directories.</p>\n </li>\n<li>\n<p>A symbolic link will not keep a file alive by itself. Only a hard link can do that.</p>\n </li>\n</ul>\n<p>Thus:</p>\n<ol>\n<li>\n<p>If we start with a file called “a” and then call <code class=\"western\">yaffs_symlink(“a”, “b”)</code> we now have one link to the file called “a” and a symbolic link aliasising from “b” to “a”.</p>\n </li>\n<li>\n<p>If we use <code class=\"western\">yaffs_open(“a”)</code> or <code class=\"western\">yaffs_open(“b”)</code> they will open the same file. The path resolution mechanism substitutes in the alias and so will look up “a”. The same applies to almost all functions that takes a path, such as <code class=\"western\">yaffs_truncate()</code>, <code class=\"western\">yaffs_stat()</code> etc. The only exceptions are <code class=\"western\">yaffs_lstat()</code> and <code class=\"western\">yaffs_readlink()</code> which will treat the path as pointing to the symbolic link and not the file.</p>\n </li>\n<li>\n<p>You can tell “a” and “b” apart by using <code class=\"western\">yaffs_lstat()</code>. <code class=\"western\">yaffs_lstat(“a”)</code> will show the information for file “a”. <code class=\"western\">yaffs_lstat(“b”)</code> will show the information for the symbolic link itself. Note the difference with hard links. With hard links <code class=\"western\">yaffs_lstat(“a”)</code> and <code class=\"western\">yaffs_lstat(“b”)</code> would show the same results since they are EXACTLY the same thing being referenced.</p>\n </li>\n<li>\n<p>If we now unlink “a”. then the file is no longer linked and will no longer be accessible from “b”. Note the difference with hard links.</p>\n </li>\n</ol>\n<p><br />\n<br />\n</p>\n<h2 class=\"western\">11.6 Handle-based file handling</h2>\n<p>A handle is file accessor that allows us to access the contents of a regular file. The handle identifies the file being accessed as well as a position pointer tracking where the next read or write operation will take place.</p>\n<p>A handle is identified by an integer of value 0 or greater.</p>\n<p>A handle is created by using the <code class=\"western\">yaffs_open()</code> call and returns the handle value. If the handle could not be created then a negative value is returned and the yaffs error code is set.</p>\n<p>A handle remains valid until the handle is closed by <code class=\"western\">yaffs_close()</code>.</p>\n<p>The <code class=\"western\">yaffs_open()</code> call takes three parameters:</p>\n<ul>\n<li>\n<p>name: Full path name of the file being opened.</p>\n </li>\n<li>\n<p>access flags: Flags being used to open this handle</p>\n </li>\n<li>\n<p>creation mode: Mode flags used when creating a file.</p>\n </li>\n</ul>\n<p>The access flags are one or more of:</p>\n<table cellpadding=\"4\" style=\"width: 100%; border-spacing: 0px;\">\n<col width=\"59*\" /> <col width=\"197*\" />\n<tr valign=\"top\">\n <td style=\"border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0.1cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 23%;\">\n <p><span style=\"font-family: Courier, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><code class=\"western\">O_CREAT</code></span></span></p>\n  </td>\n <td style=\"border: 1px solid #000000; padding: 0.1cm; width: 77%;\">\n <p>Create file if it does not already exist.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 23%;\">\n <p><span style=\"font-family: Courier, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><code class=\"western\">O_EXCL</code></span></span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 77%;\">\n <p>Only use with O_CREAT. Create file if it does not exist. If the file already exists then fail.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 23%;\">\n <p><span style=\"font-family: Courier, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><code class=\"western\">O_TRUNC</code></span></span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 77%;\">\n <p>If the file exists, and opening with write access, then truncate the file to zero bytes long.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 23%;\">\n <p><br />\n  </p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 77%;\">\n <p><br />\n  </p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 23%;\">\n <p><span style=\"font-family: Courier, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><code class=\"western\">O_APPEND</code></span></span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 77%;\">\n <p>Regardless of the handle position, always write to the end of the file.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 23%;\">\n <p><br />\n  </p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 77%;\">\n <p><br />\n  </p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 23%;\">\n <p><span style=\"font-family: Courier, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><code class=\"western\">O_RDWR</code></span></span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 77%;\">\n <p>Open for read/write access.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 23%;\">\n <p><span style=\"font-family: Courier, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><code class=\"western\">O_WRONLY</code></span></span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 77%;\">\n <p>Open for write access and no read access.</p>\n <p><br />\n  </p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 23%;\">\n <p><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>0 (zero)</b></span></span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 77%;\">\n <p>If neither O_RDWR or O_WRONLY is set then the file will be opened for read-only access.</p>\n  </td>\n</tr>\n</table>\n<p><br />\n<br />\n</p>\n<p>Where they are not mutually exclusive, these flags are typically combined. For example:</p>\n<p><code class=\"western\">O_CREAT | O_TRUNC | O_RDWR</code> : Create a new file if it does not exist otherwise if the file already exists then truncate to zero length. Typically used to overwrite a file or create if it does not already exist.</p>\n<p><code class=\"western\">O_CREAT | OEXCL | O_WRONLY</code> : Create a new file, opening it for write only. Fails if file already exists.</p>\n<p>There are three mode flags that can be controlled or set. These flags may be set by the open that creates the file or later by the <code class=\"western\">yaffs_chmod()</code>.</p>\n<table cellpadding=\"4\" style=\"width: 100%; border-spacing: 0px;\">\n<col width=\"59*\" /> <col width=\"197*\" />\n<tr valign=\"top\">\n <td style=\"border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0.1cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 23%;\">\n <p><span style=\"font-family: Courier New, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><code class=\"western\">S_IREAD</code></span></span></p>\n  </td>\n <td style=\"border: 1px solid #000000; padding: 0.1cm; width: 77%;\">\n <p>The file may be opened for read access.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 23%;\">\n <p><span style=\"font-family: Courier New, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><code class=\"western\">S_IWRITE</code></span></span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 77%;\">\n <p>The file may be opened for write access.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 23%;\">\n <p><span style=\"font-family: Courier New, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><code class=\"western\">S_IEXEC</code></span></span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 77%;\">\n <p>The file may be opened for execution. This is not enforced by yaffs.</p>\n  </td>\n</tr>\n</table>\n<p><br />\n<br />\n</p>\n<p>Once you have opened a handle you can then do various operations on the file.</p>\n<table cellpadding=\"4\" style=\"width: 605px; border-spacing: 0px;\">\n<col width=\"248\" /> <col width=\"339\" />\n<tr valign=\"top\">\n <td style=\"border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0.1cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 248px;\">\n <p><span style=\"font-family: Courier New, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><code class=\"western\">yaffs_close(handle)</code></span></span></p>\n  </td>\n <td style=\"border: 1px solid #000000; padding: 0.1cm; width: 339px;\">\n <p>Close the handle. It is no longer usable.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 248px;\">\n <p><span style=\"font-family: Courier New, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><code class=\"western\">yaffs_fsync(handle)</code></span></span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 339px;\">\n <p>Flush out any cached writes to the file, as well as the file meta-data.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 248px;\">\n <p><span style=\"font-family: Courier New, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><code class=\"western\">yaffs_datasync(handle)</code></span></span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 339px;\">\n <p>Same as yaffs_fsync() but no file metadata.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 248px;\">\n <p><span style=\"font-family: Courier New, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><code class=\"western\">yaffs_flush(handle)</code></span></span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 339px;\">\n <p>Same as yaffs_fsync()</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 248px;\">\n <p><span style=\"font-family: Courier New, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><code class=\"western\">yaffs_dup(handle)</code></span></span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 339px;\">\n <p>Duplicates a handle.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 248px;\">\n <p><span style=\"font-family: Courier New, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><code class=\"western\">yaffs_lseek(handle, offset, whence)</code></span></span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 339px;\">\n <p>Set the handle read/write position. Note that this does not modify the file. You can seek past the end of the file. This does not modify the file size.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 248px;\">\n <p><span style=\"font-family: Courier New, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><code class=\"western\">yaffs_ftruncate(handle, size)</code></span></span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 339px;\">\n <p>Change the file size. It can be made bigger or smaller. This does not change the handle read/write position.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 248px;\">\n <p><span style=\"font-family: Courier New, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><code class=\"western\">yaffs_fstat(handle, buf)</code></span></span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 339px;\">\n <p>Get file status.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 248px;\">\n <p><span style=\"font-family: Courier New, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><code class=\"western\">yaffs_fchmod(handle, mode)</code></span></span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 339px;\">\n <p>Change the file mode.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 248px;\">\n <p><br />\n  </p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 339px;\">\n <p><br />\n  </p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 248px;\">\n <p><span style=\"font-family: Courier New, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><code class=\"western\">yaffs_read(handle, buffer, nbytes)</code></span></span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 339px;\">\n <p>Read data from file at file pointer and update pointer.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 248px;\">\n <p><span style=\"font-family: Courier New, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><code class=\"western\">yaffs_pread(handle, buffer, nbytes, position)</code></span></span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 339px;\">\n <p>Read data from file at specified position. Does not modify file pointer</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 248px;\">\n <p><span style=\"font-family: Courier New, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><code class=\"western\">yaffs_write(handle, buffer, nbytes)</code></span></span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 339px;\">\n <p>Write data to file at file pointer and update pointer.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 248px;\">\n <p><span style=\"font-family: Courier New, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><code class=\"western\">yaffs_pread(handle, buffer, nbytes, position)</code></span></span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 339px;\">\n <p>Write data to file at specified position. Does not modify file pointer</p>\n  </td>\n</tr>\n</table>\n<p><br />\n<br />\n</p>\n<h2 class=\"western\">11.7 Changing file size</h2>\n<p class=\"code-western\"><code class=\"western\">yaffs_truncate(path, newSize)</code></p>\n<p class=\"code-western\"><code class=\"western\">yaffs_ftruncate(handle, newSize)</code></p>\n<p><br />\n<br />\n</p>\n<p>These change a file\'s size. Note that truncating does not just mean make the file smaller. The file can also be made larger.</p>\n<p>Yaffs does not store bytes that it does not need to. If you use truncate to make a file larger then this will not necessarily occupt more flash space.</p>\n<p>See also <code class=\"western\">yaffs_lseek()</code> too. Note that <code class=\"western\">yaffs_lseek() </code>only changes the position of the write pointer and does not impact on the file size unless the file is written.</p>\n<p><br />\n<br />\n</p>\n<h2 class=\"western\">11.8 Getting/setting information about files</h2>\n<p class=\"code-western\"><code class=\"western\">yaffs_chmod(path, mode)</code></p>\n<p class=\"code-western\"><code class=\"western\">yaffs_fchmod(handle, mode)</code></p>\n<p class=\"code-western\"><br />\n<br />\n</p>\n<p class=\"code-western\"><code class=\"western\">yaffs_access(path,amode)</code></p>\n<p class=\"code-western\"><br />\n<br />\n</p>\n<p class=\"code-western\"><code class=\"western\">yaffs_stat(path, struct yaffs_stat *buf) </code> </p>\n<p class=\"code-western\"><code class=\"western\">yaffs_fstat(handle, struct yaffs_stat *buf)</code></p>\n<p class=\"code-western\"><code class=\"western\">yaffs_lstat(path, struct yaffs_stat *buf)</code></p>\n<p class=\"code-western\"><code class=\"western\">yaffs_readlink(path, buf, bufsize)</code></p>\n<p><br />\n<br />\n</p>\n<p>The chmod calls allow you to set different mode flags for the file. These can only be used to manipulate the permissions flags and not change the mode flags relating to the type of file.</p>\n<p><code class=\"western\">yaffs_access() </code>tests that the file can be accessed in the specified mode. This call returns zero on success and -1 is returned</p>\n<p>amode is a bitmask of the following values:</p>\n<table cellpadding=\"4\" style=\"width: 100%; border-spacing: 0px;\">\n<col width=\"43*\" /> <col width=\"213*\" />\n<tr valign=\"top\">\n <td style=\"border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0.1cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 17%;\">\n <p><span style=\"font-family: Courier New, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><code class=\"western\">R_OK</code></span></span></p>\n  </td>\n <td style=\"border: 1px solid #000000; padding: 0.1cm; width: 83%;\">\n <p>Check read is OK</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 17%;\">\n <p><span style=\"font-family: Courier New, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><code class=\"western\">W_OK</code></span></span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 83%;\">\n <p>Check write is OK</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 17%;\">\n <p><span style=\"font-family: Courier New, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><code class=\"western\">X_OK</code></span></span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 83%;\">\n <p>Check execute is OK.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 17%;\">\n <p><span style=\"font-family: Courier New, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><code class=\"western\">0 (zero)</code></span></span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 83%;\">\n <p>Just checks the file exists</p>\n  </td>\n</tr>\n</table>\n<p>These can be combined.</p>\n<p>For example:</p>\n<p class=\"code-western\"><code class=\"western\">if(yaffs_access(path, R_OK | W_OK) == 0)</code></p>\n<p class=\"code-western\"><code class=\"western\">the file exists and can be read and written</code></p>\n<p class=\"code-western\"><code class=\"western\">if(yaffs_access(path, 0) == 0)</code></p>\n<p class=\"code-western\"><code class=\"western\">the file exists</code></p>\n<p><br />\n<br />\n</p>\n<p>The stat calls retrieve a yaffs_stat structure of data which is defined in yaffsfs.h. There are three versions:</p>\n<p><code class=\"western\">yaffs_fstat</code>: Takes a handle.</p>\n<p><code class=\"western\">yaffs_stat</code>: Takes a path name and follows symbolic links.</p>\n<p><code class=\"western\">yaffs_lstat</code>: Takes a path but does not follow symbolic links.</p>\n<p><br />\n<br />\n</p>\n<p>Thus, if path is a symbolic link, <code class=\"western\">yaffs_fstat() </code>will give information on the file that the link points to while <code class=\"western\">yaffs_lstat()</code> will give information about the link itself.</p>\n<p><code class=\"western\">yaffs_readlink()</code> will read the read the link value into the buffer provided. For example:</p>\n<p class=\"code-western\"><code class=\"western\">yaffs_symlink(“target”,”/link”); /* create a link called link to target */</code></p>\n<p class=\"code-western\"><code class=\"western\">yaffs_readlink(“/link”,buffer,10); /* now buffer contains “target” */</code></p>\n<p><br />\n<br />\n</p>\n<h2 class=\"western\">11.9 Changing the directory structure and names</h2>\n<p class=\"code-western\"><code class=\"western\">yaffs_open(path, flags, mode)</code></p>\n<p class=\"code-western\"><code class=\"western\">yaffs_mkdir(path, mode)</code></p>\n<p class=\"code-western\"><code class=\"western\">yaffs_symlink(targetPath, linkPath)</code></p>\n<p class=\"code-western\"><code class=\"western\">yaffs_mknod(pathname, mode, dev)</code></p>\n<p class=\"code-western\"><br />\n<br />\n</p>\n<p class=\"code-western\"><code class=\"western\">yaffs_link(existingPath, newath)</code></p>\n<p class=\"code-western\"><br />\n<br />\n</p>\n<p class=\"code-western\"><code class=\"western\">yaffs_unlink(path)</code></p>\n<p class=\"code-western\"><code class=\"western\">yaffs_rmdir(path)</code></p>\n<p class=\"code-western\"><br />\n<br />\n</p>\n<p class=\"code-western\"><code class=\"western\">yaffs_rename(oldPath, newPath)</code></p>\n<p><br />\n<br />\n</p>\n<p>Files of various types, and their first link, are created via the <code class=\"western\">yaffs_open()</code><code class=\"western\"><span style=\"font-family: Liberation Serif, serif;\"><span style=\"font-weight: normal\">,</span></span></code><span style=\"font-family: Courier New, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"></span></span><code class=\"western\">yaffs_mkdir()</code><span style=\"font-family: Liberation Serif, serif;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\">, </span></span><code class=\"western\">yaffs_symlink()</code> and <code class=\"western\">yaffs_mknod()</code><span style=\"font-family: Liberation Serif, serif;\"><span style=\"font-size: 12pt; font-size: medium; font-size: medium;\"></span></span>functions.</p>\n<p><code class=\"western\">yaffs_link()</code> can be used to create subsequent links to files. Note that you cannot create a link to a directory.</p>\n<p><code class=\"western\">yaffs_rename()</code> allows you to rename a link. Note that renaming one link over another link is an atomic operation. That means that even if the operation is interrupted by a power failure, the result will either complete or not happen at all. If the target link is for a directory, then the rename will only work if the target directory is empty.</p>\n<p><br />\n<br />\n</p>\n<h2 class=\"western\">11.10 Searching directories</h2>\n<p class=\"code-western\"><code class=\"western\">yaffs_DIR *yaffs_opendir(const YCHAR *dirname) ; </code> </p>\n<p class=\"code-western\"><code class=\"western\">struct yaffs_dirent *yaffs_readdir(yaffs_DIR *dirp) ; </code> </p>\n<p class=\"code-western\"><code class=\"western\">void yaffs_rewinddir(yaffs_DIR *dirp) ; </code> </p>\n<p class=\"code-western\"><code class=\"western\">int yaffs_closedir(yaffs_DIR *dirp) ; </code> </p>\n<p><br />\n<br />\n</p>\n<p>Searching is performed by the following sequence of operations:</p>\n<ul>\n<li>\n<p>Open the directory for reading with <code class=\"western\">yaffs_opendir()</code>.</p>\n </li>\n<li>\n<p>Iterate through the entries in the directory using <code class=\"western\">yaffs_readdir()</code>. Each read will advance the directory read position.</p>\n </li>\n<li>\n<p>You can reset to the start of the directory with <code class=\"western\">yaffs_rewinddir()</code>.</p>\n </li>\n<li>\n<p>Close the directory when finished with <code class=\"western\">yaffs_closedir()</code>.</p>\n </li>\n</ul>\n<h2 class=\"western\">11.11 Searching directories (fd interface)</h2>\n<p class=\"code-western\"><code class=\"western\">int </code><code class=\"western\">yaffs_open(const YCHAR *dirname, </code><code class=\"western\">O_RDONLY, 0</code><code class=\"western\">) ; </code> </p>\n<p class=\"code-western\"><code class=\"western\">struct yaffs_dirent *yaffs_readdir_</code><code class=\"western\">fd</code><code class=\"western\">(</code><code class=\"western\">int fd</code><code class=\"western\">) ; </code> </p>\n<p class=\"code-western\"><code class=\"western\">void yaffs_rewinddir_</code><code class=\"western\">fd</code><code class=\"western\">(</code><code class=\"western\">int fd</code><code class=\"western\">) ; </code> </p>\n<p class=\"code-western\"><code class=\"western\">int yaffs_close(</code><code class=\"western\">int fd</code><code class=\"western\">) ; </code> </p>\n<p><br />\n<br />\n</p>\n<p>This is not a POSIX interface, but provides an alternate interface for reading directories.</p>\n<p><br />\n<br />\n</p>\n<p>Searching is performed by the following sequence of operations:</p>\n<ul>\n<li>\n<p>Open the directory for reading with <code class=\"western\">yaffs_open( </code><code class=\"western\">name, O_RDONLY, 0</code><code class=\"western\">)</code>.</p>\n </li>\n<li>\n<p>Iterate through the entries in the directory using <code class=\"western\">yaffs_readdir_</code><code class=\"western\">fd</code><code class=\"western\">()</code>. Each read will advance the directory read position.</p>\n </li>\n<li>\n<p>You can reset to the start of the directory with <code class=\"western\">yaffs_rewinddir_</code><code class=\"western\">fd</code><code class=\"western\">()</code>.</p>\n </li>\n<li>\n<p>Close the directory when finished with <code class=\"western\">yaffs_close()</code>.</p>\n </li>\n</ul>\n<p><br />\n<br />\n</p>\n<h2 class=\"western\">11.12 Mount control and similar</h2>\n<p class=\"code-western\"><code class=\"western\">yaffs_mount(path) ; </code> </p>\n<p class=\"code-western\"><code class=\"western\">yaffs_mount2(path, readOnly); </code> </p>\n<p class=\"code-western\"><code class=\"western\">yaffs_unmount(path);</code></p>\n<p class=\"code-western\"><code class=\"western\">yaffs_unmount2(path, int force); </code> </p>\n<p class=\"code-western\"><code class=\"western\">yaffs_remount(path, force, readOnly);</code></p>\n<p class=\"code-western\"><code class=\"western\">yaffs_sync(path) ;</code></p>\n<p class=\"code-western\"><code class=\"western\">yaffs_format(const YCHAR *path, </code> </p>\n<p><code class=\"western\"></code> <code class=\"western\">int unmount_flag, </code> </p>\n<p><code class=\"western\"></code> <code class=\"western\">int force_unmount_flag, </code> </p>\n<p><code class=\"western\"></code> <code class=\"western\">int remount_flag) </code> </p>\n<p><br />\n<br />\n</p>\n<p>A partition must be mounted to be accessed. <code class=\"western\">yaffs_mount()</code> will mount the partition for read/write access. <code class=\"western\">yaffs_mount2()</code> can be used to control whether the access is read/write or read only.</p>\n<p>A partition can be unmounted to remove it from use. <code class=\"western\">yaffs_unmount()</code> will fail if any files are in use whereas <code class=\"western\">yaffs_unmount2()</code> allows you to force the unmount even if files are open. Note that any file handles will then be broken and will no longer access the files.</p>\n<p><code class=\"western\">yaffs_remount()</code> can be used to change the access to a currently mounted partition and is equivalent to making an <code class=\"western\">unmount2()</code> call followed by a <code class=\"western\">mount2()</code> call.</p>\n<p><code class=\"western\">yaffs_sync()</code> does not change the mount status but flushes out any pending data on a partition that is mounted with write access.</p>\n<p><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>yaffs_format()</b></span></span> provides a mechanism to format a device. It has various parameters.<br />\n<span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>unmount_flag</b></span></span>: If set, yaffs_format() will unmount the device before formatting. If this flag is not set and the device is mounted, then the format will fail with EBUSY.</p>\n<p><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>force_unmount</b></span></span>: If set, then an unmount is allowed even if the device is busy (eg. files open). If not set, then yaffs_format() will fail (EBUSY) if files are open.</p>\n<p><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>remount_flag</b></span></span>: If set, then the device will be remounted after the format if it was mounted.</p>\n<p>The force_unmount and remount_flag options only have meaning if unmount_flag is set.</p>\n<h2 class=\"western\">11.13 Extended attributes (xattrt)</h2>\n<p>Extended attributes provide a mechanism to attach a limited amount of extra data to a file without actually modifying the file. Each xattribute is a named pair of name and some data. Each file can have as many xattribs as there is space for. In Yaffs, this is around chunk-size – 512 bytes. So on devices with 2kbyte chunks you can store up to 1.5kbytes of xattribute information.</p>\n<p>Although there are 12 xattr functions, there are really only four basic functions, each with 3 different flavours.</p>\n<p>The basic functions are: set an xattr, get an xattr, remove an xattribute and list the xattribute names.</p>\n<p class=\"code-western\">int yaffs_setxattr(const char *path, const char *name, </p>\n<p class=\"code-western\">const void *data, int size, int flags); </p>\n<p class=\"code-western\">int yaffs_lsetxattr(const char *path, const char *name, </p>\n<p class=\"code-western\">const void *data, int size, int flags); </p>\n<p class=\"code-western\">int yaffs_fsetxattr(int fd, const char *name, </p>\n<p class=\"code-western\">const void *data, int size, int flags); </p>\n<p>These functions are called with name being the name of the xattr, a pointer to the data and the size of the data, and flags.</p>\n<p>The flags are:</p>\n<p>XATTR_CREATE: Create a new xattr, fail with -EEXIST if the xattrib already exists.</p>\n<p>XATTR_REPLACE: Replace an existing xattr, fail with -ENOATTR if it does not exist.</p>\n<p>zero: Just create with no checks, replace if it already exists.</p>\n<p><br />\n<br />\n</p>\n<p>Setting can fail with -ENOSPC if there is not enough space to store the xattrib.</p>\n<p><br />\n<br />\n</p>\n<p class=\"code-western\">int yaffs_getxattr(const char *path, const char *name, </p>\n<p class=\"code-western\">void *data, int size); </p>\n<p class=\"code-western\">int yaffs_lgetxattr(const char *path, const char *name, </p>\n<p class=\"code-western\">void *data, int size); </p>\n<p class=\"code-western\">int yaffs_fgetxattr(int fd, const char *name, </p>\n<p class=\"code-western\">void *data, int size); </p>\n<p>These get (fetch) an xattrib.</p>\n<p>If the call succeeds, the length of the retrieved xattrib is returned. This call can fail with -ENOATTR if the requested xattr does not exist or -ERANGE if the buffer was too small.</p>\n<p><br />\n<br />\n</p>\n<p class=\"code-western\">int yaffs_removexattr(const char *path, const char *name); </p>\n<p class=\"code-western\">int yaffs_lremovexattr(const char *path, const char *name); </p>\n<p class=\"code-western\">int yaffs_fremovexattr(int fd, const char *name); </p>\n<p>These functions delete an existing xattr. If the xattr does not exist then -ENOATTR is returned.</p>\n<p><br />\n<br />\n</p>\n<p class=\"code-western\">int yaffs_listxattr(const char *path, char *list, int size); </p>\n<p class=\"code-western\">int yaffs_llistxattr(const char *path, char *list, int size); </p>\n<p class=\"code-western\">int yaffs_flistxattr(int fd, char *list, int size); </p>\n<p>These functions fetch a list of the xattrib names into the list buffer. The names are NUL terminated. eg. “attrib0\\0attrib1\\0...”.</p>\n<p>The function returns the length of the list, otherwise if the list buffer is too short it returns -ERANGE.</p>\n<p>Note: If you call these functions with a list buffer size of zero, this acts as a query of the required buffer size. No data is actually transferred into the list.</p>\n<p><br />\n<br />\n</p>\n<p>For example we might choose to add some xattribs to a media file:</p>\n<p class=\"code-western\">//Set description</p>\n<p class=\"code-western\">yaffs_fsetxattr(fd, “user-comment”, “I hate this song!”,18);</p>\n<p class=\"code-western\">yaffs_fsetxattr(fd, “price-in-cents”, &amp;cost, sizeof(cost));</p>\n<p class=\"code-western\">// Get the comment</p>\n<p class=\"code-western\">yaffs_fgetxattr(fd, “user_comment”, buffer, sizeof(buffer);</p>\n<p class=\"code-western\"><br />\n<br />\n</p>\n<p class=\"code-western\">//List the attributes in a NUL delimited list</p>\n<p class=\"code-western\">yaffs_flistxattr(fd, list_buf, sizeof(list_buf));</p>\n<p class=\"code-western\">// Now list_buf has user-comment\\0price-in-cents\\0</p>\n<p class=\"code-western\">yaffs_fremovexattr(fd, ”user-comment”);</p>\n<p><br />\n<br />\n</p>\n<h2 class=\"western\">11.14 Other</h2>\n<p class=\"code-western\"><code class=\"western\">yaffs_freespace(path); </code> </p>\n<p class=\"code-western\"><code class=\"western\">yaffs_totalspace(path); </code> </p>\n<p class=\"code-western\"><code class=\"western\">yaffs_inodecount(path); </code> </p>\n<p><br />\n<br />\n</p>\n<p>These functions provide information on the free and total space (in bytes) for the mount that the path addresses.</p>\n<p><code class=\"western\">yaffs_inodecount()</code> returns the number of files on the mount that the path addresses.</p>\n<h1 class=\"western\" style=\"page-break-before: always\">12 Example: yaffs_readdir() and yaffs_stat()</h1>\n<p>This code snippet illustrates using <code class=\"western\">yaffs_readdir()</code> and associated functions to iterate through a directory. It also shows how to use <code class=\"western\">yaffs_lstat() </code>to get information on a file and interpret it.</p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\">void dump_directory(const char *dname) </span></code> </p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\">{ </span></code> </p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\">yaffs_DIR *d; </span></code> </p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\">yaffs_dirent *de; </span></code> </p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\">struct yaffs_stat s; </span></code> </p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\">char str[100]; </span></code> </p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"></span></code> </p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\">d = yaffs_opendir(dname); </span></code> </p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"></span></code> </p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\">if(!d) { </span></code> </p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\">printf(&quot;opendir failed\\n&quot;); </span></code> </p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\">} else { </span></code> </p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\">while((de = yaffs_readdir(d)) != NULL) { </span></code> </p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\">sprintf(str,&quot;%s/%s&quot;,dname,de-&gt;d_name); </span></code> </p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"></span></code> </p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\">yaffs_lstat(str,&amp;s); </span></code> </p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"></span></code> </p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\">printf(&quot;%s inode %d length %d mode %X &quot;,</span></code></p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\">str,s.st_ino,(int)s.st_size,s.st_mode); </span></code> </p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\">switch(s.st_mode &amp; S_IFMT) { </span></code> </p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\">case S_IFREG: printf(&quot;data file&quot;); break; </span></code> </p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\">case S_IFDIR: printf(&quot;directory&quot;); break; </span></code> </p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\">case S_IFLNK: printf(&quot;symlink --&gt;&quot;); </span></code> </p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\">if(yaffs_readlink(str,str,100) &lt; 0) </span></code> </p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\">printf(&quot;no alias&quot;); </span></code> </p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\">else </span></code> </p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\">printf(&quot;\\&quot;%s\\&quot;&quot;,str);</span></code></p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\">break; </span></code> </p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\">default: printf(&quot;unknown&quot;); break; </span></code> </p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\">}</span></code></p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\">printf(&quot;\\n&quot;); </span></code> </p>\n<p class=\"code-western\"><br />\n<br />\n</p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\">if((s.st_mode &amp; S_IFMT) == S_IFDIR)</span></code></p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\">dump_directory_tree_worker(str); </span></code> </p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\">} </span></code> </p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"></span></code> </p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\">yaffs_closedir(d); </span></code> </p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\">} </span></code> </p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\">} </span></code> </p>\n<p><br />\n<br />\n</p>\n</div>\n      \";}s:9:\"#attached\";a:0:{}s:6:\"#cache\";a:3:{s:8:\"contexts\";a:5:{i:0;s:28:\"languages:language_interface\";i:1;s:5:\"theme\";i:2;s:8:\"timezone\";i:3;s:17:\"url.path.is_front\";i:4;s:16:\"user.permissions\";}s:4:\"tags\";a:5:{i:0;s:29:\"config:filter.format.raw_html\";i:1;s:7:\"file:80\";i:2;s:8:\"node:453\";i:3;s:9:\"node_view\";i:4;s:6:\"user:1\";}s:7:\"max-age\";i:-1;}}',-1,1504783535.921,1,'config:filter.format.raw_html file:80 node:453 node_view rendered user:1','269'),('entity_view:node:453:rss:[languages:language_interface]=en:[theme]=yaffs:[user.permissions]=aa7fc4c8fb40c7a8665ccd12fea07926dff0f59b9ee3346bc513c6399bee5b01','a:2:{s:15:\"#cache_redirect\";b:1;s:6:\"#cache\";a:5:{s:4:\"keys\";a:4:{i:0;s:11:\"entity_view\";i:1;s:4:\"node\";i:2;s:3:\"453\";i:3;s:3:\"rss\";}s:8:\"contexts\";a:5:{i:0;s:28:\"languages:language_interface\";i:1;s:5:\"theme\";i:2;s:8:\"timezone\";i:3;s:17:\"url.path.is_front\";i:4;s:16:\"user.permissions\";}s:4:\"tags\";a:5:{i:0;s:29:\"config:filter.format.raw_html\";i:1;s:7:\"file:80\";i:2;s:8:\"node:453\";i:3;s:9:\"node_view\";i:4;s:6:\"user:1\";}s:7:\"max-age\";i:-1;s:3:\"bin\";s:6:\"render\";}}',-1,1504783535.907,1,'config:filter.format.raw_html file:80 node:453 node_view rendered user:1','269'),('entity_view:node:453:search_result:[languages:language_interface]=en:[theme]=yaffs:[url.path.is_front]=is_front.0:[user.permissions]=aa7fc4c8fb40c7a8665ccd12fea07926dff0f59b9ee3346bc513c6399bee5b01','a:3:{s:7:\"#markup\";O:25:\"Drupal\\Core\\Render\\Markup\":1:{s:9:\"\0*\0string\";s:145559:\"<span>Yaffs Direct Interface</span>\n\n      <div class=\"field field--name-upload field--type-file field--label-hidden field--items\">\n              <div class=\"field--item\"><span class=\"file file--mime-application-pdf file--application-pdf icon-before\"><span class=\"file-icon\"><span class=\"icon glyphicon glyphicon-file text-primary\" aria-hidden=\"true\"></span></span><span class=\"file-link\"><a href=\"https://yaffs.net/sites/default/files/downloads/YaffsDirect.pdf\" type=\"application/pdf; length=256079\" title=\"Open file in new window\" target=\"_blank\" data-toggle=\"tooltip\" data-placement=\"bottom\">YaffsDirect.pdf</a></span><span class=\"file-size\">250.08 KB</span></span></div>\n          </div>\n  \n            <div class=\"field field--name-body field--type-text-with-summary field--label-hidden field--item\">\n<p>This document describes the Yaffs Direct Interface (YDI), which allows Yaffs to be simply integrated with embedded systems, with or without an RTOS.</p>\n<p style=\"page-break-before: always\"><br />\n<br />\n</p>\n<h1 class=\"western\" style=\"page-break-before: always\">1 Background</h1>\n<p>The purpose of this document is to describe the interfacing of the Yaffs Direct Interface (YDI) as well as to provide sufficient information to allow a preliminary evaluation of Yaffs. This document tries to focus on the issues important to the system integrator without getting too detailed about how Yaffs works. Other documents provide an in-depth discussion of how Yaffs works.</p>\n<h1 class=\"western\">2 Licensing</h1>\n<p>Yaffs was originally released for Linux under the GNU Public License (GPL). Various embedded developers soon identified that Yaffs would be ideal for their applications, but were not able to use GPL based code in their systems. Aleph One <span style=\"font-style: normal\"><span style=\"font-weight: normal\">has</span></span> alternative licensing arrangements to support such applications.</p>\n<h1 class=\"western\">3 What are Yaffs and Yaffs Direct Interface?</h1>\n<p>Yaffs stands for <i>Yet Another Flash File System</i>. Yaffs was the first file system designed, from the ground up, for NAND storage.</p>\n<p>In 2002 Aleph One set out to identify file system options for using NAND Flash as a file system. Various file systems available at the time were evaluated and all were found lacking in one way or another. The need for a suitable NAND storage file system was identified and Yaffs was designed to fill that need.</p>\n<p>Although Yaffs was originally designed for NAND flash, it has been used successfully with NOR flash systems and even as a RAM file system. This allows high reliability file systems to be constructed using NOR flash, with a future migration path <span style=\"font-weight: normal\">to NAND</span> flash for higher density and performance.</p>\n<p>Yaffs was originally designed for use with the Linux operating system, but was designed in a very modular way. The operating-system-specific code was kept separate from the main Yaffs file system code. This allows Yaffs to be ported quite cleanly to other operating systems through operating system personality modules. One such personality module is the Yaffs Direct Interface (YDI) which allows Yaffs to be simply integrated with embedded systems, with or without an RTOS. </p>\n<p>Yaffs has been used for many products using various operating systems including Windows CE and various RTOSs, including <span style=\"font-weight: normal\">ThreadX, vXworks, pSOS to name just a few.</span></p>\n<p>Note that there is a native port of Yaffs to eCOS that does not use YDI. This is supported and distributed by eCocCentric.(http://www.ecoscentric.com/).</p>\n<p>Yaffs2, a more recent release of Yaffs, supports a wider range of NAND flash components including 2k page devices and devices with multi-level cells (MLC), and produces equivalent or better performance. It include Yaffs1 compatibility code so Yaffs1 images still work and migration is quite simple. Yaffs1 or Yaffs2 mode of operation are simply selected by a run-time parameter.</p>\n<p>As well as providing a NAND file system, YDI also provides a RAM emulation layer to allow Yaffs to operate as a RAM file system too. While the RAM emulation is perhaps not as efficient as a dedicated RAM file system, this does allow one well proven file system to use both RAM and flash.</p>\n<h1 class=\"western\">4 Why use Yaffs?</h1>\n<p>Yaffs is the first, and perhaps only, file system designed specifically for NAND flash. This means that Yaffs has been designed to work around the various limitations and quirks of NAND flash, as well as exploit the various features of NAND to achieve an effective file system.</p>\n<p>Some features to consider:</p>\n<ul>\n<li>\n<p>Yaffs has been well proven and has been used to ship in <span style=\"font-weight: normal\">large volumes in several products using many different operating systems, compilers and processors.</span></p>\n </li>\n<li>\n<p>Yaffs is written in portable C and is endian neutral.</p>\n </li>\n<li>\n<p>Yaffs provides <span style=\"font-weight: normal\">bad</span> <b></b><span style=\"font-weight: normal\">block</span> handling and ECC algorithms to handle deficiencies in NAND flash.</p>\n </li>\n<li>\n<p>Yaffs is a log-structured file system which makes it very robust to corruptions caused by power failures etc.</p>\n </li>\n<li>\n<p>Yaffs has highly optimised and predictable garbage collection strategies. This makes it high performance and very deterministic when compared with similar file systems.</p>\n </li>\n<li>\n<p>Yaffs has a lower memory footprint than most other log-structured flash file systems.</p>\n </li>\n<li>\n<p>Yaffs provides a wide range of POSIX-style file system support including directories, symbolic and hard links etc. through standard file system interface calls.</p>\n </li>\n<li>\n<p><span style=\"font-weight: normal\">Yaffs is h</span>ighly configurable to work with various flash geometries, various ECC options, caching options etc.</p>\n </li>\n<li>\n<p>Yaffs Direct Interface is simple to integrate in a system – only a few interface functions are required.</p>\n </li>\n<li>\n<p>Yaffs can be used with a wide range of memory technologies.</p>\n </li>\n</ul>\n<h1 class=\"western\">5 Source Code and Yaffs Resources </h1>\n<p><span style=\"font-family: Liberation Serif, serif;\">Please note the licensing terms that apply to using the Yaffs code.</span></p>\n<p><a href=\"http://www.yaffs.net/\"><span style=\"font-family: Liberation Serif, serif;\">http://www.yaffs.net</span></a><span style=\"font-family: Liberation Serif, serif;\"><span style=\"font-style: normal\"><span style=\"font-weight: normal\">serves as the hub for all Yaffs information.</span></span></span></p>\n<p><span style=\"font-family: Liberation Serif, serif;\">This document refers to the Yaffs source code extensively.<span style=\"font-style: normal\"><span style=\"font-weight: normal\">and is available via the download link on this site.</span></span></span></p>\n<p><span style=\"font-family: Liberation Serif, serif;\">There are various other documents and a Yaffs mailing list for Yaffs discussions.</span></p>\n<p><span style=\"font-family: Liberation Serif, serif;\">Consulting services are also available.</span></p>\n<h1 class=\"western\">6 System Requirements</h1>\n<p>Determining minimum system requirements is often quite difficult. The following are presented as a guideline only. Contact Aleph One for more detailed analysis if required.</p>\n<ul>\n<li>\n<p>Yaffs is endian-neutral and works fine with little-endian and big-endian processors.</p>\n </li>\n<li>\n<p>Yaffs code has been used successfully with many different 32-bit and 64-bit CPUs including MIPS, 68000, ARM, ColdFire, PowerPC and x86 variants. Yaffs has even been used with various DSP architectures. Yaffs should work with 16-bit CPUs too, but this is generally untested and might need some tuning, depending on compiler options.</p>\n </li>\n<li>\n<p>Because Yaffs is log structured, RAM is required to build up runtime data structures for acceptable performance. As a rule of thumb, budget approximately 2 bytes per <i>chunk</i> of NAND flash, where a <i>chunk</i> is typically one page of NAND. For NAND with 512byte pages, budget approximately 4kbytes of RAM per 1Mbyte of NAND. For 2kbyte page devices budget approximately 1kbyte per 1Mbyte of NAND.</p>\n </li>\n</ul>\n<h1 class=\"western\">7 How to integrate Yaffs with an RTOS/Embedded system</h1>\n<p>Yaffs Direct Interface (YDI) wraps Yaffs in a way that is simple to integrate. You need to provide a few functions for Yaffs to use to talk to your hardware and RTOS. Yaffs provides a set of POSIX-compliant functions for applications to use to talk to it.</p>\n<p>In addition to the Yaffs core file system, the YDI has three parts which are each explained in more detail in further sections:</p>\n<ul>\n<li>\n<p><b>POSIX Application Interface</b>: This is the POSIX-like interface that the application code uses to access the Yaffs file system. (<span style=\"font-family: Times New Roman;\"><i>open, close, read, write, </i></span>etc) </p>\n </li>\n<li>\n<p><b>RTOS Integration Interface</b>: These are the functions that must be provided for Yaffs to access the RTOS system resources. (<span style=\"font-family: Times New Roman;\"><i>initialise, lock, unlock, get time, </i></span><span style=\"font-family: Times New Roman;\"><i>memory allocation,</i></span><span style=\"font-family: Times New Roman;\"><i>set error, </i></span><span style=\"font-family: Times New Roman;\"><i>etc</i></span>). Note that although we use the term RTOS, the same can be done with other OSs or even with no RTOS at all in a bare-metal system.</p>\n </li>\n<li>\n<p><img src=\"data:image/png;base64,[encoded data, 27864 characters]\" width=\"485\" height=\"530\" alt=\"image\" /> <b>Flash Device </b><b>Interface</b>: This interface support is where the flash device and appropriate device drivers are installed to provide an access path from Yaffs to the flash device(s). Multiple different devices and device types can be supported simultaneously.</p>\n </li>\n</ul>\n<h2 class=\"western\">7.1 Source Files</h2>\n<p>The following source files contain the core file system:</p>\n<table cellpadding=\"4\" style=\"width: 100%; border-spacing: 0px;\">\n<col width=\"71*\" /> <col width=\"185*\" />\n<tr valign=\"top\">\n <td style=\"border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0.1cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 28%;\">\n <p>yaffs_allocator.c</p>\n  </td>\n <td style=\"border: 1px solid #000000; padding: 0.1cm; width: 72%;\">\n <p>Allocates Yaffs object and tnode structures.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 28%;\">\n <p><br />\n  </p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 72%;\">\n <p><br />\n  </p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 28%;\">\n <p>yaffs_bitmap.c</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 72%;\">\n <p>Block and chunk bitmap handling code.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 28%;\">\n <p>yaffs_checkpointrw.c</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 72%;\">\n <p>Streamer for writing checkpoint data</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 28%;\">\n <p>yaffs_ecc.c</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 72%;\">\n <p>1-bit Hamming ECC code</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 28%;\">\n <p><br />\n  </p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 72%;\">\n <p><br />\n  </p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 28%;\">\n <p>yaffs_guts.c</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 72%;\">\n <p>The major Yaffs algorithms.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 28%;\">\n <p>yaffs_nameval.c</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 72%;\">\n <p>Name/value code for handling extended attributes (xattr).</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 28%;\">\n <p>yaffs_nand.c</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 72%;\">\n <p>Flash interfacing abstraction.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 28%;\">\n <p>yaffs_packedtags1.c<br />\n  yaffs_packedtags2.c</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 72%;\">\n <p>Tags packing code</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 28%;\">\n <p>yaffs_summary.c</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 72%;\">\n <p>Code for handling block summaries.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 28%;\">\n <p>yaffs_tagscompat.c</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 72%;\">\n <p>Tags compatibility code to support Yaffs1 mode.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 28%;\">\n <p>yaffs_tagsmarshall.c</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 72%;\">\n <p>Tags marshalling code.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 28%;\">\n <p>yaffs_verify.c</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 72%;\">\n <p>Test verification code.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 28%;\">\n <p>yaffs_yaffs1.c</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 72%;\">\n <p>Yaffs1-mode specific code.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 28%;\">\n <p>yaffs_yaffs2.c</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 72%;\">\n <p>Yaffs2-mode specific code.</p>\n  </td>\n</tr>\n</table>\n<p><br />\n<br />\n</p>\n<p>The Yaffs direct interface is in yaffsfs.c, with the interface functions and structures defined in yaffsfd.h.</p>\n<p><br />\n<br />\n</p>\n<table cellpadding=\"4\" style=\"page-break-inside: avoid; width: 100%; border-spacing: 0px;\">\n<col width=\"72*\" /> <col width=\"184*\" />\n<tr valign=\"top\">\n <td style=\"border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0.1cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 28%;\">\n <p>yaffs_attribs.c</p>\n  </td>\n <td style=\"border: 1px solid #000000; padding: 0.1cm; width: 72%;\">\n <p>Attribute handling.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 28%;\">\n <p>yaffs_error.c</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 72%;\">\n <p>Error reporting code.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 28%;\">\n <p>yaffsfs.c</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 72%;\">\n <p>Yaffs Direct Interface wrapper code.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 28%;\">\n <p>yaffs_hweight.c</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 72%;\">\n <p>Counts the number of hot bits in a byte, word etc.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 28%;\">\n <p>yaffs_qsort.c</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 72%;\">\n <p>Qsort used during Yaffs2 scanning</p>\n  </td>\n</tr>\n</table>\n<p><br />\n<br />\n</p>\n<p>Example flash drivers, simulators and configurations used for testing are are in direct/test-framework directory. These include:</p>\n<table cellpadding=\"4\" style=\"page-break-inside: avoid; width: 100%; border-spacing: 0px;\">\n<col width=\"72*\" /> <col width=\"184*\" />\n<tr valign=\"top\">\n <td style=\"border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0.1cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 28%;\">\n <p>nanddrv.c</p>\n  </td>\n <td style=\"border: 1px solid #000000; padding: 0.1cm; width: 72%;\">\n <p>A NAND driver layer that performs the commands to access NAND flash in a rudimentary manner. This code should work on many styles of CPU with little modification.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 28%;\">\n <p>yaffs_nanddrv.c</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 72%;\">\n <p>A wrapper around the NAND driver which plugs it into Yaffs.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 28%;\">\n <p>nandsim.c</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 72%;\">\n <p>A NAND simulator layer that works with a nandstore_xxx backing store. This simulates a NAND chip.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 28%;\">\n <p>nandstore_file.c</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 72%;\">\n <p>A storage backend for a NAND simulator that stores the data to file.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 28%;\">\n <p>nandsim_file.c</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 72%;\">\n <p>A wrapper around nandsim.c and nandstore_file.c which makes a NAND simulator that saves its data in a file.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 28%;\">\n <p>yaffs_nandsim_file.c</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 72%;\">\n <p>A wrapper which creates a nand simulator instance, hooks up the yaffs NAND driver and then adds it to yaffs for use.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 28%;\">\n <p>yaffs_nor_drv.c</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 72%;\">\n <ol>\n </ol>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 28%;\">\n <p>yaffs_m18_drv.c</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 72%;\">\n <p>A driver for Intel M18-style NOR flash.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 28%;\">\n <p>yaffs_osglue.c</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 72%;\">\n <p>An OS glue layer example used in the test harness.</p>\n  </td>\n</tr>\n</table>\n<p><br />\n<br />\n</p>\n<p>Example and testing build files:</p>\n<table cellpadding=\"4\" style=\"width: 100%; border-spacing: 0px;\">\n<col width=\"71*\" /> <col width=\"185*\" />\n<tr valign=\"top\">\n <td style=\"border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0.1cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 28%;\">\n <p>dtest.c</p>\n  </td>\n <td style=\"border: 1px solid #000000; padding: 0.1cm; width: 72%;\">\n <p>A test harness. Also has sample code that can be used for better understanding of how some function calls work.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 28%;\">\n <p>yaffscfg2k.c</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 72%;\">\n <p>A test configuration.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 28%;\">\n <p>yaffs_fileem.c<br />\n  yaffs_fileem2k.c</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 72%;\">\n <p>Nand flash simulation using a file as backing store.</p>\n  </td>\n</tr>\n</table>\n<p><br />\n<br />\n</p>\n<p>Further testing files are in direct/tests and direct/python.</p>\n<h2 class=\"western\" style=\"page-break-before: always\">7.2 Integrating the POSIX Application Interface</h2>\n<p>The application interface is defined in yaffsfs.h. These provide a POSIX file system interface. For the most part, this interface consists of the standard clib function names prefixed with <code class=\"western\">yaffs_</code>. For example, <code class=\"western\">yaffs_open(), yaffs_close()</code> etc.</p>\n<p><br />\n<br />\n</p>\n<p>There is a lot of flexibility in how these functions are used and the system integrator needs to determine the best strategy for the system.</p>\n<p>These functions can be used directly, with the code written using these names. For example</p>\n<p class=\"code-western\"><code class=\"western\">int main(...)<br />\n{<br />\n// initialisation<br />\nf = yaffs_open(...);<br />\nyaffs_read(f,...);<br />\nyaffs_close(f);<br />\n}</code></p>\n<p>The <span style=\"font-family: Times New Roman;\">yaffs</span> functions can also be wrapped in some way to allow existing code to use yaffs without modification. For example:</p>\n<p style=\"margin-bottom: 0cm; orphans: 0; widows: 0; page-break-before: auto; page-break-after: avoid\"><br />\n</p>\n<p class=\"code-western\"><code class=\"western\">#define open(path, oflag, mode) yaffs_open(path, oflag, mode)<br />\n..<br />\n<br />\nint main(...)<br />\n{<br />\n// initialisation<br />\nf = open(...);<br />\nread(f,...);<br />\nclose(f);<br />\n}</code><br />\n<br />\n<br />\n</p>\n<p style=\"margin-bottom: 0cm; orphans: 0; widows: 0; page-break-before: auto\"><br />\n</p>\n<p>A more complex approach that can be used if more than one file-system is used is to provide redirection functions. For example:</p>\n<p style=\"margin-bottom: 0cm; orphans: 0; widows: 0; page-break-before: auto; page-break-after: avoid\"><br />\n</p>\n<p class=\"code-western\"><code class=\"western\">int open(const char *path,...)<br />\n{<br />\n// Determine which file system is being used<br />\n</code><code class=\"western\">i</code><code class=\"western\">f(it_is_a_yaffs_path(path))<br />\nreturn yaffs_open(...);<br />\nelse {<br />\n// Do something else<br />\n}<br />\n}</code></p>\n<p style=\"margin-left: 1.25cm; margin-bottom: 0cm; page-break-inside: avoid; orphans: 0; widows: 0; page-break-before: auto; page-break-after: auto\"><br />\n</p>\n<p><br />\n<br />\n</p>\n<p>Some RTOS\'s provide a flexible way to integrate file systems in which case YDI can typically use these interfaces to access yaffs file systems.</p>\n<h1 class=\"western\" style=\"page-break-before: always\">8 RTOS Integration Interface</h1>\n<p>Before Yaffs can be used, it needs to be integrated with the system and configured so that the correct actions are performed.</p>\n<p>To do this, you need to modify the configuration file. An example configuration file is presented in <span style=\"font-family: Bitstream Vera Sans;\"><span style=\"font-family: Times New Roman;\">yaffscfg.c and yaffscfg2k.c.</span></span></p>\n<p>This is a relatively straight forward process and defines the RTOS access functions.</p>\n<p>The RTOS access functions are:</p>\n<ul>\n<li>\n<p><code class=\"western\">void yaffsfs_SetError(int err)</code>: Called by Yaffs to set the system error.</p>\n </li>\n<li>\n<p><code class=\"western\">void yaffsfs_Lock(void)</code>: Called by Yaffs to lock Yaffs from multi-threaded access.</p>\n </li>\n<li>\n<p><code class=\"western\">void yaffsfs_Unlock(void)</code>: Called by Yaffs to unlock Yaffs.</p>\n </li>\n<li>\n<p><code class=\"western\">u32 yaffsfs_CurrentTime(void)</code>: Get current time from RTOS.</p>\n </li>\n<li>\n<p><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>void *yaffsfs_malloc(size_t size)</b></span></span>: Called to allocate memory.</p>\n </li>\n<li>\n<p><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>void yaffsfs_free(void *ptr)</b></span></span>: Called to free memory.</p>\n </li>\n<li>\n<p><code class=\"western\">void yaffsfs_</code><code class=\"western\">OS</code><code class=\"western\">Initialisation(void)</code>: Called to initialise RTOS context.</p>\n </li>\n<li>\n<p><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>void yaffs_bug_fn(const char *file_name, int line_no)</b></span></span>: Function to report a bug.</p>\n </li>\n<li>\n<p><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>int yaffsfs_CheckMemRegion(const void *addr, size_t size, int writ</b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>e_request</b></span></span>) : Function to check if accesses to a memory region is valid. This function must return zero if the test passes and negative if it fails.</p>\n </li>\n</ul>\n<p><br />\n<br />\n</p>\n<p>If Yaffs is being used in a multi-threaded environment, then typically <code class=\"western\">yaffs_LocalInitialisation()</code> will initialise a suitable RTOS semaphore and <code class=\"western\">yaffs_Lock()</code> and <code class=\"western\">yaffs_Unlock()</code> will call the appropriate functions to lock and release the semaphore.</p>\n<p><code class=\"western\">yaffs_CurrentTime()</code> can be any time increment of use to the system. If this is not required, then it is fine to just use a function that is hard-wired to return zero.</p>\n<p>Before the application code uses Yaffs, the <code class=\"western\">yaffs</code><code class=\"western\">fs</code><code class=\"western\">_</code><code class=\"western\">OSInitialisation</code><code class=\"western\">()</code> function must be called.</p>\n<p><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>yaffsfs_CheckMemRegion()</b></span></span><span style=\"font-family: Liberation Serif, serif;\"><span style=\"font-size: 12pt; font-size: medium; font-size: medium;\"><span style=\"font-weight: normal\">is used to check addresses passed to the various yaffs_xxx functions (yaffs_open(), yaffs_read() etc)). If the function returns -1, then the yaffs_xxx function will return -EFAULT rather than attempt to dereference the address and crash.</span></span></span></p>\n<p style=\"font-weight: normal\"><span style=\"font-family: Liberation Serif, serif;\"><span style=\"font-size: 12pt; font-size: medium; font-size: medium;\">An implementation might do something like:</span></span></p>\n<p style=\"font-weight: normal\"><br />\n<br />\n</p>\n<p class=\"code-western\"><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>int yaffsfs_CheckMemRegion(const void addr, size_t size, <br />\nint write_</b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>request</b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>) <br />\n{<br />\nu32 uaddr</b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>b</b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>= (u32) addr;<br />\n</b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>u32 uaddrt = uaddrb + size -1;<br />\n</b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b><br />\nif( uaddr</b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>b</b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>&gt;= stack_bottom &amp;&amp; uaddr</b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>b</b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>&lt;= stack_top &amp;&amp;<br />\n</b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>uaddrt &gt;= stack_bottom &amp;&amp; uaddrt &lt;= stack_top)<br />\nreturn 0; /* </b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>r/w </b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>access is OK */<br />\n</b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b><br />\nif( uaddr</b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>b</b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>&gt;= </b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>heap</b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>_bottom &amp;&amp; uaddr</b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>b</b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>&lt;= </b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>heap</b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>_top &amp;&amp;<br />\n</b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>uaddrt &gt;= heap_bottom &amp;&amp; uaddrt &lt;= heap_top)<br />\nreturn 0; /* </b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>r/w</b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>access is OK /<br />\n</b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b><br />\nif( !</b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>write_request &amp;&amp;<br />\n</b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>uaddr</b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>b</b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>&gt;= </b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>rom</b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>_bottom &amp;&amp; uaddr</b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>b</b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>&lt;= </b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>rom</b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>_top &amp;&amp;<br />\n</b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>uaddrt &gt;= rom_bottom &amp;&amp; uaddrt &lt;= rom_top)<br />\nreturn 0; / </b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>read </b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>access is OK /</b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b><br />\n<br />\n</b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>return -1; /* Bad access */</b></span></span><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b><br />\n<br />\n}</b></span></span></p>\n<p class=\"code-western\"><br />\n<br />\n</p>\n<h1 class=\"western\" style=\"page-break-before: always\">9 Yaffs NAND Model</h1>\n<p>Before defining the flash integration interface, it is important to understand the model and corresponding nomenclature used throughout Yaffs and its documentation.</p>\n<p>Yaffs uses a fairly abstract model for NAND flash. This allows a lot of flexibility in the way it can be used.</p>\n<p>Yaffs is designed for NAND flash and makes the following assumptions and definitions:</p>\n<ul>\n<li>\n<p>The flash is arranged in <i><b>blocks</b></i>. Each block is the same size and comprises an integer number of <span style=\"font-style: normal\"><span style=\"font-weight: normal\">chunks</span></span>. Each block is treated as a single erasable item. A block contains a number of chunks.</p>\n </li>\n<li>\n<p>A <i><b>chunk</b></i> equates to the allocation units of flash. For Yaffs1, each chunk equates to a 512-byte or larger NAND page (that is, a 512-byte or larger data portion and a 16-byte spare area). For Yaffs2, a chunk will typically be larger (eg. on 2k page devices, a chunk will typically be a single 2k page: 2kbytes of data and 64 bytes of spare). Yaffs2 is capable of working with smaller chunk sizes by using inband tags.</p>\n </li>\n<li>\n<p>All accesses (reads and writes) are page chunk aligned. Some reads might only read the spare area where the tags are kept.</p>\n </li>\n<li>\n<p>When programming a NAND flash, only the zero bits in the pattern being programmed are relevant, and one bits are &quot;don\'t care&quot;. For example, if a byte already contains the binary pattern b1010, then programming b1001 will result in the pattern which is the logical AND of these two patterns ie. b1000. This is different to NOR flash which would typically abort the attempt to convert a 0 into a 1.</p>\n </li>\n</ul>\n<p><br />\n<br />\n</p>\n<p>Yaffs ide<span style=\"font-weight: normal\">ntifies</span> blocks by their block number and chunks by the chunk Id. A chunk Id is calculated as:</p>\n<p><code class=\"western\">chunkId = block_id * chunks_per_block + chunk_offset_in_block</code></p>\n<p>Yaffs treats a blank (0xFF filled) block as being free or erased. Thus, the equivalent of formatting for a Yaffs partition is to erase all the blocks that are not bad.</p>\n<p>Yaffs2 has a generalised tags interface to provide better flexibility to cater for a wider range of devices with larger pages and stricter programming limitations. Yaffs2 thus handles more abstract constructs than Yaffs1 and, in older versions of Yaffs, more effort was required to interface to the NAND.</p>\n<p>In newer versions of Yaffs, the tags management has been abstracted out of the driver. This makes the driver interface far simpler.</p>\n<h2 class=\"western\">9.1 Formatting</h2>\n<p>Yaffs treats erased blocks as empty. That makes it really easy to “format” a device: just erase it.. Note that this should be done while the partition is not mounted.</p>\n<p>Unmounting will not normally work when the file system is busy (eg. files are open), Some extra non-standard unmount options are provided to enable an unmount to be forced. Note that using these will break any current handles and you will no longer be able to use open files.</p>\n<p><code class=\"western\"><span style=\"font-family: Liberation Serif, serif;\"><span style=\"font-size: 12pt; font-size: medium; font-size: medium;\"><span style=\"font-weight: normal\">There is a </span></span></span></code><code class=\"western\"><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>yaffs_format() </b></span></span></code><code class=\"western\"><span style=\"font-family: Liberation Serif, serif;\"><span style=\"font-size: 12pt; font-size: medium; font-size: medium;\"><span style=\"font-weight: normal\">function that will take care of the details.</span></span></span></code></p>\n<p><br />\n<br />\n</p>\n<h2 class=\"western\">9.2 NAND Model considerations for Yaffs1</h2>\n<p>The historical Yaffs1 tags structure was laid out in accordance with the SmartMedia specification for use with 512-byte pages. There is now much more flexibility in the way things can be configured.</p>\n<p><br />\n<br />\n</p>\n<p>Yaffs1 is capable of being used with a variety of memory layouts so long as the flash supports the ability to overwrite the tags area to set the deletion marker to zero.</p>\n<p>If the yaffs_dev\'s use_nand_ecc field is not set, then yaffs will perform the ECC calculations. If this is set then yaffs will expect the NAND driver to do any required ECC checks. On devices that are not using ECC, for example NOR, set use_nand_ecc=1 and then don\'t do any ECC anyway.</p>\n<p>The Yaffs1 flash model expects an area of 16 spare bytes, some of which are used for tags. The mapping between the spare bytes and the usage of the bytes is specified in yaffs_packedtags1.c</p>\n<p>The Yaffs1 model has been used in many NOR-based systems. One particularly instructive example is in yaffs_nor_drv.c which implements a driver for Yaffs1 mode on CFI-style NOR flash. This does not use ECC but uses checksumming instead.</p>\n<p>The yaffs_dev structure has a yaffs_driver structure which holds the function pointers to the driver. For Yaffs1 mode of operations the following are required:</p>\n<table cellpadding=\"4\" style=\"page-break-inside: avoid; width: 100%; border-spacing: 0px;\">\n<col width=\"77*\" /> <col width=\"179*\" />\n<tr valign=\"top\">\n <td style=\"border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0.1cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 30%;\">\n <p>drv_write_chunk_fn</p>\n  </td>\n <td style=\"border: 1px solid #000000; padding: 0.1cm; width: 70%;\">\n <p>Write a data chunk</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 30%;\">\n <p>drv_read_chunk_fn</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 70%;\">\n <p>Read a data chunk.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 30%;\">\n <p>drv_erase_fn</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 70%;\">\n <p>Erase a block</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 30%;\">\n <p>drv_initialise_fn</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 70%;\">\n <p>Initialisation.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 30%;\">\n <p>drv_deinitialise_fn</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 70%;\">\n <p>De-initialise</p>\n  </td>\n</tr>\n</table>\n<p><br />\n<br />\n</p>\n<p>These functions are described later.</p>\n<h2 class=\"western\">9.3 NAND Model for Yaffs2</h2>\n<p>The Yaffs2 interface is far more flexible than Yaffs1, but that means a bit more effort must be done in the driver. In particular:</p>\n<ul>\n<li>\n<p>There is is no standard spare area/ECC layout. The driver must handle all the layout of the spare area and ECC handling.</p>\n </li>\n<li>\n<p>There is not a standard implementation for bad block markers. Thus, the driver must provide functions for checking and marking bad blocks.</p>\n </li>\n</ul>\n<p>The yaffs_driver structure for Yaffs2 mode requires the following functions:</p>\n<p style=\"margin-bottom: 0cm; orphans: 0; widows: 0; page-break-before: auto\"><br />\n</p>\n<table cellpadding=\"4\" style=\"page-break-inside: avoid; width: 100%; border-spacing: 0px;\">\n<col width=\"77*\" /> <col width=\"179*\" />\n<tr valign=\"top\">\n <td style=\"border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0.1cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 30%;\">\n <p>drv_write_chunk_fn</p>\n  </td>\n <td style=\"border: 1px solid #000000; padding: 0.1cm; width: 70%;\">\n <p>Write a data chunk</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 30%;\">\n <p>drv_read_chunk_fn</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 70%;\">\n <p>Read a data chunk.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 30%;\">\n <p>drv_erase_fn</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 70%;\">\n <p>Erase a block</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 30%;\">\n <p>drv_mark_bad_fn</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 70%;\">\n <p>Mark a block bad</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 30%;\">\n <p>drv_check_bad_fn</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 70%;\">\n <p>Check bad block status of a block.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 30%;\">\n <p>drv_initialise_fn</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 70%;\">\n <p>Initialisation.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 30%;\">\n <p>drv_deinitialise_fn</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 70%;\">\n <p>De-initialise</p>\n  </td>\n</tr>\n</table>\n<p><br />\n<br />\n</p>\n<h2 class=\"western\">9.4 Overview of flash driver function</h2>\n<p>The best way to understand how to write these functions is to look at the example drivers.</p>\n<p><br />\n<br />\n</p>\n<p class=\"code-western\">int (*drv_write_chunk_fn) (struct yaffs_dev *dev, int nand_chunk, </p>\n<p class=\"code-western\">const u8 *data, int data_len, </p>\n<p class=\"code-western\">const u8 *oob, int oob_len)</p>\n<p>This function writes the specified chunk data and oob/spare data to flash.</p>\n<p>This function should return YAFFS_OK on success or YAFFS_FAIL on failure.</p>\n<p>If this is a Yaffs2 device, or Yaffs1 with use_nand_ecc set, then this function must take care of any ECC that is required.</p>\n<p><br />\n<br />\n</p>\n<p class=\"code-western\">int (*drv_read_chunk_fn) (struct yaffs_dev *dev, int nand_chunk, </p>\n<p class=\"code-western\">u8 *data, int data_len, </p>\n<p class=\"code-western\">u8 *oob, int oob_len,</p>\n<p class=\"code-western\">enum yaffs_ecc_result *ecc_result)</p>\n<p>This function reads the specified chunk data and oob/spare data from flash.</p>\n<p>This function should return YAFFS_OK on success or YAFFS_FAIL on failure.</p>\n<p>If this is a Yaffs2 device, or Yaffs1 with use_nand_ecc set, then this function must take care of any ECC that is required and set the ecc_result.</p>\n<p><br />\n<br />\n</p>\n<p class=\"code-western\">int (*drv_erase_fn) (struct yaffs_dev *dev, int block_no) </p>\n<p>This function erases the specified block.</p>\n<p>This function should return YAFFS_OK on success or YAFFS_FAIL on failure.</p>\n<p><br />\n<br />\n</p>\n<p class=\"code-western\">int (*drv_mark_bad_fn) (struct yaffs_dev *dev, int block_no); </p>\n<p class=\"code-western\">int (*drv_check_bad_fn) (struct yaffs_dev *dev, int block_no); </p>\n<p>These functions are only required for Yaffs2 mode. They mark a block bad or check if it is bad.</p>\n<p><br />\n<br />\n</p>\n<p class=\"code-western\">int (*drv_initialise_fn) (struct yaffs_dev *dev); </p>\n<p class=\"code-western\">int (*drv_deinitialise_fn) (struct yaffs_dev *dev); </p>\n<p>These functions provide hooks for initialising or deinitialising the flash driver.</p>\n<p><br />\n<br />\n</p>\n<h1 class=\"western\" style=\"page-break-before: always\">10 Configuration and flash driver installation</h1>\n<p>For an example of how to do the configuration, refer to yaffs_cfg2k.c and one of the drivers such as yaffs_nand_drv.c</p>\n<p>The old mechanism was static and required a table of devices that was installed at start up. This mechanism had shortcomings – in particular it broke modularity and did not allow devices to be added dynamically.</p>\n<p>Things are different now. As any time, a yaffs_dev structure can be configured and then registered with Yaffs by using the yaffs_add_device() function.</p>\n<p>A yaffs_dev structure has two parts which must be configured before yaffs_add_device() is called: the paramers (dev-&gt;param) and the driver (dev-&gt;drv). The driver configuration (plugging in the driver functions) has already been described above, so we will now look at the yaffs parameters.</p>\n<p><br />\n<br />\n</p>\n<p>The yaffs_param structure must be set before the yaffs_dev is added with yaffs_add_device() and should not be modified after that.</p>\n<p>The params are defined in the Yaffs Tuning Document.</p>\n<h1 class=\"western\" style=\"page-break-before: always\">11 Using the POSIX file system interface</h1>\n<p>This section is directed to readers that might not be very familiar with accessing a file system via POSIX and POSIX-like interfaces.</p>\n<h2 class=\"western\">11.1 Difference to Windows POSIX-like interfaces</h2>\n<p>MSDOS and Windows provide a POSIX-lke interface. If you are familiar with this then that will help you. There are are however some slight differences, most importantly:</p>\n<ul>\n<li>\n<p>Windows has no concept of links and has a 1:1 mapping between file names and files.POSIX supports files with zero, one or many names. Refer to the sections on linking and unlinking files. For instance POSIX allows you to unlink a file (ie delete the name for a file) while it is still in use. You can continue to read/write the file but it will be deleted as soon as the last file handle to the file is closed. Windows, on the other hand, does not allow you to unlink a file while it is in use.</p>\n </li>\n<li>\n<p>Windows names drives with a letter. POSIX has no drive letters. The whole POSIX file system is in a single directory tree.</p>\n </li>\n<li>\n<p>Directories and “folders” are the same thing.</p>\n </li>\n</ul>\n<h2 class=\"western\">11.2 Fundamental concepts</h2>\n<table cellpadding=\"4\" style=\"width: 642px; border-spacing: 0px;\">\n<col width=\"126\" /> <col width=\"499\" />\n<tr valign=\"top\">\n <td style=\"border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0.1cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 126px;\">\n <p>File</p>\n  </td>\n <td style=\"border: 1px solid #000000; padding: 0.1cm; width: 499px;\">\n <p>A file is an object that is stored in the file system. yaffs supports the following file types:</p>\n <p>A regular file is a sequence of bytes stored in the file system.</p>\n <p>A directory holds links to other files.</p>\n <p>A symbolic link holds a name to another file.</p>\n <p>A special file holds device ids or similar information.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 126px;\">\n <p>Directory</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 499px;\">\n <p>This is a structure that holds links and allows a file to be found by name. Note that a single file may have many links(ie names) and many be found in many places in the directory structure.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 126px;\">\n <p>Link</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 499px;\">\n <p>This is a name that allows the file to be found. There are two types of link: real links (sometimes called hard links) and symbolic (or soft) links. </p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 126px;\">\n <p>Handle</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 499px;\">\n <p>A file handle provides a context from which a file can be accessed and manipulated. A handle has a current file position pointer which points to where the file is being read or written. Multiple handles can simultaneously access a single file.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 126px;\">\n <p>File mode</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 499px;\">\n <p>The mode is the set of flags that define the type of file as well as the current permissions associated with the file.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 126px;\">\n <p>Path</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 499px;\">\n <p>This is a string that defines the directories and file name. For example:</p>\n <p>“/data/direct-1/file1”</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 126px;\">\n <p>File metadata</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 499px;\">\n <p>This is the information about the file, excluding the file contents. The metadata includes the name, mode, size and other details.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 126px;\">\n <p>Mount,<br />\n  partition,<br />\n  file system</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 499px;\">\n <p>These terms all refer to a single mounted flash area. Each mount is hooked into a common directory structure.<br />\n  The term file system can sometimes be confusing because it is used both for a single mounted partition as well as the the file system code. In other words, we might say that both “/boot” is a file system and might also say that yaffs is a file system.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 126px;\">\n <p>inode number</p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 499px;\">\n <p>The inode number is a unique number that identifies the object within the mount. Note that inodes are not unique between two or more mounts. There is no way to reach a file by inode, only via its links.</p>\n  </td>\n</tr>\n</table>\n<p><br />\n<br />\n</p>\n<h2 class=\"western\">11.3 Error code</h2>\n<p>Most functions result in error codes if the function does not execute successfully. In these cases yaffs calls a function called <code class=\"western\">yaffs_SetError()</code> with the error value. This function can be configured to deliver the error into the system\'s error mechanism.</p>\n<p>In the case of functions that return integers, a returned value smaller than 0 indicates an error occurred. Functions returning pointers will return NULL if an error occurred.</p>\n<h2 class=\"western\">11.4 Links – the hard kind (not symbolic links)</h2>\n<p>At first we\'re just considering real links and not symbolic links. Sometimes real links are also called hard links to differentiate them from symbolic links (which are sometimes called soft links).</p>\n<p>The difference between links and files is subtle and can be confusing. Briefly:</p>\n<ul>\n<li>\n<p>a file is the stored object in the file system</p>\n </li>\n<li>\n<p>the link is how it is hooked into the directory structure.</p>\n </li>\n</ul>\n<p><br />\n<br />\n</p>\n<p>The first link to a file is created by using the file creation calls: <code class=\"western\">yaffs_open()</code>, <code class=\"western\">yaffs_mknod()</code>, <code class=\"western\">yaffs_symlink()</code> and <code class=\"western\">yaffs_mkdir()</code>.</p>\n<p>A link can be destroyed by using the <code class=\"western\">yaffs_unlink()</code> function. Directories are destroyed using the <code class=\"western\">yaffs_rmdir()</code> function (oh, and the directory must be empty).</p>\n<p>Once a file is both unused (there are no handles open to it) and there are no links to it it is then deleted.</p>\n<p>A link can be renamed by using the <code class=\"western\">yaffs_rename()</code> function.</p>\n<p>A file may have many links. These may be created using the <code class=\"western\">yaffs_link()</code> function. All the links access the same file and there is no one link that is considered “the real link” and others being “the duplicate link”. All links to a file have the same priority. If you look at the inode number for “a” and for “b” then they will be the same because they are refering to exactly the same file.</p>\n<p>Thus:</p>\n<ol>\n<li>\n<p>If we start with a file called “a” and then call <code class=\"western\">yaffs_link(“a”, “b”)</code> we now have two links to the same file. We can\'t tell them apart.</p>\n </li>\n<li>\n<p>If we now unlink “a”, the file still exists under the link “b”.</p>\n </li>\n<li>\n<p>If we now unlink “b” the file will no longer be linked. If there is a handle open to the file then we can still access the file through the handle and continue to read or modify the file. If there is no link to the file it is deleted.</p>\n </li>\n<li>\n<p>If an unlinked file was kept alive because of a handle being open, the file will not show up in the directory structure (because it has no link) and will be deleted as soon as the handle is closed (or if the file system is unmounted).</p>\n </li>\n</ol>\n<p>There are some limitations in how links are used:</p>\n<ul>\n<li>\n<p>The existing file you are linking to must exist.</p>\n </li>\n<li>\n<p>The file you are linking to must be in the same mount (partition) as the link you are creating.</p>\n </li>\n<li>\n<p>You cannot create a link to a directory because this would allow the creation of recursive loops.</p>\n </li>\n<li>\n<p>The new link name must not exist.</p>\n </li>\n</ul>\n<p><br />\n<br />\n</p>\n<h2 class=\"western\">11.5 Symbolic links</h2>\n<p>Now that you understand how hard links work, we\'ll introduce symbolic (or soft) links.</p>\n<p>A symbolic link holds an alias for a different object. When you use that symbolic link in a path the alias is used instead. To that extent symbolic link and hard links are the same.</p>\n<p>You can remove symbolic links with the <code class=\"western\">yaffs_unlink()</code> function, just like hard links.</p>\n<p>There are, however, some important differences. A symbolic link only does its linking function when the path is being evaluated and thus:</p>\n<ul>\n<li>\n<p>The file you are creating an alias to does not have to exist.</p>\n </li>\n<li>\n<p>The file you are creating an alias to does not have to be in the same mount.</p>\n </li>\n<li>\n<p>You can create symbolic links to directories.</p>\n </li>\n<li>\n<p>A symbolic link will not keep a file alive by itself. Only a hard link can do that.</p>\n </li>\n</ul>\n<p>Thus:</p>\n<ol>\n<li>\n<p>If we start with a file called “a” and then call <code class=\"western\">yaffs_symlink(“a”, “b”)</code> we now have one link to the file called “a” and a symbolic link aliasising from “b” to “a”.</p>\n </li>\n<li>\n<p>If we use <code class=\"western\">yaffs_open(“a”)</code> or <code class=\"western\">yaffs_open(“b”)</code> they will open the same file. The path resolution mechanism substitutes in the alias and so will look up “a”. The same applies to almost all functions that takes a path, such as <code class=\"western\">yaffs_truncate()</code>, <code class=\"western\">yaffs_stat()</code> etc. The only exceptions are <code class=\"western\">yaffs_lstat()</code> and <code class=\"western\">yaffs_readlink()</code> which will treat the path as pointing to the symbolic link and not the file.</p>\n </li>\n<li>\n<p>You can tell “a” and “b” apart by using <code class=\"western\">yaffs_lstat()</code>. <code class=\"western\">yaffs_lstat(“a”)</code> will show the information for file “a”. <code class=\"western\">yaffs_lstat(“b”)</code> will show the information for the symbolic link itself. Note the difference with hard links. With hard links <code class=\"western\">yaffs_lstat(“a”)</code> and <code class=\"western\">yaffs_lstat(“b”)</code> would show the same results since they are EXACTLY the same thing being referenced.</p>\n </li>\n<li>\n<p>If we now unlink “a”. then the file is no longer linked and will no longer be accessible from “b”. Note the difference with hard links.</p>\n </li>\n</ol>\n<p><br />\n<br />\n</p>\n<h2 class=\"western\">11.6 Handle-based file handling</h2>\n<p>A handle is file accessor that allows us to access the contents of a regular file. The handle identifies the file being accessed as well as a position pointer tracking where the next read or write operation will take place.</p>\n<p>A handle is identified by an integer of value 0 or greater.</p>\n<p>A handle is created by using the <code class=\"western\">yaffs_open()</code> call and returns the handle value. If the handle could not be created then a negative value is returned and the yaffs error code is set.</p>\n<p>A handle remains valid until the handle is closed by <code class=\"western\">yaffs_close()</code>.</p>\n<p>The <code class=\"western\">yaffs_open()</code> call takes three parameters:</p>\n<ul>\n<li>\n<p>name: Full path name of the file being opened.</p>\n </li>\n<li>\n<p>access flags: Flags being used to open this handle</p>\n </li>\n<li>\n<p>creation mode: Mode flags used when creating a file.</p>\n </li>\n</ul>\n<p>The access flags are one or more of:</p>\n<table cellpadding=\"4\" style=\"width: 100%; border-spacing: 0px;\">\n<col width=\"59*\" /> <col width=\"197*\" />\n<tr valign=\"top\">\n <td style=\"border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0.1cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 23%;\">\n <p><span style=\"font-family: Courier, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><code class=\"western\">O_CREAT</code></span></span></p>\n  </td>\n <td style=\"border: 1px solid #000000; padding: 0.1cm; width: 77%;\">\n <p>Create file if it does not already exist.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 23%;\">\n <p><span style=\"font-family: Courier, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><code class=\"western\">O_EXCL</code></span></span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 77%;\">\n <p>Only use with O_CREAT. Create file if it does not exist. If the file already exists then fail.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 23%;\">\n <p><span style=\"font-family: Courier, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><code class=\"western\">O_TRUNC</code></span></span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 77%;\">\n <p>If the file exists, and opening with write access, then truncate the file to zero bytes long.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 23%;\">\n <p><br />\n  </p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 77%;\">\n <p><br />\n  </p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 23%;\">\n <p><span style=\"font-family: Courier, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><code class=\"western\">O_APPEND</code></span></span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 77%;\">\n <p>Regardless of the handle position, always write to the end of the file.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 23%;\">\n <p><br />\n  </p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 77%;\">\n <p><br />\n  </p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 23%;\">\n <p><span style=\"font-family: Courier, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><code class=\"western\">O_RDWR</code></span></span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 77%;\">\n <p>Open for read/write access.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 23%;\">\n <p><span style=\"font-family: Courier, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><code class=\"western\">O_WRONLY</code></span></span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 77%;\">\n <p>Open for write access and no read access.</p>\n <p><br />\n  </p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 23%;\">\n <p><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>0 (zero)</b></span></span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 77%;\">\n <p>If neither O_RDWR or O_WRONLY is set then the file will be opened for read-only access.</p>\n  </td>\n</tr>\n</table>\n<p><br />\n<br />\n</p>\n<p>Where they are not mutually exclusive, these flags are typically combined. For example:</p>\n<p><code class=\"western\">O_CREAT | O_TRUNC | O_RDWR</code> : Create a new file if it does not exist otherwise if the file already exists then truncate to zero length. Typically used to overwrite a file or create if it does not already exist.</p>\n<p><code class=\"western\">O_CREAT | OEXCL | O_WRONLY</code> : Create a new file, opening it for write only. Fails if file already exists.</p>\n<p>There are three mode flags that can be controlled or set. These flags may be set by the open that creates the file or later by the <code class=\"western\">yaffs_chmod()</code>.</p>\n<table cellpadding=\"4\" style=\"width: 100%; border-spacing: 0px;\">\n<col width=\"59*\" /> <col width=\"197*\" />\n<tr valign=\"top\">\n <td style=\"border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0.1cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 23%;\">\n <p><span style=\"font-family: Courier New, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><code class=\"western\">S_IREAD</code></span></span></p>\n  </td>\n <td style=\"border: 1px solid #000000; padding: 0.1cm; width: 77%;\">\n <p>The file may be opened for read access.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 23%;\">\n <p><span style=\"font-family: Courier New, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><code class=\"western\">S_IWRITE</code></span></span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 77%;\">\n <p>The file may be opened for write access.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 23%;\">\n <p><span style=\"font-family: Courier New, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><code class=\"western\">S_IEXEC</code></span></span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 77%;\">\n <p>The file may be opened for execution. This is not enforced by yaffs.</p>\n  </td>\n</tr>\n</table>\n<p><br />\n<br />\n</p>\n<p>Once you have opened a handle you can then do various operations on the file.</p>\n<table cellpadding=\"4\" style=\"width: 605px; border-spacing: 0px;\">\n<col width=\"248\" /> <col width=\"339\" />\n<tr valign=\"top\">\n <td style=\"border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0.1cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 248px;\">\n <p><span style=\"font-family: Courier New, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><code class=\"western\">yaffs_close(handle)</code></span></span></p>\n  </td>\n <td style=\"border: 1px solid #000000; padding: 0.1cm; width: 339px;\">\n <p>Close the handle. It is no longer usable.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 248px;\">\n <p><span style=\"font-family: Courier New, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><code class=\"western\">yaffs_fsync(handle)</code></span></span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 339px;\">\n <p>Flush out any cached writes to the file, as well as the file meta-data.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 248px;\">\n <p><span style=\"font-family: Courier New, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><code class=\"western\">yaffs_datasync(handle)</code></span></span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 339px;\">\n <p>Same as yaffs_fsync() but no file metadata.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 248px;\">\n <p><span style=\"font-family: Courier New, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><code class=\"western\">yaffs_flush(handle)</code></span></span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 339px;\">\n <p>Same as yaffs_fsync()</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 248px;\">\n <p><span style=\"font-family: Courier New, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><code class=\"western\">yaffs_dup(handle)</code></span></span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 339px;\">\n <p>Duplicates a handle.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 248px;\">\n <p><span style=\"font-family: Courier New, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><code class=\"western\">yaffs_lseek(handle, offset, whence)</code></span></span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 339px;\">\n <p>Set the handle read/write position. Note that this does not modify the file. You can seek past the end of the file. This does not modify the file size.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 248px;\">\n <p><span style=\"font-family: Courier New, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><code class=\"western\">yaffs_ftruncate(handle, size)</code></span></span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 339px;\">\n <p>Change the file size. It can be made bigger or smaller. This does not change the handle read/write position.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 248px;\">\n <p><span style=\"font-family: Courier New, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><code class=\"western\">yaffs_fstat(handle, buf)</code></span></span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 339px;\">\n <p>Get file status.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 248px;\">\n <p><span style=\"font-family: Courier New, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><code class=\"western\">yaffs_fchmod(handle, mode)</code></span></span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 339px;\">\n <p>Change the file mode.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 248px;\">\n <p><br />\n  </p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 339px;\">\n <p><br />\n  </p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 248px;\">\n <p><span style=\"font-family: Courier New, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><code class=\"western\">yaffs_read(handle, buffer, nbytes)</code></span></span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 339px;\">\n <p>Read data from file at file pointer and update pointer.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 248px;\">\n <p><span style=\"font-family: Courier New, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><code class=\"western\">yaffs_pread(handle, buffer, nbytes, position)</code></span></span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 339px;\">\n <p>Read data from file at specified position. Does not modify file pointer</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 248px;\">\n <p><span style=\"font-family: Courier New, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><code class=\"western\">yaffs_write(handle, buffer, nbytes)</code></span></span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 339px;\">\n <p>Write data to file at file pointer and update pointer.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 248px;\">\n <p><span style=\"font-family: Courier New, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><code class=\"western\">yaffs_pread(handle, buffer, nbytes, position)</code></span></span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 339px;\">\n <p>Write data to file at specified position. Does not modify file pointer</p>\n  </td>\n</tr>\n</table>\n<p><br />\n<br />\n</p>\n<h2 class=\"western\">11.7 Changing file size</h2>\n<p class=\"code-western\"><code class=\"western\">yaffs_truncate(path, newSize)</code></p>\n<p class=\"code-western\"><code class=\"western\">yaffs_ftruncate(handle, newSize)</code></p>\n<p><br />\n<br />\n</p>\n<p>These change a file\'s size. Note that truncating does not just mean make the file smaller. The file can also be made larger.</p>\n<p>Yaffs does not store bytes that it does not need to. If you use truncate to make a file larger then this will not necessarily occupt more flash space.</p>\n<p>See also <code class=\"western\">yaffs_lseek()</code> too. Note that <code class=\"western\">yaffs_lseek() </code>only changes the position of the write pointer and does not impact on the file size unless the file is written.</p>\n<p><br />\n<br />\n</p>\n<h2 class=\"western\">11.8 Getting/setting information about files</h2>\n<p class=\"code-western\"><code class=\"western\">yaffs_chmod(path, mode)</code></p>\n<p class=\"code-western\"><code class=\"western\">yaffs_fchmod(handle, mode)</code></p>\n<p class=\"code-western\"><br />\n<br />\n</p>\n<p class=\"code-western\"><code class=\"western\">yaffs_access(path,amode)</code></p>\n<p class=\"code-western\"><br />\n<br />\n</p>\n<p class=\"code-western\"><code class=\"western\">yaffs_stat(path, struct yaffs_stat *buf) </code> </p>\n<p class=\"code-western\"><code class=\"western\">yaffs_fstat(handle, struct yaffs_stat *buf)</code></p>\n<p class=\"code-western\"><code class=\"western\">yaffs_lstat(path, struct yaffs_stat *buf)</code></p>\n<p class=\"code-western\"><code class=\"western\">yaffs_readlink(path, buf, bufsize)</code></p>\n<p><br />\n<br />\n</p>\n<p>The chmod calls allow you to set different mode flags for the file. These can only be used to manipulate the permissions flags and not change the mode flags relating to the type of file.</p>\n<p><code class=\"western\">yaffs_access() </code>tests that the file can be accessed in the specified mode. This call returns zero on success and -1 is returned</p>\n<p>amode is a bitmask of the following values:</p>\n<table cellpadding=\"4\" style=\"width: 100%; border-spacing: 0px;\">\n<col width=\"43*\" /> <col width=\"213*\" />\n<tr valign=\"top\">\n <td style=\"border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0.1cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 17%;\">\n <p><span style=\"font-family: Courier New, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><code class=\"western\">R_OK</code></span></span></p>\n  </td>\n <td style=\"border: 1px solid #000000; padding: 0.1cm; width: 83%;\">\n <p>Check read is OK</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 17%;\">\n <p><span style=\"font-family: Courier New, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><code class=\"western\">W_OK</code></span></span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 83%;\">\n <p>Check write is OK</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 17%;\">\n <p><span style=\"font-family: Courier New, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><code class=\"western\">X_OK</code></span></span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 83%;\">\n <p>Check execute is OK.</p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 17%;\">\n <p><span style=\"font-family: Courier New, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><code class=\"western\">0 (zero)</code></span></span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 83%;\">\n <p>Just checks the file exists</p>\n  </td>\n</tr>\n</table>\n<p>These can be combined.</p>\n<p>For example:</p>\n<p class=\"code-western\"><code class=\"western\">if(yaffs_access(path, R_OK | W_OK) == 0)</code></p>\n<p class=\"code-western\"><code class=\"western\">the file exists and can be read and written</code></p>\n<p class=\"code-western\"><code class=\"western\">if(yaffs_access(path, 0) == 0)</code></p>\n<p class=\"code-western\"><code class=\"western\">the file exists</code></p>\n<p><br />\n<br />\n</p>\n<p>The stat calls retrieve a yaffs_stat structure of data which is defined in yaffsfs.h. There are three versions:</p>\n<p><code class=\"western\">yaffs_fstat</code>: Takes a handle.</p>\n<p><code class=\"western\">yaffs_stat</code>: Takes a path name and follows symbolic links.</p>\n<p><code class=\"western\">yaffs_lstat</code>: Takes a path but does not follow symbolic links.</p>\n<p><br />\n<br />\n</p>\n<p>Thus, if path is a symbolic link, <code class=\"western\">yaffs_fstat() </code>will give information on the file that the link points to while <code class=\"western\">yaffs_lstat()</code> will give information about the link itself.</p>\n<p><code class=\"western\">yaffs_readlink()</code> will read the read the link value into the buffer provided. For example:</p>\n<p class=\"code-western\"><code class=\"western\">yaffs_symlink(“target”,”/link”); /* create a link called link to target */</code></p>\n<p class=\"code-western\"><code class=\"western\">yaffs_readlink(“/link”,buffer,10); /* now buffer contains “target” */</code></p>\n<p><br />\n<br />\n</p>\n<h2 class=\"western\">11.9 Changing the directory structure and names</h2>\n<p class=\"code-western\"><code class=\"western\">yaffs_open(path, flags, mode)</code></p>\n<p class=\"code-western\"><code class=\"western\">yaffs_mkdir(path, mode)</code></p>\n<p class=\"code-western\"><code class=\"western\">yaffs_symlink(targetPath, linkPath)</code></p>\n<p class=\"code-western\"><code class=\"western\">yaffs_mknod(pathname, mode, dev)</code></p>\n<p class=\"code-western\"><br />\n<br />\n</p>\n<p class=\"code-western\"><code class=\"western\">yaffs_link(existingPath, newath)</code></p>\n<p class=\"code-western\"><br />\n<br />\n</p>\n<p class=\"code-western\"><code class=\"western\">yaffs_unlink(path)</code></p>\n<p class=\"code-western\"><code class=\"western\">yaffs_rmdir(path)</code></p>\n<p class=\"code-western\"><br />\n<br />\n</p>\n<p class=\"code-western\"><code class=\"western\">yaffs_rename(oldPath, newPath)</code></p>\n<p><br />\n<br />\n</p>\n<p>Files of various types, and their first link, are created via the <code class=\"western\">yaffs_open()</code><code class=\"western\"><span style=\"font-family: Liberation Serif, serif;\"><span style=\"font-weight: normal\">,</span></span></code><span style=\"font-family: Courier New, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"></span></span><code class=\"western\">yaffs_mkdir()</code><span style=\"font-family: Liberation Serif, serif;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\">, </span></span><code class=\"western\">yaffs_symlink()</code> and <code class=\"western\">yaffs_mknod()</code><span style=\"font-family: Liberation Serif, serif;\"><span style=\"font-size: 12pt; font-size: medium; font-size: medium;\"></span></span>functions.</p>\n<p><code class=\"western\">yaffs_link()</code> can be used to create subsequent links to files. Note that you cannot create a link to a directory.</p>\n<p><code class=\"western\">yaffs_rename()</code> allows you to rename a link. Note that renaming one link over another link is an atomic operation. That means that even if the operation is interrupted by a power failure, the result will either complete or not happen at all. If the target link is for a directory, then the rename will only work if the target directory is empty.</p>\n<p><br />\n<br />\n</p>\n<h2 class=\"western\">11.10 Searching directories</h2>\n<p class=\"code-western\"><code class=\"western\">yaffs_DIR *yaffs_opendir(const YCHAR *dirname) ; </code> </p>\n<p class=\"code-western\"><code class=\"western\">struct yaffs_dirent *yaffs_readdir(yaffs_DIR *dirp) ; </code> </p>\n<p class=\"code-western\"><code class=\"western\">void yaffs_rewinddir(yaffs_DIR *dirp) ; </code> </p>\n<p class=\"code-western\"><code class=\"western\">int yaffs_closedir(yaffs_DIR *dirp) ; </code> </p>\n<p><br />\n<br />\n</p>\n<p>Searching is performed by the following sequence of operations:</p>\n<ul>\n<li>\n<p>Open the directory for reading with <code class=\"western\">yaffs_opendir()</code>.</p>\n </li>\n<li>\n<p>Iterate through the entries in the directory using <code class=\"western\">yaffs_readdir()</code>. Each read will advance the directory read position.</p>\n </li>\n<li>\n<p>You can reset to the start of the directory with <code class=\"western\">yaffs_rewinddir()</code>.</p>\n </li>\n<li>\n<p>Close the directory when finished with <code class=\"western\">yaffs_closedir()</code>.</p>\n </li>\n</ul>\n<h2 class=\"western\">11.11 Searching directories (fd interface)</h2>\n<p class=\"code-western\"><code class=\"western\">int </code><code class=\"western\">yaffs_open(const YCHAR *dirname, </code><code class=\"western\">O_RDONLY, 0</code><code class=\"western\">) ; </code> </p>\n<p class=\"code-western\"><code class=\"western\">struct yaffs_dirent *yaffs_readdir_</code><code class=\"western\">fd</code><code class=\"western\">(</code><code class=\"western\">int fd</code><code class=\"western\">) ; </code> </p>\n<p class=\"code-western\"><code class=\"western\">void yaffs_rewinddir_</code><code class=\"western\">fd</code><code class=\"western\">(</code><code class=\"western\">int fd</code><code class=\"western\">) ; </code> </p>\n<p class=\"code-western\"><code class=\"western\">int yaffs_close(</code><code class=\"western\">int fd</code><code class=\"western\">) ; </code> </p>\n<p><br />\n<br />\n</p>\n<p>This is not a POSIX interface, but provides an alternate interface for reading directories.</p>\n<p><br />\n<br />\n</p>\n<p>Searching is performed by the following sequence of operations:</p>\n<ul>\n<li>\n<p>Open the directory for reading with <code class=\"western\">yaffs_open( </code><code class=\"western\">name, O_RDONLY, 0</code><code class=\"western\">)</code>.</p>\n </li>\n<li>\n<p>Iterate through the entries in the directory using <code class=\"western\">yaffs_readdir_</code><code class=\"western\">fd</code><code class=\"western\">()</code>. Each read will advance the directory read position.</p>\n </li>\n<li>\n<p>You can reset to the start of the directory with <code class=\"western\">yaffs_rewinddir_</code><code class=\"western\">fd</code><code class=\"western\">()</code>.</p>\n </li>\n<li>\n<p>Close the directory when finished with <code class=\"western\">yaffs_close()</code>.</p>\n </li>\n</ul>\n<p><br />\n<br />\n</p>\n<h2 class=\"western\">11.12 Mount control and similar</h2>\n<p class=\"code-western\"><code class=\"western\">yaffs_mount(path) ; </code> </p>\n<p class=\"code-western\"><code class=\"western\">yaffs_mount2(path, readOnly); </code> </p>\n<p class=\"code-western\"><code class=\"western\">yaffs_unmount(path);</code></p>\n<p class=\"code-western\"><code class=\"western\">yaffs_unmount2(path, int force); </code> </p>\n<p class=\"code-western\"><code class=\"western\">yaffs_remount(path, force, readOnly);</code></p>\n<p class=\"code-western\"><code class=\"western\">yaffs_sync(path) ;</code></p>\n<p class=\"code-western\"><code class=\"western\">yaffs_format(const YCHAR *path, </code> </p>\n<p><code class=\"western\"></code> <code class=\"western\">int unmount_flag, </code> </p>\n<p><code class=\"western\"></code> <code class=\"western\">int force_unmount_flag, </code> </p>\n<p><code class=\"western\"></code> <code class=\"western\">int remount_flag) </code> </p>\n<p><br />\n<br />\n</p>\n<p>A partition must be mounted to be accessed. <code class=\"western\">yaffs_mount()</code> will mount the partition for read/write access. <code class=\"western\">yaffs_mount2()</code> can be used to control whether the access is read/write or read only.</p>\n<p>A partition can be unmounted to remove it from use. <code class=\"western\">yaffs_unmount()</code> will fail if any files are in use whereas <code class=\"western\">yaffs_unmount2()</code> allows you to force the unmount even if files are open. Note that any file handles will then be broken and will no longer access the files.</p>\n<p><code class=\"western\">yaffs_remount()</code> can be used to change the access to a currently mounted partition and is equivalent to making an <code class=\"western\">unmount2()</code> call followed by a <code class=\"western\">mount2()</code> call.</p>\n<p><code class=\"western\">yaffs_sync()</code> does not change the mount status but flushes out any pending data on a partition that is mounted with write access.</p>\n<p><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>yaffs_format()</b></span></span> provides a mechanism to format a device. It has various parameters.<br />\n<span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>unmount_flag</b></span></span>: If set, yaffs_format() will unmount the device before formatting. If this flag is not set and the device is mounted, then the format will fail with EBUSY.</p>\n<p><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>force_unmount</b></span></span>: If set, then an unmount is allowed even if the device is busy (eg. files open). If not set, then yaffs_format() will fail (EBUSY) if files are open.</p>\n<p><span style=\"font-family: Liberation Mono, monospace;\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"><b>remount_flag</b></span></span>: If set, then the device will be remounted after the format if it was mounted.</p>\n<p>The force_unmount and remount_flag options only have meaning if unmount_flag is set.</p>\n<h2 class=\"western\">11.13 Extended attributes (xattrt)</h2>\n<p>Extended attributes provide a mechanism to attach a limited amount of extra data to a file without actually modifying the file. Each xattribute is a named pair of name and some data. Each file can have as many xattribs as there is space for. In Yaffs, this is around chunk-size – 512 bytes. So on devices with 2kbyte chunks you can store up to 1.5kbytes of xattribute information.</p>\n<p>Although there are 12 xattr functions, there are really only four basic functions, each with 3 different flavours.</p>\n<p>The basic functions are: set an xattr, get an xattr, remove an xattribute and list the xattribute names.</p>\n<p class=\"code-western\">int yaffs_setxattr(const char *path, const char *name, </p>\n<p class=\"code-western\">const void *data, int size, int flags); </p>\n<p class=\"code-western\">int yaffs_lsetxattr(const char *path, const char *name, </p>\n<p class=\"code-western\">const void *data, int size, int flags); </p>\n<p class=\"code-western\">int yaffs_fsetxattr(int fd, const char *name, </p>\n<p class=\"code-western\">const void *data, int size, int flags); </p>\n<p>These functions are called with name being the name of the xattr, a pointer to the data and the size of the data, and flags.</p>\n<p>The flags are:</p>\n<p>XATTR_CREATE: Create a new xattr, fail with -EEXIST if the xattrib already exists.</p>\n<p>XATTR_REPLACE: Replace an existing xattr, fail with -ENOATTR if it does not exist.</p>\n<p>zero: Just create with no checks, replace if it already exists.</p>\n<p><br />\n<br />\n</p>\n<p>Setting can fail with -ENOSPC if there is not enough space to store the xattrib.</p>\n<p><br />\n<br />\n</p>\n<p class=\"code-western\">int yaffs_getxattr(const char *path, const char *name, </p>\n<p class=\"code-western\">void *data, int size); </p>\n<p class=\"code-western\">int yaffs_lgetxattr(const char *path, const char *name, </p>\n<p class=\"code-western\">void *data, int size); </p>\n<p class=\"code-western\">int yaffs_fgetxattr(int fd, const char *name, </p>\n<p class=\"code-western\">void *data, int size); </p>\n<p>These get (fetch) an xattrib.</p>\n<p>If the call succeeds, the length of the retrieved xattrib is returned. This call can fail with -ENOATTR if the requested xattr does not exist or -ERANGE if the buffer was too small.</p>\n<p><br />\n<br />\n</p>\n<p class=\"code-western\">int yaffs_removexattr(const char *path, const char *name); </p>\n<p class=\"code-western\">int yaffs_lremovexattr(const char *path, const char *name); </p>\n<p class=\"code-western\">int yaffs_fremovexattr(int fd, const char *name); </p>\n<p>These functions delete an existing xattr. If the xattr does not exist then -ENOATTR is returned.</p>\n<p><br />\n<br />\n</p>\n<p class=\"code-western\">int yaffs_listxattr(const char *path, char *list, int size); </p>\n<p class=\"code-western\">int yaffs_llistxattr(const char *path, char *list, int size); </p>\n<p class=\"code-western\">int yaffs_flistxattr(int fd, char *list, int size); </p>\n<p>These functions fetch a list of the xattrib names into the list buffer. The names are NUL terminated. eg. “attrib0\\0attrib1\\0...”.</p>\n<p>The function returns the length of the list, otherwise if the list buffer is too short it returns -ERANGE.</p>\n<p>Note: If you call these functions with a list buffer size of zero, this acts as a query of the required buffer size. No data is actually transferred into the list.</p>\n<p><br />\n<br />\n</p>\n<p>For example we might choose to add some xattribs to a media file:</p>\n<p class=\"code-western\">//Set description</p>\n<p class=\"code-western\">yaffs_fsetxattr(fd, “user-comment”, “I hate this song!”,18);</p>\n<p class=\"code-western\">yaffs_fsetxattr(fd, “price-in-cents”, &amp;cost, sizeof(cost));</p>\n<p class=\"code-western\">// Get the comment</p>\n<p class=\"code-western\">yaffs_fgetxattr(fd, “user_comment”, buffer, sizeof(buffer);</p>\n<p class=\"code-western\"><br />\n<br />\n</p>\n<p class=\"code-western\">//List the attributes in a NUL delimited list</p>\n<p class=\"code-western\">yaffs_flistxattr(fd, list_buf, sizeof(list_buf));</p>\n<p class=\"code-western\">// Now list_buf has user-comment\\0price-in-cents\\0</p>\n<p class=\"code-western\">yaffs_fremovexattr(fd, ”user-comment”);</p>\n<p><br />\n<br />\n</p>\n<h2 class=\"western\">11.14 Other</h2>\n<p class=\"code-western\"><code class=\"western\">yaffs_freespace(path); </code> </p>\n<p class=\"code-western\"><code class=\"western\">yaffs_totalspace(path); </code> </p>\n<p class=\"code-western\"><code class=\"western\">yaffs_inodecount(path); </code> </p>\n<p><br />\n<br />\n</p>\n<p>These functions provide information on the free and total space (in bytes) for the mount that the path addresses.</p>\n<p><code class=\"western\">yaffs_inodecount()</code> returns the number of files on the mount that the path addresses.</p>\n<h1 class=\"western\" style=\"page-break-before: always\">12 Example: yaffs_readdir() and yaffs_stat()</h1>\n<p>This code snippet illustrates using <code class=\"western\">yaffs_readdir()</code> and associated functions to iterate through a directory. It also shows how to use <code class=\"western\">yaffs_lstat() </code>to get information on a file and interpret it.</p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\">void dump_directory(const char *dname) </span></code> </p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\">{ </span></code> </p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\">yaffs_DIR *d; </span></code> </p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\">yaffs_dirent *de; </span></code> </p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\">struct yaffs_stat s; </span></code> </p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\">char str[100]; </span></code> </p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"></span></code> </p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\">d = yaffs_opendir(dname); </span></code> </p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"></span></code> </p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\">if(!d) { </span></code> </p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\">printf(&quot;opendir failed\\n&quot;); </span></code> </p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\">} else { </span></code> </p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\">while((de = yaffs_readdir(d)) != NULL) { </span></code> </p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\">sprintf(str,&quot;%s/%s&quot;,dname,de-&gt;d_name); </span></code> </p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"></span></code> </p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\">yaffs_lstat(str,&amp;s); </span></code> </p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"></span></code> </p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\">printf(&quot;%s inode %d length %d mode %X &quot;,</span></code></p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\">str,s.st_ino,(int)s.st_size,s.st_mode); </span></code> </p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\">switch(s.st_mode &amp; S_IFMT) { </span></code> </p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\">case S_IFREG: printf(&quot;data file&quot;); break; </span></code> </p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\">case S_IFDIR: printf(&quot;directory&quot;); break; </span></code> </p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\">case S_IFLNK: printf(&quot;symlink --&gt;&quot;); </span></code> </p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\">if(yaffs_readlink(str,str,100) &lt; 0) </span></code> </p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\">printf(&quot;no alias&quot;); </span></code> </p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\">else </span></code> </p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\">printf(&quot;\\&quot;%s\\&quot;&quot;,str);</span></code></p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\">break; </span></code> </p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\">default: printf(&quot;unknown&quot;); break; </span></code> </p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\">}</span></code></p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\">printf(&quot;\\n&quot;); </span></code> </p>\n<p class=\"code-western\"><br />\n<br />\n</p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\">if((s.st_mode &amp; S_IFMT) == S_IFDIR)</span></code></p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\">dump_directory_tree_worker(str); </span></code> </p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\">} </span></code> </p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\"></span></code> </p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\">yaffs_closedir(d); </span></code> </p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\">} </span></code> </p>\n<p class=\"code-western\"><code class=\"western\"><span style=\"font-size: 10pt; font-size: small; font-size: small;\">} </span></code> </p>\n<p><br />\n<br />\n</p>\n</div>\n      \";}s:9:\"#attached\";a:0:{}s:6:\"#cache\";a:3:{s:8:\"contexts\";a:4:{i:0;s:28:\"languages:language_interface\";i:1;s:5:\"theme\";i:2;s:17:\"url.path.is_front\";i:3;s:16:\"user.permissions\";}s:4:\"tags\";a:4:{i:0;s:29:\"config:filter.format.raw_html\";i:1;s:7:\"file:80\";i:2;s:8:\"node:453\";i:3;s:9:\"node_view\";}s:7:\"max-age\";i:-1;}}',-1,1505139221.295,1,'config:filter.format.raw_html file:80 node:453 node_view rendered','262'),('entity_view:node:453:search_result:[languages:language_interface]=en:[theme]=yaffs:[user.permissions]=aa7fc4c8fb40c7a8665ccd12fea07926dff0f59b9ee3346bc513c6399bee5b01','a:2:{s:15:\"#cache_redirect\";b:1;s:6:\"#cache\";a:5:{s:4:\"keys\";a:4:{i:0;s:11:\"entity_view\";i:1;s:4:\"node\";i:2;s:3:\"453\";i:3;s:13:\"search_result\";}s:8:\"contexts\";a:4:{i:0;s:28:\"languages:language_interface\";i:1;s:5:\"theme\";i:2;s:17:\"url.path.is_front\";i:3;s:16:\"user.permissions\";}s:4:\"tags\";a:4:{i:0;s:29:\"config:filter.format.raw_html\";i:1;s:7:\"file:80\";i:2;s:8:\"node:453\";i:3;s:9:\"node_view\";}s:7:\"max-age\";i:-1;s:3:\"bin\";s:6:\"render\";}}',-1,1505139221.293,1,'config:filter.format.raw_html file:80 node:453 node_view rendered','262'),('entity_view:node:453:teaser:[languages:language_interface]=en:[theme]=yaffs:[timezone]=Europe/London:[url.path.is_front]=is_front.0:[user.permissions]=aa7fc4c8fb40c7a8665ccd12fea07926dff0f59b9ee3346bc513c6399bee5b01','a:3:{s:7:\"#markup\";O:25:\"Drupal\\Core\\Render\\Markup\":1:{s:9:\"\0*\0string\";s:1483:\"<article role=\"article\" about=\"/documents/yaffs-direct-interface\" class=\"paper is-promoted teaser clearfix\">\n\n  \n      <h2>\n      <a href=\"/documents/yaffs-direct-interface\" rel=\"bookmark\"><span>Yaffs Direct Interface</span>\n</a>\n    </h2>\n    \n\n      <footer>\n      \n      <div class=\"author\">\n        Submitted by <span><span lang=\"\" about=\"/user/admin\" typeof=\"schema:Person\" property=\"schema:name\" datatype=\"\">Admin</span></span>\n on <span>23 July, 2012 - 12:37am</span>\n        \n      </div>\n    </footer>\n  \n  <div class=\"content\">\n    <ul class=\"links inline list-inline\"><li class=\"node-readmore\"><a href=\"/documents/yaffs-direct-interface\" rel=\"tag\" title=\"Yaffs Direct Interface\" hreflang=\"und\">Read more<span class=\"visually-hidden\"> about Yaffs Direct Interface</span></a></li></ul>\n            <div class=\"field field--name-field-teaser-image field--type-image field--label-hidden field--item\">  <a href=\"/documents/yaffs-direct-interface\"><img src=\"/sites/default/files/styles/pdf_image/public/styles/pdf_image/public/downloads/YaffsDirect.pdf.png?itok=Sl5XB97b\" alt=\"Preview of YaffsDirect.pdf\" typeof=\"foaf:Image\" class=\"img-responsive\" />\n\n</a>\n</div>\n      \n            <div class=\"field field--name-body field--type-text-with-summary field--label-hidden field--item\">\n<p>This describes the Yaffs Direct Interface (YDI), which allows Yaffs to be simply integrated with embedded systems, with or without an RTOS.</p>\n<p>&nbsp;</p>\n</div>\n      \n  </div>\n\n</article>\n\";}s:9:\"#attached\";a:0:{}s:6:\"#cache\";a:3:{s:8:\"contexts\";a:5:{i:0;s:28:\"languages:language_interface\";i:1;s:5:\"theme\";i:2;s:8:\"timezone\";i:3;s:17:\"url.path.is_front\";i:4;s:16:\"user.permissions\";}s:4:\"tags\";a:6:{i:0;s:29:\"config:filter.format.raw_html\";i:1;s:28:\"config:image.style.pdf_image\";i:2;s:7:\"file:81\";i:3;s:8:\"node:453\";i:4;s:9:\"node_view\";i:5;s:6:\"user:1\";}s:7:\"max-age\";i:-1;}}',-1,1504640549.381,1,'config:filter.format.raw_html config:image.style.pdf_image file:81 node:453 node_view rendered user:1','281'),('entity_view:node:453:teaser:[languages:language_interface]=en:[theme]=yaffs:[user.permissions]=aa7fc4c8fb40c7a8665ccd12fea07926dff0f59b9ee3346bc513c6399bee5b01','a:2:{s:15:\"#cache_redirect\";b:1;s:6:\"#cache\";a:5:{s:4:\"keys\";a:4:{i:0;s:11:\"entity_view\";i:1;s:4:\"node\";i:2;s:3:\"453\";i:3;s:6:\"teaser\";}s:8:\"contexts\";a:5:{i:0;s:28:\"languages:language_interface\";i:1;s:5:\"theme\";i:2;s:8:\"timezone\";i:3;s:17:\"url.path.is_front\";i:4;s:16:\"user.permissions\";}s:4:\"tags\";a:6:{i:0;s:29:\"config:filter.format.raw_html\";i:1;s:28:\"config:image.style.pdf_image\";i:2;s:7:\"file:81\";i:3;s:8:\"node:453\";i:4;s:9:\"node_view\";i:5;s:6:\"user:1\";}s:7:\"max-age\";i:-1;s:3:\"bin\";s:6:\"render\";}}',-1,1504640549.379,1,'config:filter.format.raw_html config:image.style.pdf_image file:81 node:453 node_view rendered user:1','281'),('entity_view:node:454:full:[languages:language_interface]=en:[theme]=yaffs:[timezone]=Europe/London:[url.path.is_front]=is_front.0:[user.permissions]=aa7fc4c8fb40c7a8665ccd12fea07926dff0f59b9ee3346bc513c6399bee5b0WUPZHj2SzV1Om3yaKhkHZoFbRjP8nhf3CvXB3l9EiQg','a:5:{s:7:\"#markup\";O:25:\"Drupal\\Core\\Render\\Markup\":1:{s:9:\"\0*\0string\";s:2834:\"<article role=\"article\" about=\"/running-yaffs-direct-tests\" typeof=\"schema:Article\" class=\"article is-promoted full clearfix\">\n\n  \n      <span property=\"schema:name\" content=\"Running Yaffs Direct Tests\" class=\"hidden\"></span>\n\n\n  \n  <div class=\"content\">\n    \n      <div class=\"field field--name-upload field--type-file field--label-hidden field--items\">\n              <div class=\"field--item\"><span class=\"file file--mime-application-pdf file--application-pdf icon-before\"><span class=\"file-icon\"><span class=\"icon glyphicon glyphicon-file text-primary\" aria-hidden=\"true\"></span></span><span class=\"file-link\"><a href=\"https://yaffs.net/sites/default/files/downloads/YaffsDirectTests.pdf\" type=\"application/pdf; length=53457\" title=\"Open file in new window\" target=\"_blank\" data-toggle=\"tooltip\" data-placement=\"bottom\">YaffsDirectTests.pdf</a></span><span class=\"file-size\">52.2 KB</span></span></div>\n          </div>\n  \n            <div property=\"schema:text\" class=\"field field--name-body field--type-text-with-summary field--label-hidden field--item\">\n<p>&nbsp;</p>\n<h2>1 Background</h2>\n<p>This document is intended to provide a outline to the various tests that are incorporated into Yaffs Direct. Most of these tests were written as debug tools to test error response by various Yaffs functions. These and others can be used to check if Yaffs is working properly.</p>\n<h2>2 Running the tests</h2>\n<p>All of the test directories should have a Makefile. Run it to compile the test. The Readme.txt file should tell you how to run the tests.</p>\n<h2>3 Tests</h2>\n<ul>\n<li>\n<p>is_yaffs_working_tests folder contains a the tests related to simply seeing if yaffs is working. There is only one test at the moment, test_1_yaffs_mount.c, which tests if yaffs will mount, create a file and be able to read the file after remounting.</p>\n </li>\n<li>\n<p>stress_tester folder contains yaffs_tester.c which stress tests yaffs by opening and closing files at random. This test will run forever (or until it crashes).</p>\n </li>\n<li>\n<p>handle_tests folder contains the test handle_tests.c which just creates files and duplicates the file handle.</p>\n </li>\n<li>\n<p>The yaffs_and_linux_mirror_tests folder runs a yaffs operation and then compares the response the same command run under linux. This test is used to check that yaffs responds in expected manner with respect to linux.</p>\n </li>\n<li>\n<p>quick_tests folder contains the quick_test which tests almost all of yaffs functions\' error handling and error codes.</p>\n </li>\n<li>\n<p>The threading folder contains the test_threading.c which tests the thread locking ability of yaffs.</p>\n </li>\n</ul>\n<p>&nbsp;</p>\n<p>The folder linux_tests contains the linux_test.c test which tests yaffs running under linux using the nandsim generator. &nbsp;</p>\n</div>\n      \n  </div>\n\n</article>\n\";}s:9:\"#attached\";a:1:{s:14:\"html_head_link\";a:3:{i:0;a:2:{i:0;a:2:{s:3:\"rel\";s:9:\"canonical\";s:4:\"href\";s:27:\"/running-yaffs-direct-tests\";}i:1;b:1;}i:1;a:2:{i:0;a:2:{s:3:\"rel\";s:9:\"shortlink\";s:4:\"href\";s:9:\"/node/454\";}i:1;b:1;}i:2;a:2:{i:0;a:2:{s:3:\"rel\";s:8:\"revision\";s:4:\"href\";s:27:\"/running-yaffs-direct-tests\";}i:1;b:1;}}}s:6:\"#cache\";a:3:{s:8:\"contexts\";a:7:{i:0;s:28:\"languages:language_interface\";i:1;s:5:\"theme\";i:2;s:8:\"timezone\";i:3;s:17:\"url.path.is_front\";i:4;s:16:\"user.permissions\";i:5;s:20:\"user.roles:anonymous\";i:6;s:24:\"user.roles:authenticated\";}s:4:\"tags\";a:6:{i:0;s:30:\"config:filter.format.full_html\";i:1;s:18:\"config:system.site\";i:2;s:7:\"file:82\";i:3;s:8:\"node:454\";i:4;s:9:\"node_view\";i:5;s:6:\"user:1\";}s:7:\"max-age\";i:-1;}s:17:\"#cache_properties\";a:1:{i:0;s:6:\"#title\";}s:6:\"#title\";O:25:\"Drupal\\Core\\Render\\Markup\":1:{s:9:\"\0*\0string\";s:63:\"<span property=\"schema:name\">Running Yaffs Direct Tests</span>\n\";}}',-1,1504707640.155,1,'config:filter.format.full_html config:system.site file:82 node:454 node_view rendered user:1','313'),('entity_view:node:454:full:[languages:language_interface]=en:[theme]=yaffs:[user.permissions]=aa7fc4c8fb40c7a8665ccd12fea07926dff0f59b9ee3346bc513c6399bee5b01:[user.roles:anonymous]=0','a:2:{s:15:\"#cache_redirect\";b:1;s:6:\"#cache\";a:5:{s:4:\"keys\";a:4:{i:0;s:11:\"entity_view\";i:1;s:4:\"node\";i:2;s:3:\"454\";i:3;s:4:\"full\";}s:8:\"contexts\";a:7:{i:0;s:28:\"languages:language_interface\";i:1;s:5:\"theme\";i:2;s:8:\"timezone\";i:3;s:17:\"url.path.is_front\";i:4;s:16:\"user.permissions\";i:5;s:20:\"user.roles:anonymous\";i:6;s:24:\"user.roles:authenticated\";}s:4:\"tags\";a:6:{i:0;s:30:\"config:filter.format.full_html\";i:1;s:18:\"config:system.site\";i:2;s:7:\"file:82\";i:3;s:8:\"node:454\";i:4;s:9:\"node_view\";i:5;s:6:\"user:1\";}s:7:\"max-age\";i:-1;s:3:\"bin\";s:6:\"render\";}}',-1,1504707640.151,1,'config:filter.format.full_html config:system.site file:82 node:454 node_view rendered user:1','313'),('entity_view:node:454:rss:[languages:language_interface]=en:[theme]=yaffs:[timezone]=Europe/London:[url.path.is_front]=is_front.0:[user.permissions]=aa7fc4c8fb40c7a8665ccd12fea07926dff0f59b9ee3346bc513c6399bee5b01','a:3:{s:7:\"#markup\";O:25:\"Drupal\\Core\\Render\\Markup\":1:{s:9:\"\0*\0string\";s:303:\"<span property=\"schema:name\">Running Yaffs Direct Tests</span>\n<span rel=\"schema:author\"><span lang=\"\" about=\"/user/admin\" typeof=\"schema:Person\" property=\"schema:name\" datatype=\"\">Admin</span></span>\n<span property=\"schema:dateCreated\" content=\"2012-07-23T00:03:16+00:00\">23 July, 2012 - 1:03am</span>\n\";}s:9:\"#attached\";a:0:{}s:6:\"#cache\";a:3:{s:8:\"contexts\";a:5:{i:0;s:28:\"languages:language_interface\";i:1;s:5:\"theme\";i:2;s:8:\"timezone\";i:3;s:17:\"url.path.is_front\";i:4;s:16:\"user.permissions\";}s:4:\"tags\";a:3:{i:0;s:8:\"node:454\";i:1;s:9:\"node_view\";i:2;s:6:\"user:1\";}s:7:\"max-age\";i:-1;}}',-1,1504783535.821,1,'node:454 node_view rendered user:1','266'),('entity_view:node:454:rss:[languages:language_interface]=en:[theme]=yaffs:[user.permissions]=aa7fc4c8fb40c7a8665ccd12fea07926dff0f59b9ee3346bc513c6399bee5b01','a:2:{s:15:\"#cache_redirect\";b:1;s:6:\"#cache\";a:5:{s:4:\"keys\";a:4:{i:0;s:11:\"entity_view\";i:1;s:4:\"node\";i:2;s:3:\"454\";i:3;s:3:\"rss\";}s:8:\"contexts\";a:5:{i:0;s:28:\"languages:language_interface\";i:1;s:5:\"theme\";i:2;s:8:\"timezone\";i:3;s:17:\"url.path.is_front\";i:4;s:16:\"user.permissions\";}s:4:\"tags\";a:3:{i:0;s:8:\"node:454\";i:1;s:9:\"node_view\";i:2;s:6:\"user:1\";}s:7:\"max-age\";i:-1;s:3:\"bin\";s:6:\"render\";}}',-1,1504783535.797,1,'node:454 node_view rendered user:1','266'),('entity_view:node:454:search_result:[languages:language_interface]=en:[theme]=yaffs:[url.path.is_front]=is_front.0:[user.permissions]=aa7fc4c8fb40c7a8665ccd12fea07926dff0f59b9ee3346bc513c6399bee5b01','a:3:{s:7:\"#markup\";O:25:\"Drupal\\Core\\Render\\Markup\":1:{s:9:\"\0*\0string\";s:2616:\"<span property=\"schema:name\">Running Yaffs Direct Tests</span>\n\n      <div class=\"field field--name-upload field--type-file field--label-hidden field--items\">\n              <div class=\"field--item\"><span class=\"file file--mime-application-pdf file--application-pdf icon-before\"><span class=\"file-icon\"><span class=\"icon glyphicon glyphicon-file text-primary\" aria-hidden=\"true\"></span></span><span class=\"file-link\"><a href=\"https://yaffs.net/sites/default/files/downloads/YaffsDirectTests.pdf\" type=\"application/pdf; length=53457\" title=\"Open file in new window\" target=\"_blank\" data-toggle=\"tooltip\" data-placement=\"bottom\">YaffsDirectTests.pdf</a></span><span class=\"file-size\">52.2 KB</span></span></div>\n          </div>\n  \n            <div property=\"schema:text\" class=\"field field--name-body field--type-text-with-summary field--label-hidden field--item\">\n<p>&nbsp;</p>\n<h2>1 Background</h2>\n<p>This document is intended to provide a outline to the various tests that are incorporated into Yaffs Direct. Most of these tests were written as debug tools to test error response by various Yaffs functions. These and others can be used to check if Yaffs is working properly.</p>\n<h2>2 Running the tests</h2>\n<p>All of the test directories should have a Makefile. Run it to compile the test. The Readme.txt file should tell you how to run the tests.</p>\n<h2>3 Tests</h2>\n<ul>\n<li>\n<p>is_yaffs_working_tests folder contains a the tests related to simply seeing if yaffs is working. There is only one test at the moment, test_1_yaffs_mount.c, which tests if yaffs will mount, create a file and be able to read the file after remounting.</p>\n </li>\n<li>\n<p>stress_tester folder contains yaffs_tester.c which stress tests yaffs by opening and closing files at random. This test will run forever (or until it crashes).</p>\n </li>\n<li>\n<p>handle_tests folder contains the test handle_tests.c which just creates files and duplicates the file handle.</p>\n </li>\n<li>\n<p>The yaffs_and_linux_mirror_tests folder runs a yaffs operation and then compares the response the same command run under linux. This test is used to check that yaffs responds in expected manner with respect to linux.</p>\n </li>\n<li>\n<p>quick_tests folder contains the quick_test which tests almost all of yaffs functions\' error handling and error codes.</p>\n </li>\n<li>\n<p>The threading folder contains the test_threading.c which tests the thread locking ability of yaffs.</p>\n </li>\n</ul>\n<p>&nbsp;</p>\n<p>The folder linux_tests contains the linux_test.c test which tests yaffs running under linux using the nandsim generator. &nbsp;</p>\n</div>\n      \";}s:9:\"#attached\";a:0:{}s:6:\"#cache\";a:3:{s:8:\"contexts\";a:4:{i:0;s:28:\"languages:language_interface\";i:1;s:5:\"theme\";i:2;s:17:\"url.path.is_front\";i:3;s:16:\"user.permissions\";}s:4:\"tags\";a:4:{i:0;s:30:\"config:filter.format.full_html\";i:1;s:7:\"file:82\";i:2;s:8:\"node:454\";i:3;s:9:\"node_view\";}s:7:\"max-age\";i:-1;}}',-1,1505188402.804,1,'config:filter.format.full_html file:82 node:454 node_view rendered','300'),('entity_view:node:454:search_result:[languages:language_interface]=en:[theme]=yaffs:[user.permissions]=aa7fc4c8fb40c7a8665ccd12fea07926dff0f59b9ee3346bc513c6399bee5b01','a:2:{s:15:\"#cache_redirect\";b:1;s:6:\"#cache\";a:5:{s:4:\"keys\";a:4:{i:0;s:11:\"entity_view\";i:1;s:4:\"node\";i:2;s:3:\"454\";i:3;s:13:\"search_result\";}s:8:\"contexts\";a:4:{i:0;s:28:\"languages:language_interface\";i:1;s:5:\"theme\";i:2;s:17:\"url.path.is_front\";i:3;s:16:\"user.permissions\";}s:4:\"tags\";a:4:{i:0;s:30:\"config:filter.format.full_html\";i:1;s:7:\"file:82\";i:2;s:8:\"node:454\";i:3;s:9:\"node_view\";}s:7:\"max-age\";i:-1;s:3:\"bin\";s:6:\"render\";}}',-1,1505188402.801,1,'config:filter.format.full_html file:82 node:454 node_view rendered','300'),('entity_view:node:454:teaser:[languages:language_interface]=en:[theme]=yaffs:[timezone]=Europe/London:[url.path.is_front]=is_front.0:[user.permissions]=aa7fc4c8fb40c7a8665ccd12fea07926dff0f59b9ee3346bc513c6399bee5b01','a:3:{s:7:\"#markup\";O:25:\"Drupal\\Core\\Render\\Markup\":1:{s:9:\"\0*\0string\";s:1093:\"<article role=\"article\" about=\"/running-yaffs-direct-tests\" typeof=\"schema:Article\" class=\"article is-promoted teaser clearfix\">\n\n  \n      <h2>\n      <a href=\"/running-yaffs-direct-tests\" rel=\"bookmark\"><span property=\"schema:name\">Running Yaffs Direct Tests</span>\n</a>\n    </h2>\n      <span property=\"schema:name\" content=\"Running Yaffs Direct Tests\" class=\"hidden\"></span>\n\n\n  \n  <div class=\"content\">\n    \n            <div property=\"schema:text\" class=\"field field--name-body field--type-text-with-summary field--label-hidden field--item\">\n<p>This provides a outline to the various tests that are incorporated into Yaffs Direct. Most of these tests were written as debug tools to test error response by various Yaffs functions. These and others can be used to check if Yaffs is working properly.</p>\n</div>\n      <ul class=\"links inline list-inline\"><li class=\"node-readmore\"><a href=\"/running-yaffs-direct-tests\" rel=\"tag\" title=\"Running Yaffs Direct Tests\" hreflang=\"und\">Read more<span class=\"visually-hidden\"> about Running Yaffs Direct Tests</span></a></li></ul>\n  </div>\n\n</article>\n\";}s:9:\"#attached\";a:0:{}s:6:\"#cache\";a:3:{s:8:\"contexts\";a:5:{i:0;s:28:\"languages:language_interface\";i:1;s:5:\"theme\";i:2;s:8:\"timezone\";i:3;s:17:\"url.path.is_front\";i:4;s:16:\"user.permissions\";}s:4:\"tags\";a:4:{i:0;s:30:\"config:filter.format.full_html\";i:1;s:8:\"node:454\";i:2;s:9:\"node_view\";i:3;s:6:\"user:1\";}s:7:\"max-age\";i:-1;}}',-1,1504640549.361,1,'config:filter.format.full_html node:454 node_view rendered user:1','306'),('entity_view:node:454:teaser:[languages:language_interface]=en:[theme]=yaffs:[user.permissions]=aa7fc4c8fb40c7a8665ccd12fea07926dff0f59b9ee3346bc513c6399bee5b01','a:2:{s:15:\"#cache_redirect\";b:1;s:6:\"#cache\";a:5:{s:4:\"keys\";a:4:{i:0;s:11:\"entity_view\";i:1;s:4:\"node\";i:2;s:3:\"454\";i:3;s:6:\"teaser\";}s:8:\"contexts\";a:5:{i:0;s:28:\"languages:language_interface\";i:1;s:5:\"theme\";i:2;s:8:\"timezone\";i:3;s:17:\"url.path.is_front\";i:4;s:16:\"user.permissions\";}s:4:\"tags\";a:4:{i:0;s:30:\"config:filter.format.full_html\";i:1;s:8:\"node:454\";i:2;s:9:\"node_view\";i:3;s:6:\"user:1\";}s:7:\"max-age\";i:-1;s:3:\"bin\";s:6:\"render\";}}',-1,1504640549.359,1,'config:filter.format.full_html node:454 node_view rendered user:1','306'),('entity_view:node:455:full:[languages:language_interface]=en:[theme]=yaffs:[timezone]=Europe/London:[url.path.is_front]=is_front.0:[user.permissions]=aa7fc4c8fb40c7a8665ccd12fea07926dff0f59b9ee3346bc513c6399bee5b0mn4uxGsp_TIwdOYGXCPzwX4jkpVbiYCwDGLFATHh89o','a:5:{s:7:\"#markup\";O:25:\"Drupal\\Core\\Render\\Markup\":1:{s:9:\"\0*\0string\";s:22471:\"<article role=\"article\" about=\"/documents/yaffs-nand-flash-failure-mitigation\" class=\"paper is-promoted full clearfix\">\n\n  \n    \n\n      <footer>\n      \n      <div class=\"author\">\n        Submitted by <span><span lang=\"\" about=\"/user/admin\" typeof=\"schema:Person\" property=\"schema:name\" datatype=\"\">Admin</span></span>\n on <span>23 July, 2012 - 1:29am</span>\n        \n      </div>\n    </footer>\n  \n  <div class=\"content\">\n    \n      <div class=\"field field--name-upload field--type-file field--label-hidden field--items\">\n              <div class=\"field--item\"><span class=\"file file--mime-application-pdf file--application-pdf icon-before\"><span class=\"file-icon\"><span class=\"icon glyphicon glyphicon-file text-primary\" aria-hidden=\"true\"></span></span><span class=\"file-link\"><a href=\"https://yaffs.net/sites/default/files/downloads/YaffsNandFailureMitigation.pdf\" type=\"application/pdf; length=235109\" title=\"Open file in new window\" target=\"_blank\" data-toggle=\"tooltip\" data-placement=\"bottom\">YaffsNandFailureMitigation.pdf</a></span><span class=\"file-size\">229.6 KB</span></span></div>\n          </div>\n  \n            <div class=\"field field--name-body field--type-text-with-summary field--label-hidden field--item\">\n<p>&nbsp;</p>\n<h2>1 Purpose</h2>\n<p>The purpose of this document is to give an understanding of NAND failure modes and the measures that Yaffs takes to mitigate against these.</p>\n<p>This document is intended to be easy reading, but some very light-weight physics is required to understand the way NAND works.</p>\n<h2>2 The NAND Cell</h2>\n<p>This section explains the internal construction of a NAND device which helps to explain the way that it fails. Each NAND cell consists of a floating gate field effect transistor, described below.</p>\n<h3>2.1 Floating Gate Field Effect Transistor</h3>\n<p>A FET is the fundamental switching element used in almost all digital electronics. A FET is a a semiconductor element that conducts when a charge is applied to the gate.</p>\n<p><img alt=\"\" src=\"/sites/yaffs.net/files/images/fets.gif\" /></p>\n<p>A FET is a type of semiconductor device with a semiconducting region between the the source and drain connections, an insulating oxide and a gate region. The oxide prevents current from flowing from the gate to the oxide, but applying a voltage to the gate injects charge into the gate, creating an electric field which influences the conductive properties of the semiconductor region.</p>\n<p>In a regular FET, a conductive channel is formed between the source and drain when a suitable control voltage is applied to the gate. The current passed by the channel is dependent on the voltage (ie. the strength of the gate field). For now we will ignore analogue levels and just consider binary levels where the gate is either conducting or not. This effectively makes a switch that is controlled by the control gate.</p>\n<p>The floating gate FET is just like a regular FET except that it has an extra floating gate. This floating gate is able to trap charge between the two insulating layers. The trapped charge modifies the local electric field and thus modifies the effect of the control gate. If the floating gate has extra electrons (negative charge) then the control gate must be raised to a higher voltage to make the FET conduct.</p>\n<p>So a regular FET is conductive (on) when the control gate is high and is non-conductive (off) when the control gate is low. A floating gate FET, however, is only non-conductive (off) when the floating gate is charged and the gate is low. This gives us an output that is dependent on the floating gate and a way to read it (the gate).</p>\n<table>\n<colgroup>\n <col /> <col /> <col />\n</colgroup>\n<tbody>\n <tr>\n  <td>\n  <p><strong>Floating gate charge</strong></p>\n   </td>\n  <td>\n  <p><strong>Control gate</strong></p>\n   </td>\n  <td>\n  <p><strong>Source/drain channel</strong></p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p>Neutral(unprogrammed)</p>\n   </td>\n  <td>\n  <p>High</p>\n   </td>\n  <td>\n  <p>On (1)</p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p>Neutral(unprogrammed)</p>\n   </td>\n  <td>\n  <p>Low</p>\n   </td>\n  <td>\n  <p>On (1)</p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p>Charged(programmed)</p>\n   </td>\n  <td>\n  <p>High</p>\n   </td>\n  <td>\n  <p>On (1)</p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p>Charged(programmed)</p>\n   </td>\n  <td>\n  <p>Low</p>\n   </td>\n  <td>\n  <p>Off (0)</p>\n   </td>\n </tr>\n</tbody>\n</table>\n<p><br />\n&nbsp;</p>\n<p>The tunneling oxide is insulating at low voltages but allows quantum tunneling (Fowler-Nordheim tunneling) at higher voltages. This FN-tunneling provides a mechanism to inject or remove charge from the floating gate by applying high voltages to the control gate or the body.</p>\n<p><img alt=\"\" src=\"/sites/yaffs.net/files/images/fn-tunnelling.gif\" /></p>\n<p>By applying a high positive voltage to the control gate, electrons are drawn into the floating gate, resulting in a programmed gate. Erasing is accomplished by the reverse operation which draws electrons out of the gate.</p>\n<p>So a floating gate FET is effectively a readable, programmable switch. In other words: memory!</p>\n<h3>2.2 NAND array layout</h3>\n<p>NAND flash gets its name from the way that the cells are arranged. NAND cells are arranged in chains called <em><strong>strings</strong></em>, typically 1 string per bit-position in the page n(for SLC). The length of the chain is the same as the number of pages per block. This arrangement uses far less silicon area than the NOR flash arrangement which reduces NAND cost and increases density. It does however also introduce some operational and reliability problems.</p>\n<p><img alt=\"\" src=\"/sites/yaffs.net/files/images/nand-page-select.gif\" /></p>\n<p>NAND is read by biasing the unselected pages with a high bias voltage and the selected pages with the low bias voltage. This means that the unselected cells are always on and the selected cells will be on or off according to the state of the floating gate.</p>\n<p>This means we have a matrix where:</p>\n<ul>\n<li>\n<p>All unselected cells are on.</p>\n </li>\n<li>\n<p>Selected unprogrammed cells are on</p>\n </li>\n<li>\n<p>Selected programmed cells are off.</p>\n </li>\n</ul>\n<p>Since only one cell in a string is selected at a time, the whole string is on if the selected cell is unprogrammed and is off if the selected cell is programmed. Thus, even though the cells in a string are all in series we can still access them individually.</p>\n<p>Well, that\'s how it would work in a perfect world anyway!</p>\n<p>The string and block arrangement means that it takes quite a while ( typically a few µsec) for the voltage of the string to stabilize after the selection has been made. This stabilization time is the cause of the “access time” delay when accessing NAND flash.</p>\n<h3>3 Fault Modes</h3>\n<p>Sit back for a moment and consider everything that must come together for the NAND flash to work and all the ways things can go wrong:</p>\n<ul>\n<li>\n<p>Of course there can be fabrication faults where defects cause short circuits and open circuits within the chip. These types of fault apply to all chips type, not just flash.</p>\n </li>\n<li>\n<p>Each cell has two oxide layers trapping the floating gate charge, one of which is semi-permeable to support tunneling. If either of these layers is too thick, the gate will be unresponsive. If they are too thin then the gate will tunnel too easily or will leak. If there are impurities in the oxide then the layers may become resistive and “leak”, thus causing the charge to change and possibly causing the state to change.</p>\n </li>\n<li>\n<p>The floating gate state can change by either gaining or losing charge. If charge is lost, then a programmed cell may become unprogrammed (a 0 changes to a 1). If charge is gained, then an unprogrammed cell can become programmed.</p>\n </li>\n<li>\n<p>In very extreme cases, a programmed cell can gain further negative charge and become over-programmed. This means that even if the high read bias voltage is applied to the control gate the FET does not become conductive. In this state, a cell will read as programmed (0) even if it is not selected. This means that the whole string will always read zero irrespective of which page is selected. This fault mode will persist until the cell is erased.</p>\n </li>\n<li>\n<p>These devices are made very cheaply. Flash parts with tens of billions of NAND cells cost only a few dollars. There is little money to spend on individual part testing.</p>\n </li>\n</ul>\n<p>Extending the previous state/selection table with the over-programmed fault state, we now have:</p>\n<table>\n<colgroup>\n <col /> <col /> <col />\n</colgroup>\n<tbody>\n <tr>\n  <td>\n  <p><strong>Floating gate charge</strong></p>\n   </td>\n  <td>\n  <p><strong>Control gate</strong></p>\n   </td>\n  <td>\n  <p><strong>Source/drain channel</strong></p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p>Neutral(unprogrammed)</p>\n   </td>\n  <td>\n  <p>High</p>\n   </td>\n  <td>\n  <p>On (1)</p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p>Neutral(unprogrammed)</p>\n   </td>\n  <td>\n  <p>Low</p>\n   </td>\n  <td>\n  <p>On (1)</p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p>Charged(programmed)</p>\n   </td>\n  <td>\n  <p>High</p>\n   </td>\n  <td>\n  <p>On (1)</p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p>Charged(programmed)</p>\n   </td>\n  <td>\n  <p>Low</p>\n   </td>\n  <td>\n  <p>Off(0)</p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p>Over-charged(over-programmed)</p>\n   </td>\n  <td>\n  <p>High</p>\n   </td>\n  <td>\n  <p>Off(0)</p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p>Over-charged(over-programmed)</p>\n   </td>\n  <td>\n  <p>Low</p>\n   </td>\n  <td>\n  <p>Off(0)</p>\n   </td>\n </tr>\n</tbody>\n</table>\n<h2>4 Fault Mechanisms</h2>\n<p>This section explains some of the common NAND flash failure modes.</p>\n<h3>4.1 General chip fault</h3>\n<p>A NAND is a chip built with normal fabrication techniques and is thus prone to fail just like any other chip. Some of these faults can be isolated by marking faulty blocks. In some cases (eg. Damaged inter-block logic) the whole chip is discarded.</p>\n<p>Yaffs does not use the bad blocks, so they have no negative impact on the performance of the file system 9apart from a small reduction in the amount of storage available).</p>\n<h3>4.2 Oxide degradation</h3>\n<p>Every programming/erasure cycle causes some degradation of the oxide layers. Over many cycles this has a tendency to degrade the properties of the oxide layer. Excessive degradation can cause the cell to fail to erase or program, but more commonly just makes the other fault modes more prevalent.</p>\n<p>The primary mechanism of oxide degradation is that charge becomes permanently trapped within the oxide layer in a way that it is not cleared by programming and erasure. The resulting field disrupts both the FET\'s conductive channel and the effectiveness of the F-N tunneling.</p>\n<p>As a result of this field disruption, two things happen:</p>\n<ul>\n<li>\n<p>The FN tunneling is disrupted which means that the programming and erasure take longer to complete. Eventually programming and erasure might fail (see Program/erase failure below).</p>\n </li>\n<li>\n<p>The programming and erasure is far more marginal meaning that less leakage is required to corrupt a bit value (see Charge leakage below).</p>\n </li>\n</ul>\n<p>This degradation is permanent and incremental and is not cleared by erasure. This degradation is the cause of the endurance term in the NAND specification. Typical NAND flash endurance is 10,000 (MLC) to 100,000(SLC) program/erasure cycles.</p>\n<p>Endurance issues are largely minimized by wear leveling and write-path caching.</p>\n<p>Blocks that become too unreliable are retired from use.</p>\n<h3>4.3 Program/erase failure</h3>\n<p>Programming and erase operations are controlled by a built-in state machine that applies the programming/erasure voltages for a while then check whether the operation has succeeded. This is typically performed by an iterative algorithm that will time out if too many cycles are required.</p>\n<p>A failure is signaled in the chip status register when the built-in programming/erasure mechanisms fail to accomplish the programming or erasure within the maximum program/erasure time.</p>\n<p>It is important to realize that a programming failure is only checked on bits being set to a zero. If one bits are inadvertently set to zero then these are not raised as programming errors but are considered to be program disturb errors.</p>\n<p>Program/erase errors are generally the result of excessive oxide degradation.</p>\n<p>Yaffs handles programming/erasure errors as unrecoverable “hard errors”. If these are encountered then useful data is copied off the block and the whole block is permanently retired by marking the block as a bad block.</p>\n<p>These are the only failures that the NAND devices will actually identify. All other failures need to be detected in software.</p>\n<h3>4.4 Charge leakage</h3>\n<p>The oxide isolating the floating gate is not a perfect insulator and charge can escape very slowly, particularly at temperature extremes and when the oxide had been degraded by extensive use. High radiation environments can also make this worse.</p>\n<p>An effective way to handle charge leakage is to use ECC to detect and correct errors. Blocks with errors are rewritten on a fresh block allowing the data to be recreated before unrecoverable errors occur.</p>\n<h3>4.5 Program disturb</h3>\n<p>Program disturb happens when a bit is unintentionally programmed (1 to 0) during a programming operation. The affected bit can be in the same page or elsewhere in the block.</p>\n<p>Program disturb is caused by bias conditions in the flash block during programming. Even though full programming voltage is only applied to the cells being programmed, the other cells are also subject to lesser voltages and minor tunneling can occur. This effect is far less than regular programming but is more than read disturb. However, since a page is only programmed once before the block is erased, there is no multiplier effect as there is in read disturb.</p>\n<p>This condition is made worse by random programming in the block and by applying multiple partial writes to the pages.</p>\n<p>Yaffs1 only writes pages in a block in sequential order and writes pages only once, except for writing deletion markers.</p>\n<p>Yaffs2 does not write deletion markers and thus only programs pages sequentially and only once.</p>\n<p>Thus, Yaffs2 is far less likely to cause write disturb. Yaffs1 should only be used with devices that are tolerant of partial page programming.</p>\n<p>Program disturb within the same page can be corrected by verifying the page after programming.</p>\n<p>ECC provides a mechanism to correct infrequent program disturb errors.</p>\n<h3>4.6 Read disturb</h3>\n<p>Whenever a page is read, the other pages in the block are biased at a read-inhibit voltage to turn them on. While this voltage is not as high as the programming voltage, some very slight F-N tunneling can occur. With sufficient leakage the cell state may change, or the cell may become over-programmed. This effect is known as read disturb.</p>\n<p>Read disturb only impacts the pages in the block that are <em><strong>not</strong></em> <strong></strong>being read. This makes it difficult to detect in some systems. For example, consider a block where only the first page is read repeatedly. Other pages in the block may be incurring read disturb but these are happening without the effect being noticed by software. By the time the pages are eventually read, the read disturb may have caused more bit errors than the ECC is able to fix.</p>\n<p>Thankfully the problem is seldom that bad. Read disturb is very gradual. Under worst case conditions read disturb effects are expected to happen only after approximately 1 million page reads on the block for SLC flash or 100,000 page reads on the block for most MLC flash (or in other words, 10 times the endurance number).</p>\n<p>Be warned though that as process sizes shrink, read disturb is getting more problematic. Some flash parts are prone to read disturb after 20,000 page reads.</p>\n<p>The read disturb effect for a single read is far less than the write disturb effect for a single write. However, each page is only written once per block erase cycle but may be read many times. Therefore the cumulated effect of many read disturbs can cause problems.</p>\n<p>Read disturb effects are cleared by erasing the block.</p>\n<p>Various mechanisms are being implemented to correct read disturb in Yaffs, though these have not yet been implemented.</p>\n<p>The first mechanism is to count the number of page reads on each block. When a certain threshold is reached (say 50,000 reads for an MLC part), the block is rewritten and the count is zeroed.</p>\n<p>The second mechanism is to periodically read pages in the block. eg. Every 256 times a block has a page read we read an additional page to check for read disturb. If read disturb has happened then copy onto a fresh page.</p>\n<p>In addition, ECC does provide some benefit, but is insufficient on its own.</p>\n<h2>5 Decoding NAND reliability statistics</h2>\n<p>Many variables contribute to NAND reliability. These variables are inter-related in complex ways which mean that is is very difficult to try to isolate the variables from each other to fully characterize them. The major variables are:</p>\n<table>\n<colgroup>\n <col /> <col />\n</colgroup>\n<tbody>\n <tr>\n  <td>\n  <p>Temperature</p>\n   </td>\n  <td>\n  <p>Temperature impacts the performance of the materials and thus impacts the movement of charge within the NAND cells.</p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p>Storage time</p>\n   </td>\n  <td>\n  <p>This is related to the cell leakage. The leakage integrates over time so the longer the cells are stored, the more it changes.</p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p>Manufacturing variance</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p>Operating voltage</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p>Erasure/programming cycles</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p>Read cycles</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n </tr>\n</tbody>\n</table>\n<h2>6 MLC vs SLC</h2>\n<p>Both multi-level cell (MLC) and single-level cell (SLC) NAND cells work by trapping charge in the floating gate. By trapping different amounts of charge in the gate it is possible to modify the conductance of the string. MLC store two bits in once cell by using three threshold voltages to distinguish different cell charge levels<a href=\"#sdfootnote1sym\">1</a>.</p>\n<p><img alt=\"\" src=\"/sites/yaffs.net/files/images/nand-mlc-vs-slc-cell-voltages.gif\" /></p>\n<p>In the case of SLC, the cells are erased by the erasure state machine until the cell voltage is below V erase. Programming is accomplished by programming until the voltage exceeds Vprog. On reading, the voltage is compared with Vread.</p>\n<p>MLC programming is accomplished in the same way, except that there are multiple Vprogs and Vreads. This means that there is far less margin for error and cell disturbance is far more likely to cause state changes.</p>\n<p>For this reason, MLC is less reliable, has lower endurance numbers and lower read-disturb numbers. MLC thus requires far better ECC strategies to ensure reliable storage.</p>\n<p>But MLC is cheaper!</p>\n<h2>7 Summary</h2>\n<p>In summary, NAND flash has many failure modes but these can be corrected in software to provide a reliable storage solution. Any flash storage mechanisms that do not provide sufficient coverage of different fault modes should be considered suspect.</p>\n<table>\n<colgroup>\n <col /> <col /> <col /> <col /> <col /> <col /> <col />\n</colgroup>\n<tbody>\n <tr>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p><strong>Chip Fault</strong></p>\n   </td>\n  <td>\n  <p><strong>Degradation</strong></p>\n   </td>\n  <td>\n  <p><strong>P/E failure</strong></p>\n   </td>\n  <td>\n  <p><strong>Leakage</strong></p>\n   </td>\n  <td>\n  <p><strong>Write Disturb</strong></p>\n   </td>\n  <td>\n  <p><strong>Read Disturb</strong></p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p><strong>NAND self check</strong></p>\n   </td>\n  <td>\n  <p>Yes</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>Yes</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p><strong>Block retirement</strong></p>\n   </td>\n  <td>\n  <p>Yes</p>\n   </td>\n  <td>\n  <p>Yes</p>\n   </td>\n  <td>\n  <p>Yes</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p><strong>Wear levelling</strong></p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>Yes</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p><strong>Write Verification</strong></p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>Yes</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p><strong>Read counting/ re-write</strong></p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>Future</p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p><strong>Infrequent read checking</strong></p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>Future</p>\n   </td>\n  <td>\n  <p>Future</p>\n   </td>\n  <td>\n  <p>Future</p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p><strong>ECC</strong></p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>Yes</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>Yes</p>\n   </td>\n  <td>\n  <p>Yes</p>\n   </td>\n  <td>\n  <p>Yes</p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p><strong>Occasional rewrite of oldest data</strong></p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>Yes</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>Yes</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>Yes</p>\n   </td>\n </tr>\n</tbody>\n</table>\n<p>Thus all fault mechanisms are covered by at least two corrective mechanisms (read disturb correcting features are planned).</p>\n<p><a href=\"#sdfootnote1anc\">1</a>Some MLC parts store more than 2 bits per cell, Storing n bits requires 2n levels.</p>\n<p>&nbsp;</p>\n<p>&nbsp;</p>\n</div>\n      \n  </div>\n\n</article>\n\";}s:9:\"#attached\";a:1:{s:14:\"html_head_link\";a:3:{i:0;a:2:{i:0;a:2:{s:3:\"rel\";s:9:\"canonical\";s:4:\"href\";s:46:\"/documents/yaffs-nand-flash-failure-mitigation\";}i:1;b:1;}i:1;a:2:{i:0;a:2:{s:3:\"rel\";s:9:\"shortlink\";s:4:\"href\";s:9:\"/node/455\";}i:1;b:1;}i:2;a:2:{i:0;a:2:{s:3:\"rel\";s:8:\"revision\";s:4:\"href\";s:46:\"/documents/yaffs-nand-flash-failure-mitigation\";}i:1;b:1;}}}s:6:\"#cache\";a:3:{s:8:\"contexts\";a:7:{i:0;s:28:\"languages:language_interface\";i:1;s:5:\"theme\";i:2;s:8:\"timezone\";i:3;s:17:\"url.path.is_front\";i:4;s:16:\"user.permissions\";i:5;s:20:\"user.roles:anonymous\";i:6;s:24:\"user.roles:authenticated\";}s:4:\"tags\";a:6:{i:0;s:30:\"config:filter.format.full_html\";i:1;s:18:\"config:system.site\";i:2;s:7:\"file:83\";i:3;s:8:\"node:455\";i:4;s:9:\"node_view\";i:5;s:6:\"user:1\";}s:7:\"max-age\";i:-1;}s:17:\"#cache_properties\";a:1:{i:0;s:6:\"#title\";}s:6:\"#title\";O:25:\"Drupal\\Core\\Render\\Markup\":1:{s:9:\"\0*\0string\";s:49:\"<span>Yaffs NAND flash failure mitigation</span>\n\";}}',-1,1504634714.617,1,'config:filter.format.full_html config:system.site file:83 node:455 node_view rendered user:1','317'),('entity_view:node:455:full:[languages:language_interface]=en:[theme]=yaffs:[user.permissions]=aa7fc4c8fb40c7a8665ccd12fea07926dff0f59b9ee3346bc513c6399bee5b01:[user.roles:anonymous]=0','a:2:{s:15:\"#cache_redirect\";b:1;s:6:\"#cache\";a:5:{s:4:\"keys\";a:4:{i:0;s:11:\"entity_view\";i:1;s:4:\"node\";i:2;s:3:\"455\";i:3;s:4:\"full\";}s:8:\"contexts\";a:7:{i:0;s:28:\"languages:language_interface\";i:1;s:5:\"theme\";i:2;s:8:\"timezone\";i:3;s:17:\"url.path.is_front\";i:4;s:16:\"user.permissions\";i:5;s:20:\"user.roles:anonymous\";i:6;s:24:\"user.roles:authenticated\";}s:4:\"tags\";a:6:{i:0;s:30:\"config:filter.format.full_html\";i:1;s:18:\"config:system.site\";i:2;s:7:\"file:83\";i:3;s:8:\"node:455\";i:4;s:9:\"node_view\";i:5;s:6:\"user:1\";}s:7:\"max-age\";i:-1;s:3:\"bin\";s:6:\"render\";}}',-1,1504634714.615,1,'config:filter.format.full_html config:system.site file:83 node:455 node_view rendered user:1','317'),('entity_view:node:455:rss:[languages:language_interface]=en:[theme]=yaffs:[timezone]=Europe/London:[url.path.is_front]=is_front.0:[user.permissions]=aa7fc4c8fb40c7a8665ccd12fea07926dff0f59b9ee3346bc513c6399bee5b01','a:3:{s:7:\"#markup\";O:25:\"Drupal\\Core\\Render\\Markup\":1:{s:9:\"\0*\0string\";s:22227:\"<span>Yaffs NAND flash failure mitigation</span>\n<span><span lang=\"\" about=\"/user/admin\" typeof=\"schema:Person\" property=\"schema:name\" datatype=\"\">Admin</span></span>\n<span>23 July, 2012 - 1:29am</span>\n\n      <div class=\"field field--name-upload field--type-file field--label-hidden field--items\">\n              <div class=\"field--item\"><span class=\"file file--mime-application-pdf file--application-pdf icon-before\"><span class=\"file-icon\"><span class=\"icon glyphicon glyphicon-file text-primary\" aria-hidden=\"true\"></span></span><span class=\"file-link\"><a href=\"https://yaffs.net/sites/default/files/downloads/YaffsNandFailureMitigation.pdf\" type=\"application/pdf; length=235109\" title=\"Open file in new window\" target=\"_blank\" data-toggle=\"tooltip\" data-placement=\"bottom\">YaffsNandFailureMitigation.pdf</a></span><span class=\"file-size\">229.6 KB</span></span></div>\n          </div>\n  \n            <div class=\"field field--name-body field--type-text-with-summary field--label-hidden field--item\">\n<p>&nbsp;</p>\n<h2>1 Purpose</h2>\n<p>The purpose of this document is to give an understanding of NAND failure modes and the measures that Yaffs takes to mitigate against these.</p>\n<p>This document is intended to be easy reading, but some very light-weight physics is required to understand the way NAND works.</p>\n<h2>2 The NAND Cell</h2>\n<p>This section explains the internal construction of a NAND device which helps to explain the way that it fails. Each NAND cell consists of a floating gate field effect transistor, described below.</p>\n<h3>2.1 Floating Gate Field Effect Transistor</h3>\n<p>A FET is the fundamental switching element used in almost all digital electronics. A FET is a a semiconductor element that conducts when a charge is applied to the gate.</p>\n<p><img alt=\"\" src=\"/sites/yaffs.net/files/images/fets.gif\" /></p>\n<p>A FET is a type of semiconductor device with a semiconducting region between the the source and drain connections, an insulating oxide and a gate region. The oxide prevents current from flowing from the gate to the oxide, but applying a voltage to the gate injects charge into the gate, creating an electric field which influences the conductive properties of the semiconductor region.</p>\n<p>In a regular FET, a conductive channel is formed between the source and drain when a suitable control voltage is applied to the gate. The current passed by the channel is dependent on the voltage (ie. the strength of the gate field). For now we will ignore analogue levels and just consider binary levels where the gate is either conducting or not. This effectively makes a switch that is controlled by the control gate.</p>\n<p>The floating gate FET is just like a regular FET except that it has an extra floating gate. This floating gate is able to trap charge between the two insulating layers. The trapped charge modifies the local electric field and thus modifies the effect of the control gate. If the floating gate has extra electrons (negative charge) then the control gate must be raised to a higher voltage to make the FET conduct.</p>\n<p>So a regular FET is conductive (on) when the control gate is high and is non-conductive (off) when the control gate is low. A floating gate FET, however, is only non-conductive (off) when the floating gate is charged and the gate is low. This gives us an output that is dependent on the floating gate and a way to read it (the gate).</p>\n<table>\n<colgroup>\n <col /> <col /> <col />\n</colgroup>\n<tbody>\n <tr>\n  <td>\n  <p><strong>Floating gate charge</strong></p>\n   </td>\n  <td>\n  <p><strong>Control gate</strong></p>\n   </td>\n  <td>\n  <p><strong>Source/drain channel</strong></p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p>Neutral(unprogrammed)</p>\n   </td>\n  <td>\n  <p>High</p>\n   </td>\n  <td>\n  <p>On (1)</p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p>Neutral(unprogrammed)</p>\n   </td>\n  <td>\n  <p>Low</p>\n   </td>\n  <td>\n  <p>On (1)</p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p>Charged(programmed)</p>\n   </td>\n  <td>\n  <p>High</p>\n   </td>\n  <td>\n  <p>On (1)</p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p>Charged(programmed)</p>\n   </td>\n  <td>\n  <p>Low</p>\n   </td>\n  <td>\n  <p>Off (0)</p>\n   </td>\n </tr>\n</tbody>\n</table>\n<p><br />\n&nbsp;</p>\n<p>The tunneling oxide is insulating at low voltages but allows quantum tunneling (Fowler-Nordheim tunneling) at higher voltages. This FN-tunneling provides a mechanism to inject or remove charge from the floating gate by applying high voltages to the control gate or the body.</p>\n<p><img alt=\"\" src=\"/sites/yaffs.net/files/images/fn-tunnelling.gif\" /></p>\n<p>By applying a high positive voltage to the control gate, electrons are drawn into the floating gate, resulting in a programmed gate. Erasing is accomplished by the reverse operation which draws electrons out of the gate.</p>\n<p>So a floating gate FET is effectively a readable, programmable switch. In other words: memory!</p>\n<h3>2.2 NAND array layout</h3>\n<p>NAND flash gets its name from the way that the cells are arranged. NAND cells are arranged in chains called <em><strong>strings</strong></em>, typically 1 string per bit-position in the page n(for SLC). The length of the chain is the same as the number of pages per block. This arrangement uses far less silicon area than the NOR flash arrangement which reduces NAND cost and increases density. It does however also introduce some operational and reliability problems.</p>\n<p><img alt=\"\" src=\"/sites/yaffs.net/files/images/nand-page-select.gif\" /></p>\n<p>NAND is read by biasing the unselected pages with a high bias voltage and the selected pages with the low bias voltage. This means that the unselected cells are always on and the selected cells will be on or off according to the state of the floating gate.</p>\n<p>This means we have a matrix where:</p>\n<ul>\n<li>\n<p>All unselected cells are on.</p>\n </li>\n<li>\n<p>Selected unprogrammed cells are on</p>\n </li>\n<li>\n<p>Selected programmed cells are off.</p>\n </li>\n</ul>\n<p>Since only one cell in a string is selected at a time, the whole string is on if the selected cell is unprogrammed and is off if the selected cell is programmed. Thus, even though the cells in a string are all in series we can still access them individually.</p>\n<p>Well, that\'s how it would work in a perfect world anyway!</p>\n<p>The string and block arrangement means that it takes quite a while ( typically a few µsec) for the voltage of the string to stabilize after the selection has been made. This stabilization time is the cause of the “access time” delay when accessing NAND flash.</p>\n<h3>3 Fault Modes</h3>\n<p>Sit back for a moment and consider everything that must come together for the NAND flash to work and all the ways things can go wrong:</p>\n<ul>\n<li>\n<p>Of course there can be fabrication faults where defects cause short circuits and open circuits within the chip. These types of fault apply to all chips type, not just flash.</p>\n </li>\n<li>\n<p>Each cell has two oxide layers trapping the floating gate charge, one of which is semi-permeable to support tunneling. If either of these layers is too thick, the gate will be unresponsive. If they are too thin then the gate will tunnel too easily or will leak. If there are impurities in the oxide then the layers may become resistive and “leak”, thus causing the charge to change and possibly causing the state to change.</p>\n </li>\n<li>\n<p>The floating gate state can change by either gaining or losing charge. If charge is lost, then a programmed cell may become unprogrammed (a 0 changes to a 1). If charge is gained, then an unprogrammed cell can become programmed.</p>\n </li>\n<li>\n<p>In very extreme cases, a programmed cell can gain further negative charge and become over-programmed. This means that even if the high read bias voltage is applied to the control gate the FET does not become conductive. In this state, a cell will read as programmed (0) even if it is not selected. This means that the whole string will always read zero irrespective of which page is selected. This fault mode will persist until the cell is erased.</p>\n </li>\n<li>\n<p>These devices are made very cheaply. Flash parts with tens of billions of NAND cells cost only a few dollars. There is little money to spend on individual part testing.</p>\n </li>\n</ul>\n<p>Extending the previous state/selection table with the over-programmed fault state, we now have:</p>\n<table>\n<colgroup>\n <col /> <col /> <col />\n</colgroup>\n<tbody>\n <tr>\n  <td>\n  <p><strong>Floating gate charge</strong></p>\n   </td>\n  <td>\n  <p><strong>Control gate</strong></p>\n   </td>\n  <td>\n  <p><strong>Source/drain channel</strong></p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p>Neutral(unprogrammed)</p>\n   </td>\n  <td>\n  <p>High</p>\n   </td>\n  <td>\n  <p>On (1)</p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p>Neutral(unprogrammed)</p>\n   </td>\n  <td>\n  <p>Low</p>\n   </td>\n  <td>\n  <p>On (1)</p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p>Charged(programmed)</p>\n   </td>\n  <td>\n  <p>High</p>\n   </td>\n  <td>\n  <p>On (1)</p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p>Charged(programmed)</p>\n   </td>\n  <td>\n  <p>Low</p>\n   </td>\n  <td>\n  <p>Off(0)</p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p>Over-charged(over-programmed)</p>\n   </td>\n  <td>\n  <p>High</p>\n   </td>\n  <td>\n  <p>Off(0)</p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p>Over-charged(over-programmed)</p>\n   </td>\n  <td>\n  <p>Low</p>\n   </td>\n  <td>\n  <p>Off(0)</p>\n   </td>\n </tr>\n</tbody>\n</table>\n<h2>4 Fault Mechanisms</h2>\n<p>This section explains some of the common NAND flash failure modes.</p>\n<h3>4.1 General chip fault</h3>\n<p>A NAND is a chip built with normal fabrication techniques and is thus prone to fail just like any other chip. Some of these faults can be isolated by marking faulty blocks. In some cases (eg. Damaged inter-block logic) the whole chip is discarded.</p>\n<p>Yaffs does not use the bad blocks, so they have no negative impact on the performance of the file system 9apart from a small reduction in the amount of storage available).</p>\n<h3>4.2 Oxide degradation</h3>\n<p>Every programming/erasure cycle causes some degradation of the oxide layers. Over many cycles this has a tendency to degrade the properties of the oxide layer. Excessive degradation can cause the cell to fail to erase or program, but more commonly just makes the other fault modes more prevalent.</p>\n<p>The primary mechanism of oxide degradation is that charge becomes permanently trapped within the oxide layer in a way that it is not cleared by programming and erasure. The resulting field disrupts both the FET\'s conductive channel and the effectiveness of the F-N tunneling.</p>\n<p>As a result of this field disruption, two things happen:</p>\n<ul>\n<li>\n<p>The FN tunneling is disrupted which means that the programming and erasure take longer to complete. Eventually programming and erasure might fail (see Program/erase failure below).</p>\n </li>\n<li>\n<p>The programming and erasure is far more marginal meaning that less leakage is required to corrupt a bit value (see Charge leakage below).</p>\n </li>\n</ul>\n<p>This degradation is permanent and incremental and is not cleared by erasure. This degradation is the cause of the endurance term in the NAND specification. Typical NAND flash endurance is 10,000 (MLC) to 100,000(SLC) program/erasure cycles.</p>\n<p>Endurance issues are largely minimized by wear leveling and write-path caching.</p>\n<p>Blocks that become too unreliable are retired from use.</p>\n<h3>4.3 Program/erase failure</h3>\n<p>Programming and erase operations are controlled by a built-in state machine that applies the programming/erasure voltages for a while then check whether the operation has succeeded. This is typically performed by an iterative algorithm that will time out if too many cycles are required.</p>\n<p>A failure is signaled in the chip status register when the built-in programming/erasure mechanisms fail to accomplish the programming or erasure within the maximum program/erasure time.</p>\n<p>It is important to realize that a programming failure is only checked on bits being set to a zero. If one bits are inadvertently set to zero then these are not raised as programming errors but are considered to be program disturb errors.</p>\n<p>Program/erase errors are generally the result of excessive oxide degradation.</p>\n<p>Yaffs handles programming/erasure errors as unrecoverable “hard errors”. If these are encountered then useful data is copied off the block and the whole block is permanently retired by marking the block as a bad block.</p>\n<p>These are the only failures that the NAND devices will actually identify. All other failures need to be detected in software.</p>\n<h3>4.4 Charge leakage</h3>\n<p>The oxide isolating the floating gate is not a perfect insulator and charge can escape very slowly, particularly at temperature extremes and when the oxide had been degraded by extensive use. High radiation environments can also make this worse.</p>\n<p>An effective way to handle charge leakage is to use ECC to detect and correct errors. Blocks with errors are rewritten on a fresh block allowing the data to be recreated before unrecoverable errors occur.</p>\n<h3>4.5 Program disturb</h3>\n<p>Program disturb happens when a bit is unintentionally programmed (1 to 0) during a programming operation. The affected bit can be in the same page or elsewhere in the block.</p>\n<p>Program disturb is caused by bias conditions in the flash block during programming. Even though full programming voltage is only applied to the cells being programmed, the other cells are also subject to lesser voltages and minor tunneling can occur. This effect is far less than regular programming but is more than read disturb. However, since a page is only programmed once before the block is erased, there is no multiplier effect as there is in read disturb.</p>\n<p>This condition is made worse by random programming in the block and by applying multiple partial writes to the pages.</p>\n<p>Yaffs1 only writes pages in a block in sequential order and writes pages only once, except for writing deletion markers.</p>\n<p>Yaffs2 does not write deletion markers and thus only programs pages sequentially and only once.</p>\n<p>Thus, Yaffs2 is far less likely to cause write disturb. Yaffs1 should only be used with devices that are tolerant of partial page programming.</p>\n<p>Program disturb within the same page can be corrected by verifying the page after programming.</p>\n<p>ECC provides a mechanism to correct infrequent program disturb errors.</p>\n<h3>4.6 Read disturb</h3>\n<p>Whenever a page is read, the other pages in the block are biased at a read-inhibit voltage to turn them on. While this voltage is not as high as the programming voltage, some very slight F-N tunneling can occur. With sufficient leakage the cell state may change, or the cell may become over-programmed. This effect is known as read disturb.</p>\n<p>Read disturb only impacts the pages in the block that are <em><strong>not</strong></em> <strong></strong>being read. This makes it difficult to detect in some systems. For example, consider a block where only the first page is read repeatedly. Other pages in the block may be incurring read disturb but these are happening without the effect being noticed by software. By the time the pages are eventually read, the read disturb may have caused more bit errors than the ECC is able to fix.</p>\n<p>Thankfully the problem is seldom that bad. Read disturb is very gradual. Under worst case conditions read disturb effects are expected to happen only after approximately 1 million page reads on the block for SLC flash or 100,000 page reads on the block for most MLC flash (or in other words, 10 times the endurance number).</p>\n<p>Be warned though that as process sizes shrink, read disturb is getting more problematic. Some flash parts are prone to read disturb after 20,000 page reads.</p>\n<p>The read disturb effect for a single read is far less than the write disturb effect for a single write. However, each page is only written once per block erase cycle but may be read many times. Therefore the cumulated effect of many read disturbs can cause problems.</p>\n<p>Read disturb effects are cleared by erasing the block.</p>\n<p>Various mechanisms are being implemented to correct read disturb in Yaffs, though these have not yet been implemented.</p>\n<p>The first mechanism is to count the number of page reads on each block. When a certain threshold is reached (say 50,000 reads for an MLC part), the block is rewritten and the count is zeroed.</p>\n<p>The second mechanism is to periodically read pages in the block. eg. Every 256 times a block has a page read we read an additional page to check for read disturb. If read disturb has happened then copy onto a fresh page.</p>\n<p>In addition, ECC does provide some benefit, but is insufficient on its own.</p>\n<h2>5 Decoding NAND reliability statistics</h2>\n<p>Many variables contribute to NAND reliability. These variables are inter-related in complex ways which mean that is is very difficult to try to isolate the variables from each other to fully characterize them. The major variables are:</p>\n<table>\n<colgroup>\n <col /> <col />\n</colgroup>\n<tbody>\n <tr>\n  <td>\n  <p>Temperature</p>\n   </td>\n  <td>\n  <p>Temperature impacts the performance of the materials and thus impacts the movement of charge within the NAND cells.</p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p>Storage time</p>\n   </td>\n  <td>\n  <p>This is related to the cell leakage. The leakage integrates over time so the longer the cells are stored, the more it changes.</p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p>Manufacturing variance</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p>Operating voltage</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p>Erasure/programming cycles</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p>Read cycles</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n </tr>\n</tbody>\n</table>\n<h2>6 MLC vs SLC</h2>\n<p>Both multi-level cell (MLC) and single-level cell (SLC) NAND cells work by trapping charge in the floating gate. By trapping different amounts of charge in the gate it is possible to modify the conductance of the string. MLC store two bits in once cell by using three threshold voltages to distinguish different cell charge levels<a href=\"#sdfootnote1sym\">1</a>.</p>\n<p><img alt=\"\" src=\"/sites/yaffs.net/files/images/nand-mlc-vs-slc-cell-voltages.gif\" /></p>\n<p>In the case of SLC, the cells are erased by the erasure state machine until the cell voltage is below V erase. Programming is accomplished by programming until the voltage exceeds Vprog. On reading, the voltage is compared with Vread.</p>\n<p>MLC programming is accomplished in the same way, except that there are multiple Vprogs and Vreads. This means that there is far less margin for error and cell disturbance is far more likely to cause state changes.</p>\n<p>For this reason, MLC is less reliable, has lower endurance numbers and lower read-disturb numbers. MLC thus requires far better ECC strategies to ensure reliable storage.</p>\n<p>But MLC is cheaper!</p>\n<h2>7 Summary</h2>\n<p>In summary, NAND flash has many failure modes but these can be corrected in software to provide a reliable storage solution. Any flash storage mechanisms that do not provide sufficient coverage of different fault modes should be considered suspect.</p>\n<table>\n<colgroup>\n <col /> <col /> <col /> <col /> <col /> <col /> <col />\n</colgroup>\n<tbody>\n <tr>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p><strong>Chip Fault</strong></p>\n   </td>\n  <td>\n  <p><strong>Degradation</strong></p>\n   </td>\n  <td>\n  <p><strong>P/E failure</strong></p>\n   </td>\n  <td>\n  <p><strong>Leakage</strong></p>\n   </td>\n  <td>\n  <p><strong>Write Disturb</strong></p>\n   </td>\n  <td>\n  <p><strong>Read Disturb</strong></p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p><strong>NAND self check</strong></p>\n   </td>\n  <td>\n  <p>Yes</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>Yes</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p><strong>Block retirement</strong></p>\n   </td>\n  <td>\n  <p>Yes</p>\n   </td>\n  <td>\n  <p>Yes</p>\n   </td>\n  <td>\n  <p>Yes</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p><strong>Wear levelling</strong></p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>Yes</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p><strong>Write Verification</strong></p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>Yes</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p><strong>Read counting/ re-write</strong></p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>Future</p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p><strong>Infrequent read checking</strong></p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>Future</p>\n   </td>\n  <td>\n  <p>Future</p>\n   </td>\n  <td>\n  <p>Future</p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p><strong>ECC</strong></p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>Yes</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>Yes</p>\n   </td>\n  <td>\n  <p>Yes</p>\n   </td>\n  <td>\n  <p>Yes</p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p><strong>Occasional rewrite of oldest data</strong></p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>Yes</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>Yes</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>Yes</p>\n   </td>\n </tr>\n</tbody>\n</table>\n<p>Thus all fault mechanisms are covered by at least two corrective mechanisms (read disturb correcting features are planned).</p>\n<p><a href=\"#sdfootnote1anc\">1</a>Some MLC parts store more than 2 bits per cell, Storing n bits requires 2n levels.</p>\n<p>&nbsp;</p>\n<p>&nbsp;</p>\n</div>\n      \";}s:9:\"#attached\";a:0:{}s:6:\"#cache\";a:3:{s:8:\"contexts\";a:5:{i:0;s:28:\"languages:language_interface\";i:1;s:5:\"theme\";i:2;s:8:\"timezone\";i:3;s:17:\"url.path.is_front\";i:4;s:16:\"user.permissions\";}s:4:\"tags\";a:5:{i:0;s:30:\"config:filter.format.full_html\";i:1;s:7:\"file:83\";i:2;s:8:\"node:455\";i:3;s:9:\"node_view\";i:4;s:6:\"user:1\";}s:7:\"max-age\";i:-1;}}',-1,1504783535.741,1,'config:filter.format.full_html file:83 node:455 node_view rendered user:1','311'),('entity_view:node:455:rss:[languages:language_interface]=en:[theme]=yaffs:[user.permissions]=aa7fc4c8fb40c7a8665ccd12fea07926dff0f59b9ee3346bc513c6399bee5b01','a:2:{s:15:\"#cache_redirect\";b:1;s:6:\"#cache\";a:5:{s:4:\"keys\";a:4:{i:0;s:11:\"entity_view\";i:1;s:4:\"node\";i:2;s:3:\"455\";i:3;s:3:\"rss\";}s:8:\"contexts\";a:5:{i:0;s:28:\"languages:language_interface\";i:1;s:5:\"theme\";i:2;s:8:\"timezone\";i:3;s:17:\"url.path.is_front\";i:4;s:16:\"user.permissions\";}s:4:\"tags\";a:5:{i:0;s:30:\"config:filter.format.full_html\";i:1;s:7:\"file:83\";i:2;s:8:\"node:455\";i:3;s:9:\"node_view\";i:4;s:6:\"user:1\";}s:7:\"max-age\";i:-1;s:3:\"bin\";s:6:\"render\";}}',-1,1504783535.726,1,'config:filter.format.full_html file:83 node:455 node_view rendered user:1','311'),('entity_view:node:455:search_result:[languages:language_interface]=en:[theme]=yaffs:[url.path.is_front]=is_front.0:[user.permissions]=aa7fc4c8fb40c7a8665ccd12fea07926dff0f59b9ee3346bc513c6399bee5b01','a:3:{s:7:\"#markup\";O:25:\"Drupal\\Core\\Render\\Markup\":1:{s:9:\"\0*\0string\";s:22073:\"<span>Yaffs NAND flash failure mitigation</span>\n\n      <div class=\"field field--name-upload field--type-file field--label-hidden field--items\">\n              <div class=\"field--item\"><span class=\"file file--mime-application-pdf file--application-pdf icon-before\"><span class=\"file-icon\"><span class=\"icon glyphicon glyphicon-file text-primary\" aria-hidden=\"true\"></span></span><span class=\"file-link\"><a href=\"https://yaffs.net/sites/default/files/downloads/YaffsNandFailureMitigation.pdf\" type=\"application/pdf; length=235109\" title=\"Open file in new window\" target=\"_blank\" data-toggle=\"tooltip\" data-placement=\"bottom\">YaffsNandFailureMitigation.pdf</a></span><span class=\"file-size\">229.6 KB</span></span></div>\n          </div>\n  \n            <div class=\"field field--name-body field--type-text-with-summary field--label-hidden field--item\">\n<p>&nbsp;</p>\n<h2>1 Purpose</h2>\n<p>The purpose of this document is to give an understanding of NAND failure modes and the measures that Yaffs takes to mitigate against these.</p>\n<p>This document is intended to be easy reading, but some very light-weight physics is required to understand the way NAND works.</p>\n<h2>2 The NAND Cell</h2>\n<p>This section explains the internal construction of a NAND device which helps to explain the way that it fails. Each NAND cell consists of a floating gate field effect transistor, described below.</p>\n<h3>2.1 Floating Gate Field Effect Transistor</h3>\n<p>A FET is the fundamental switching element used in almost all digital electronics. A FET is a a semiconductor element that conducts when a charge is applied to the gate.</p>\n<p><img alt=\"\" src=\"/sites/yaffs.net/files/images/fets.gif\" /></p>\n<p>A FET is a type of semiconductor device with a semiconducting region between the the source and drain connections, an insulating oxide and a gate region. The oxide prevents current from flowing from the gate to the oxide, but applying a voltage to the gate injects charge into the gate, creating an electric field which influences the conductive properties of the semiconductor region.</p>\n<p>In a regular FET, a conductive channel is formed between the source and drain when a suitable control voltage is applied to the gate. The current passed by the channel is dependent on the voltage (ie. the strength of the gate field). For now we will ignore analogue levels and just consider binary levels where the gate is either conducting or not. This effectively makes a switch that is controlled by the control gate.</p>\n<p>The floating gate FET is just like a regular FET except that it has an extra floating gate. This floating gate is able to trap charge between the two insulating layers. The trapped charge modifies the local electric field and thus modifies the effect of the control gate. If the floating gate has extra electrons (negative charge) then the control gate must be raised to a higher voltage to make the FET conduct.</p>\n<p>So a regular FET is conductive (on) when the control gate is high and is non-conductive (off) when the control gate is low. A floating gate FET, however, is only non-conductive (off) when the floating gate is charged and the gate is low. This gives us an output that is dependent on the floating gate and a way to read it (the gate).</p>\n<table>\n<colgroup>\n <col /> <col /> <col />\n</colgroup>\n<tbody>\n <tr>\n  <td>\n  <p><strong>Floating gate charge</strong></p>\n   </td>\n  <td>\n  <p><strong>Control gate</strong></p>\n   </td>\n  <td>\n  <p><strong>Source/drain channel</strong></p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p>Neutral(unprogrammed)</p>\n   </td>\n  <td>\n  <p>High</p>\n   </td>\n  <td>\n  <p>On (1)</p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p>Neutral(unprogrammed)</p>\n   </td>\n  <td>\n  <p>Low</p>\n   </td>\n  <td>\n  <p>On (1)</p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p>Charged(programmed)</p>\n   </td>\n  <td>\n  <p>High</p>\n   </td>\n  <td>\n  <p>On (1)</p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p>Charged(programmed)</p>\n   </td>\n  <td>\n  <p>Low</p>\n   </td>\n  <td>\n  <p>Off (0)</p>\n   </td>\n </tr>\n</tbody>\n</table>\n<p><br />\n&nbsp;</p>\n<p>The tunneling oxide is insulating at low voltages but allows quantum tunneling (Fowler-Nordheim tunneling) at higher voltages. This FN-tunneling provides a mechanism to inject or remove charge from the floating gate by applying high voltages to the control gate or the body.</p>\n<p><img alt=\"\" src=\"/sites/yaffs.net/files/images/fn-tunnelling.gif\" /></p>\n<p>By applying a high positive voltage to the control gate, electrons are drawn into the floating gate, resulting in a programmed gate. Erasing is accomplished by the reverse operation which draws electrons out of the gate.</p>\n<p>So a floating gate FET is effectively a readable, programmable switch. In other words: memory!</p>\n<h3>2.2 NAND array layout</h3>\n<p>NAND flash gets its name from the way that the cells are arranged. NAND cells are arranged in chains called <em><strong>strings</strong></em>, typically 1 string per bit-position in the page n(for SLC). The length of the chain is the same as the number of pages per block. This arrangement uses far less silicon area than the NOR flash arrangement which reduces NAND cost and increases density. It does however also introduce some operational and reliability problems.</p>\n<p><img alt=\"\" src=\"/sites/yaffs.net/files/images/nand-page-select.gif\" /></p>\n<p>NAND is read by biasing the unselected pages with a high bias voltage and the selected pages with the low bias voltage. This means that the unselected cells are always on and the selected cells will be on or off according to the state of the floating gate.</p>\n<p>This means we have a matrix where:</p>\n<ul>\n<li>\n<p>All unselected cells are on.</p>\n </li>\n<li>\n<p>Selected unprogrammed cells are on</p>\n </li>\n<li>\n<p>Selected programmed cells are off.</p>\n </li>\n</ul>\n<p>Since only one cell in a string is selected at a time, the whole string is on if the selected cell is unprogrammed and is off if the selected cell is programmed. Thus, even though the cells in a string are all in series we can still access them individually.</p>\n<p>Well, that\'s how it would work in a perfect world anyway!</p>\n<p>The string and block arrangement means that it takes quite a while ( typically a few µsec) for the voltage of the string to stabilize after the selection has been made. This stabilization time is the cause of the “access time” delay when accessing NAND flash.</p>\n<h3>3 Fault Modes</h3>\n<p>Sit back for a moment and consider everything that must come together for the NAND flash to work and all the ways things can go wrong:</p>\n<ul>\n<li>\n<p>Of course there can be fabrication faults where defects cause short circuits and open circuits within the chip. These types of fault apply to all chips type, not just flash.</p>\n </li>\n<li>\n<p>Each cell has two oxide layers trapping the floating gate charge, one of which is semi-permeable to support tunneling. If either of these layers is too thick, the gate will be unresponsive. If they are too thin then the gate will tunnel too easily or will leak. If there are impurities in the oxide then the layers may become resistive and “leak”, thus causing the charge to change and possibly causing the state to change.</p>\n </li>\n<li>\n<p>The floating gate state can change by either gaining or losing charge. If charge is lost, then a programmed cell may become unprogrammed (a 0 changes to a 1). If charge is gained, then an unprogrammed cell can become programmed.</p>\n </li>\n<li>\n<p>In very extreme cases, a programmed cell can gain further negative charge and become over-programmed. This means that even if the high read bias voltage is applied to the control gate the FET does not become conductive. In this state, a cell will read as programmed (0) even if it is not selected. This means that the whole string will always read zero irrespective of which page is selected. This fault mode will persist until the cell is erased.</p>\n </li>\n<li>\n<p>These devices are made very cheaply. Flash parts with tens of billions of NAND cells cost only a few dollars. There is little money to spend on individual part testing.</p>\n </li>\n</ul>\n<p>Extending the previous state/selection table with the over-programmed fault state, we now have:</p>\n<table>\n<colgroup>\n <col /> <col /> <col />\n</colgroup>\n<tbody>\n <tr>\n  <td>\n  <p><strong>Floating gate charge</strong></p>\n   </td>\n  <td>\n  <p><strong>Control gate</strong></p>\n   </td>\n  <td>\n  <p><strong>Source/drain channel</strong></p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p>Neutral(unprogrammed)</p>\n   </td>\n  <td>\n  <p>High</p>\n   </td>\n  <td>\n  <p>On (1)</p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p>Neutral(unprogrammed)</p>\n   </td>\n  <td>\n  <p>Low</p>\n   </td>\n  <td>\n  <p>On (1)</p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p>Charged(programmed)</p>\n   </td>\n  <td>\n  <p>High</p>\n   </td>\n  <td>\n  <p>On (1)</p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p>Charged(programmed)</p>\n   </td>\n  <td>\n  <p>Low</p>\n   </td>\n  <td>\n  <p>Off(0)</p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p>Over-charged(over-programmed)</p>\n   </td>\n  <td>\n  <p>High</p>\n   </td>\n  <td>\n  <p>Off(0)</p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p>Over-charged(over-programmed)</p>\n   </td>\n  <td>\n  <p>Low</p>\n   </td>\n  <td>\n  <p>Off(0)</p>\n   </td>\n </tr>\n</tbody>\n</table>\n<h2>4 Fault Mechanisms</h2>\n<p>This section explains some of the common NAND flash failure modes.</p>\n<h3>4.1 General chip fault</h3>\n<p>A NAND is a chip built with normal fabrication techniques and is thus prone to fail just like any other chip. Some of these faults can be isolated by marking faulty blocks. In some cases (eg. Damaged inter-block logic) the whole chip is discarded.</p>\n<p>Yaffs does not use the bad blocks, so they have no negative impact on the performance of the file system 9apart from a small reduction in the amount of storage available).</p>\n<h3>4.2 Oxide degradation</h3>\n<p>Every programming/erasure cycle causes some degradation of the oxide layers. Over many cycles this has a tendency to degrade the properties of the oxide layer. Excessive degradation can cause the cell to fail to erase or program, but more commonly just makes the other fault modes more prevalent.</p>\n<p>The primary mechanism of oxide degradation is that charge becomes permanently trapped within the oxide layer in a way that it is not cleared by programming and erasure. The resulting field disrupts both the FET\'s conductive channel and the effectiveness of the F-N tunneling.</p>\n<p>As a result of this field disruption, two things happen:</p>\n<ul>\n<li>\n<p>The FN tunneling is disrupted which means that the programming and erasure take longer to complete. Eventually programming and erasure might fail (see Program/erase failure below).</p>\n </li>\n<li>\n<p>The programming and erasure is far more marginal meaning that less leakage is required to corrupt a bit value (see Charge leakage below).</p>\n </li>\n</ul>\n<p>This degradation is permanent and incremental and is not cleared by erasure. This degradation is the cause of the endurance term in the NAND specification. Typical NAND flash endurance is 10,000 (MLC) to 100,000(SLC) program/erasure cycles.</p>\n<p>Endurance issues are largely minimized by wear leveling and write-path caching.</p>\n<p>Blocks that become too unreliable are retired from use.</p>\n<h3>4.3 Program/erase failure</h3>\n<p>Programming and erase operations are controlled by a built-in state machine that applies the programming/erasure voltages for a while then check whether the operation has succeeded. This is typically performed by an iterative algorithm that will time out if too many cycles are required.</p>\n<p>A failure is signaled in the chip status register when the built-in programming/erasure mechanisms fail to accomplish the programming or erasure within the maximum program/erasure time.</p>\n<p>It is important to realize that a programming failure is only checked on bits being set to a zero. If one bits are inadvertently set to zero then these are not raised as programming errors but are considered to be program disturb errors.</p>\n<p>Program/erase errors are generally the result of excessive oxide degradation.</p>\n<p>Yaffs handles programming/erasure errors as unrecoverable “hard errors”. If these are encountered then useful data is copied off the block and the whole block is permanently retired by marking the block as a bad block.</p>\n<p>These are the only failures that the NAND devices will actually identify. All other failures need to be detected in software.</p>\n<h3>4.4 Charge leakage</h3>\n<p>The oxide isolating the floating gate is not a perfect insulator and charge can escape very slowly, particularly at temperature extremes and when the oxide had been degraded by extensive use. High radiation environments can also make this worse.</p>\n<p>An effective way to handle charge leakage is to use ECC to detect and correct errors. Blocks with errors are rewritten on a fresh block allowing the data to be recreated before unrecoverable errors occur.</p>\n<h3>4.5 Program disturb</h3>\n<p>Program disturb happens when a bit is unintentionally programmed (1 to 0) during a programming operation. The affected bit can be in the same page or elsewhere in the block.</p>\n<p>Program disturb is caused by bias conditions in the flash block during programming. Even though full programming voltage is only applied to the cells being programmed, the other cells are also subject to lesser voltages and minor tunneling can occur. This effect is far less than regular programming but is more than read disturb. However, since a page is only programmed once before the block is erased, there is no multiplier effect as there is in read disturb.</p>\n<p>This condition is made worse by random programming in the block and by applying multiple partial writes to the pages.</p>\n<p>Yaffs1 only writes pages in a block in sequential order and writes pages only once, except for writing deletion markers.</p>\n<p>Yaffs2 does not write deletion markers and thus only programs pages sequentially and only once.</p>\n<p>Thus, Yaffs2 is far less likely to cause write disturb. Yaffs1 should only be used with devices that are tolerant of partial page programming.</p>\n<p>Program disturb within the same page can be corrected by verifying the page after programming.</p>\n<p>ECC provides a mechanism to correct infrequent program disturb errors.</p>\n<h3>4.6 Read disturb</h3>\n<p>Whenever a page is read, the other pages in the block are biased at a read-inhibit voltage to turn them on. While this voltage is not as high as the programming voltage, some very slight F-N tunneling can occur. With sufficient leakage the cell state may change, or the cell may become over-programmed. This effect is known as read disturb.</p>\n<p>Read disturb only impacts the pages in the block that are <em><strong>not</strong></em> <strong></strong>being read. This makes it difficult to detect in some systems. For example, consider a block where only the first page is read repeatedly. Other pages in the block may be incurring read disturb but these are happening without the effect being noticed by software. By the time the pages are eventually read, the read disturb may have caused more bit errors than the ECC is able to fix.</p>\n<p>Thankfully the problem is seldom that bad. Read disturb is very gradual. Under worst case conditions read disturb effects are expected to happen only after approximately 1 million page reads on the block for SLC flash or 100,000 page reads on the block for most MLC flash (or in other words, 10 times the endurance number).</p>\n<p>Be warned though that as process sizes shrink, read disturb is getting more problematic. Some flash parts are prone to read disturb after 20,000 page reads.</p>\n<p>The read disturb effect for a single read is far less than the write disturb effect for a single write. However, each page is only written once per block erase cycle but may be read many times. Therefore the cumulated effect of many read disturbs can cause problems.</p>\n<p>Read disturb effects are cleared by erasing the block.</p>\n<p>Various mechanisms are being implemented to correct read disturb in Yaffs, though these have not yet been implemented.</p>\n<p>The first mechanism is to count the number of page reads on each block. When a certain threshold is reached (say 50,000 reads for an MLC part), the block is rewritten and the count is zeroed.</p>\n<p>The second mechanism is to periodically read pages in the block. eg. Every 256 times a block has a page read we read an additional page to check for read disturb. If read disturb has happened then copy onto a fresh page.</p>\n<p>In addition, ECC does provide some benefit, but is insufficient on its own.</p>\n<h2>5 Decoding NAND reliability statistics</h2>\n<p>Many variables contribute to NAND reliability. These variables are inter-related in complex ways which mean that is is very difficult to try to isolate the variables from each other to fully characterize them. The major variables are:</p>\n<table>\n<colgroup>\n <col /> <col />\n</colgroup>\n<tbody>\n <tr>\n  <td>\n  <p>Temperature</p>\n   </td>\n  <td>\n  <p>Temperature impacts the performance of the materials and thus impacts the movement of charge within the NAND cells.</p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p>Storage time</p>\n   </td>\n  <td>\n  <p>This is related to the cell leakage. The leakage integrates over time so the longer the cells are stored, the more it changes.</p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p>Manufacturing variance</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p>Operating voltage</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p>Erasure/programming cycles</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p>Read cycles</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n </tr>\n</tbody>\n</table>\n<h2>6 MLC vs SLC</h2>\n<p>Both multi-level cell (MLC) and single-level cell (SLC) NAND cells work by trapping charge in the floating gate. By trapping different amounts of charge in the gate it is possible to modify the conductance of the string. MLC store two bits in once cell by using three threshold voltages to distinguish different cell charge levels<a href=\"#sdfootnote1sym\">1</a>.</p>\n<p><img alt=\"\" src=\"/sites/yaffs.net/files/images/nand-mlc-vs-slc-cell-voltages.gif\" /></p>\n<p>In the case of SLC, the cells are erased by the erasure state machine until the cell voltage is below V erase. Programming is accomplished by programming until the voltage exceeds Vprog. On reading, the voltage is compared with Vread.</p>\n<p>MLC programming is accomplished in the same way, except that there are multiple Vprogs and Vreads. This means that there is far less margin for error and cell disturbance is far more likely to cause state changes.</p>\n<p>For this reason, MLC is less reliable, has lower endurance numbers and lower read-disturb numbers. MLC thus requires far better ECC strategies to ensure reliable storage.</p>\n<p>But MLC is cheaper!</p>\n<h2>7 Summary</h2>\n<p>In summary, NAND flash has many failure modes but these can be corrected in software to provide a reliable storage solution. Any flash storage mechanisms that do not provide sufficient coverage of different fault modes should be considered suspect.</p>\n<table>\n<colgroup>\n <col /> <col /> <col /> <col /> <col /> <col /> <col />\n</colgroup>\n<tbody>\n <tr>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p><strong>Chip Fault</strong></p>\n   </td>\n  <td>\n  <p><strong>Degradation</strong></p>\n   </td>\n  <td>\n  <p><strong>P/E failure</strong></p>\n   </td>\n  <td>\n  <p><strong>Leakage</strong></p>\n   </td>\n  <td>\n  <p><strong>Write Disturb</strong></p>\n   </td>\n  <td>\n  <p><strong>Read Disturb</strong></p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p><strong>NAND self check</strong></p>\n   </td>\n  <td>\n  <p>Yes</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>Yes</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p><strong>Block retirement</strong></p>\n   </td>\n  <td>\n  <p>Yes</p>\n   </td>\n  <td>\n  <p>Yes</p>\n   </td>\n  <td>\n  <p>Yes</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p><strong>Wear levelling</strong></p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>Yes</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p><strong>Write Verification</strong></p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>Yes</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p><strong>Read counting/ re-write</strong></p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>Future</p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p><strong>Infrequent read checking</strong></p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>Future</p>\n   </td>\n  <td>\n  <p>Future</p>\n   </td>\n  <td>\n  <p>Future</p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p><strong>ECC</strong></p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>Yes</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>Yes</p>\n   </td>\n  <td>\n  <p>Yes</p>\n   </td>\n  <td>\n  <p>Yes</p>\n   </td>\n </tr>\n <tr>\n  <td>\n  <p><strong>Occasional rewrite of oldest data</strong></p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>Yes</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>Yes</p>\n   </td>\n  <td>\n  <p>&nbsp;</p>\n   </td>\n  <td>\n  <p>Yes</p>\n   </td>\n </tr>\n</tbody>\n</table>\n<p>Thus all fault mechanisms are covered by at least two corrective mechanisms (read disturb correcting features are planned).</p>\n<p><a href=\"#sdfootnote1anc\">1</a>Some MLC parts store more than 2 bits per cell, Storing n bits requires 2n levels.</p>\n<p>&nbsp;</p>\n<p>&nbsp;</p>\n</div>\n      \";}s:9:\"#attached\";a:0:{}s:6:\"#cache\";a:3:{s:8:\"contexts\";a:4:{i:0;s:28:\"languages:language_interface\";i:1;s:5:\"theme\";i:2;s:17:\"url.path.is_front\";i:3;s:16:\"user.permissions\";}s:4:\"tags\";a:4:{i:0;s:30:\"config:filter.format.full_html\";i:1;s:7:\"file:83\";i:2;s:8:\"node:455\";i:3;s:9:\"node_view\";}s:7:\"max-age\";i:-1;}}',-1,1505425928.743,1,'config:filter.format.full_html file:83 node:455 node_view rendered','304'),('entity_view:node:455:search_result:[languages:language_interface]=en:[theme]=yaffs:[user.permissions]=aa7fc4c8fb40c7a8665ccd12fea07926dff0f59b9ee3346bc513c6399bee5b01','a:2:{s:15:\"#cache_redirect\";b:1;s:6:\"#cache\";a:5:{s:4:\"keys\";a:4:{i:0;s:11:\"entity_view\";i:1;s:4:\"node\";i:2;s:3:\"455\";i:3;s:13:\"search_result\";}s:8:\"contexts\";a:4:{i:0;s:28:\"languages:language_interface\";i:1;s:5:\"theme\";i:2;s:17:\"url.path.is_front\";i:3;s:16:\"user.permissions\";}s:4:\"tags\";a:4:{i:0;s:30:\"config:filter.format.full_html\";i:1;s:7:\"file:83\";i:2;s:8:\"node:455\";i:3;s:9:\"node_view\";}s:7:\"max-age\";i:-1;s:3:\"bin\";s:6:\"render\";}}',-1,1505425928.727,1,'config:filter.format.full_html file:83 node:455 node_view rendered','304'),('entity_view:node:455:teaser:[languages:language_interface]=en:[theme]=yaffs:[timezone]=Europe/London:[url.path.is_front]=is_front.0:[user.permissions]=aa7fc4c8fb40c7a8665ccd12fea07926dff0f59b9ee3346bc513c6399bee5b01','a:3:{s:7:\"#markup\";O:25:\"Drupal\\Core\\Render\\Markup\":1:{s:9:\"\0*\0string\";s:1713:\"<article role=\"article\" about=\"/documents/yaffs-nand-flash-failure-mitigation\" class=\"paper is-promoted teaser clearfix\">\n\n  \n      <h2>\n      <a href=\"/documents/yaffs-nand-flash-failure-mitigation\" rel=\"bookmark\"><span>Yaffs NAND flash failure mitigation</span>\n</a>\n    </h2>\n    \n\n      <footer>\n      \n      <div class=\"author\">\n        Submitted by <span><span lang=\"\" about=\"/user/admin\" typeof=\"schema:Person\" property=\"schema:name\" datatype=\"\">Admin</span></span>\n on <span>23 July, 2012 - 1:29am</span>\n        \n      </div>\n    </footer>\n  \n  <div class=\"content\">\n    <ul class=\"links inline list-inline\"><li class=\"node-readmore\"><a href=\"/documents/yaffs-nand-flash-failure-mitigation\" rel=\"tag\" title=\"Yaffs NAND flash failure mitigation\" hreflang=\"und\">Read more<span class=\"visually-hidden\"> about Yaffs NAND flash failure mitigation</span></a></li></ul>\n            <div class=\"field field--name-field-teaser-image field--type-image field--label-hidden field--item\">  <a href=\"/documents/yaffs-nand-flash-failure-mitigation\"><img src=\"/sites/default/files/styles/pdf_image/public/styles/pdf_image/public/downloads/YaffsNandFailureMitigation.pdf.png?itok=OohOxWup\" alt=\"Preview of YaffsNandFailureMitigation.pdf\" typeof=\"foaf:Image\" class=\"img-responsive\" />\n\n</a>\n</div>\n      \n            <div class=\"field field--name-body field--type-text-with-summary field--label-hidden field--item\">NAND flash is one of very few types of electronic device which are knowingly shipped with errors and are expected to generate further errors without causing system failure. This document describes the most important failure modes and how they may be addressed in software.</div>\n      \n  </div>\n\n</article>\n\";}s:9:\"#attached\";a:0:{}s:6:\"#cache\";a:3:{s:8:\"contexts\";a:5:{i:0;s:28:\"languages:language_interface\";i:1;s:5:\"theme\";i:2;s:8:\"timezone\";i:3;s:17:\"url.path.is_front\";i:4;s:16:\"user.permissions\";}s:4:\"tags\";a:6:{i:0;s:30:\"config:filter.format.full_html\";i:1;s:28:\"config:image.style.pdf_image\";i:2;s:7:\"file:84\";i:3;s:8:\"node:455\";i:4;s:9:\"node_view\";i:5;s:6:\"user:1\";}s:7:\"max-age\";i:-1;}}',-1,1504640549.347,1,'config:filter.format.full_html config:image.style.pdf_image file:84 node:455 node_view rendered user:1','323'),('entity_view:node:455:teaser:[languages:language_interface]=en:[theme]=yaffs:[user.permissions]=aa7fc4c8fb40c7a8665ccd12fea07926dff0f59b9ee3346bc513c6399bee5b01','a:2:{s:15:\"#cache_redirect\";b:1;s:6:\"#cache\";a:5:{s:4:\"keys\";a:4:{i:0;s:11:\"entity_view\";i:1;s:4:\"node\";i:2;s:3:\"455\";i:3;s:6:\"teaser\";}s:8:\"contexts\";a:5:{i:0;s:28:\"languages:language_interface\";i:1;s:5:\"theme\";i:2;s:8:\"timezone\";i:3;s:17:\"url.path.is_front\";i:4;s:16:\"user.permissions\";}s:4:\"tags\";a:6:{i:0;s:30:\"config:filter.format.full_html\";i:1;s:28:\"config:image.style.pdf_image\";i:2;s:7:\"file:84\";i:3;s:8:\"node:455\";i:4;s:9:\"node_view\";i:5;s:6:\"user:1\";}s:7:\"max-age\";i:-1;s:3:\"bin\";s:6:\"render\";}}',-1,1504640549.345,1,'config:filter.format.full_html config:image.style.pdf_image file:84 node:455 node_view rendered user:1','323'),('entity_view:node:456:full:[languages:language_interface]=en:[theme]=yaffs:[timezone]=Europe/London:[url.path.is_front]=is_front.0:[user.permissions]=aa7fc4c8fb40c7a8665ccd12fea07926dff0f59b9ee3346bc513c6399bee5b0Fldme3bRR_bw67lfQijEUORadGtKaKpl5-y_rxUv9es','a:5:{s:7:\"#markup\";O:25:\"Drupal\\Core\\Render\\Markup\":1:{s:9:\"\0*\0string\";s:485:\"<article role=\"article\" about=\"/yaffs-structure-diagram\" class=\"image full clearfix\">\n\n  \n    \n\n  \n  <div class=\"content\">\n    \n            <div class=\"field field--name-body field--type-text-with-summary field--label-hidden field--item\"><p>This diagram shows the relationships between the Yaffs filesystem, the <a href=\"/documents/yaffs-direct-interface\">Yaffs Direct Interface</a>, Posix, the operating system and the flash hardware.</p>\n\n<p> </p></div>\n      \n  </div>\n\n</article>\n\";}s:9:\"#attached\";a:1:{s:14:\"html_head_link\";a:3:{i:0;a:2:{i:0;a:2:{s:3:\"rel\";s:9:\"canonical\";s:4:\"href\";s:24:\"/yaffs-structure-diagram\";}i:1;b:1;}i:1;a:2:{i:0;a:2:{s:3:\"rel\";s:9:\"shortlink\";s:4:\"href\";s:9:\"/node/456\";}i:1;b:1;}i:2;a:2:{i:0;a:2:{s:3:\"rel\";s:8:\"revision\";s:4:\"href\";s:24:\"/yaffs-structure-diagram\";}i:1;b:1;}}}s:6:\"#cache\";a:3:{s:8:\"contexts\";a:7:{i:0;s:28:\"languages:language_interface\";i:1;s:5:\"theme\";i:2;s:8:\"timezone\";i:3;s:17:\"url.path.is_front\";i:4;s:16:\"user.permissions\";i:5;s:20:\"user.roles:anonymous\";i:6;s:24:\"user.roles:authenticated\";}s:4:\"tags\";a:5:{i:0;s:31:\"config:filter.format.basic_html\";i:1;s:18:\"config:system.site\";i:2;s:8:\"node:456\";i:3;s:9:\"node_view\";i:4;s:6:\"user:1\";}s:7:\"max-age\";i:-1;}s:17:\"#cache_properties\";a:1:{i:0;s:6:\"#title\";}s:6:\"#title\";O:25:\"Drupal\\Core\\Render\\Markup\":1:{s:9:\"\0*\0string\";s:37:\"<span>Yaffs structure diagram</span>\n\";}}',-1,1505078159.045,1,'config:filter.format.basic_html config:system.site node:456 node_view rendered user:1','279'),('entity_view:node:456:full:[languages:language_interface]=en:[theme]=yaffs:[user.permissions]=aa7fc4c8fb40c7a8665ccd12fea07926dff0f59b9ee3346bc513c6399bee5b01:[user.roles:anonymous]=0','a:2:{s:15:\"#cache_redirect\";b:1;s:6:\"#cache\";a:5:{s:4:\"keys\";a:4:{i:0;s:11:\"entity_view\";i:1;s:4:\"node\";i:2;s:3:\"456\";i:3;s:4:\"full\";}s:8:\"contexts\";a:7:{i:0;s:28:\"languages:language_interface\";i:1;s:5:\"theme\";i:2;s:8:\"timezone\";i:3;s:17:\"url.path.is_front\";i:4;s:16:\"user.permissions\";i:5;s:20:\"user.roles:anonymous\";i:6;s:24:\"user.roles:authenticated\";}s:4:\"tags\";a:5:{i:0;s:31:\"config:filter.format.basic_html\";i:1;s:18:\"config:system.site\";i:2;s:8:\"node:456\";i:3;s:9:\"node_view\";i:4;s:6:\"user:1\";}s:7:\"max-age\";i:-1;s:3:\"bin\";s:6:\"render\";}}',-1,1505078159.039,1,'config:filter.format.basic_html config:system.site node:456 node_view rendered user:1','279'),('entity_view:node:456:search_result:[languages:language_interface]=en:[theme]=yaffs:[url.path.is_front]=is_front.0:[user.permissions]=aa7fc4c8fb40c7a8665ccd12fea07926dff0f59b9ee3346bc513c6399bee5b01','a:3:{s:7:\"#markup\";O:25:\"Drupal\\Core\\Render\\Markup\":1:{s:9:\"\0*\0string\";s:373:\"<span>Yaffs structure diagram</span>\n\n            <div class=\"field field--name-body field--type-text-with-summary field--label-hidden field--item\"><p>This diagram shows the relationships between the Yaffs filesystem, the <a href=\"/documents/yaffs-direct-interface\">Yaffs Direct Interface</a>, Posix, the operating system and the flash hardware.</p>\n\n<p> </p></div>\n      \";}s:9:\"#attached\";a:0:{}s:6:\"#cache\";a:3:{s:8:\"contexts\";a:4:{i:0;s:28:\"languages:language_interface\";i:1;s:5:\"theme\";i:2;s:17:\"url.path.is_front\";i:3;s:16:\"user.permissions\";}s:4:\"tags\";a:3:{i:0;s:31:\"config:filter.format.basic_html\";i:1;s:8:\"node:456\";i:2;s:9:\"node_view\";}s:7:\"max-age\";i:-1;}}',-1,1505188402.829,1,'config:filter.format.basic_html node:456 node_view rendered','266'),('entity_view:node:456:search_result:[languages:language_interface]=en:[theme]=yaffs:[user.permissions]=aa7fc4c8fb40c7a8665ccd12fea07926dff0f59b9ee3346bc513c6399bee5b01','a:2:{s:15:\"#cache_redirect\";b:1;s:6:\"#cache\";a:5:{s:4:\"keys\";a:4:{i:0;s:11:\"entity_view\";i:1;s:4:\"node\";i:2;s:3:\"456\";i:3;s:13:\"search_result\";}s:8:\"contexts\";a:4:{i:0;s:28:\"languages:language_interface\";i:1;s:5:\"theme\";i:2;s:17:\"url.path.is_front\";i:3;s:16:\"user.permissions\";}s:4:\"tags\";a:3:{i:0;s:31:\"config:filter.format.basic_html\";i:1;s:8:\"node:456\";i:2;s:9:\"node_view\";}s:7:\"max-age\";i:-1;s:3:\"bin\";s:6:\"render\";}}',-1,1505188402.827,1,'config:filter.format.basic_html node:456 node_view rendered','266'),('entity_view:node:457:full:[languages:language_interface]=en:[theme]=yaffs:[timezone]=Europe/London:[url.path.is_front]=is_front.0:[user.permissions]=aa7fc4c8fb40c7a8665ccd12fea07926dff0f59b9ee3346bc513c6399bee5b0Mm5LjBolex4CcWqHJdjvtz7NC0OUPnP_B15LwRFuLXQ','a:5:{s:7:\"#markup\";O:25:\"Drupal\\Core\\Render\\Markup\":1:{s:9:\"\0*\0string\";s:902:\"<article role=\"article\" about=\"/logos/google-android\" class=\"yaffs-user-logo is-sticky full clearfix\">\n\n  \n    \n\n  \n  <div class=\"content\">\n    \n            <div class=\"field field--name-field-logo-link field--type-link field--label-hidden field--item\"><a href=\"http://www.android.com/\">Google Android</a></div>\n      \n            <div class=\"field field--name-body field--type-text-with-summary field--label-hidden field--item\"><p>Google Android and all the phone manufacturers who use it, use Yaffs as the default filesystem in some versions of Android.</p>\n\n<p>The Android Robot logo is reproduced from work created and <a href=\"http://code.google.com/policies.html\">shared by the Android Open Source Project</a> and used according to terms described in the <a href=\"http://creativecommons.org/licenses/by/2.5/\">Creative Commons 2.5 Attribution License</a>.</p></div>\n      \n  </div>\n\n</article>\n\";}s:9:\"#attached\";a:1:{s:14:\"html_head_link\";a:3:{i:0;a:2:{i:0;a:2:{s:3:\"rel\";s:9:\"canonical\";s:4:\"href\";s:21:\"/logos/google-android\";}i:1;b:1;}i:1;a:2:{i:0;a:2:{s:3:\"rel\";s:9:\"shortlink\";s:4:\"href\";s:9:\"/node/457\";}i:1;b:1;}i:2;a:2:{i:0;a:2:{s:3:\"rel\";s:8:\"revision\";s:4:\"href\";s:21:\"/logos/google-android\";}i:1;b:1;}}}s:6:\"#cache\";a:3:{s:8:\"contexts\";a:7:{i:0;s:28:\"languages:language_interface\";i:1;s:5:\"theme\";i:2;s:8:\"timezone\";i:3;s:17:\"url.path.is_front\";i:4;s:16:\"user.permissions\";i:5;s:20:\"user.roles:anonymous\";i:6;s:24:\"user.roles:authenticated\";}s:4:\"tags\";a:5:{i:0;s:31:\"config:filter.format.basic_html\";i:1;s:18:\"config:system.site\";i:2;s:8:\"node:457\";i:3;s:9:\"node_view\";i:4;s:6:\"user:1\";}s:7:\"max-age\";i:-1;}s:17:\"#cache_properties\";a:1:{i:0;s:6:\"#title\";}s:6:\"#title\";O:25:\"Drupal\\Core\\Render\\Markup\":1:{s:9:\"\0*\0string\";s:28:\"<span>Google Android</span>\n\";}}',-1,1504654906.524,1,'config:filter.format.basic_html config:system.site node:457 node_view rendered user:1','279'),('entity_view:node:457:full:[languages:language_interface]=en:[theme]=yaffs:[user.permissions]=aa7fc4c8fb40c7a8665ccd12fea07926dff0f59b9ee3346bc513c6399bee5b01:[user.roles:anonymous]=0','a:2:{s:15:\"#cache_redirect\";b:1;s:6:\"#cache\";a:5:{s:4:\"keys\";a:4:{i:0;s:11:\"entity_view\";i:1;s:4:\"node\";i:2;s:3:\"457\";i:3;s:4:\"full\";}s:8:\"contexts\";a:7:{i:0;s:28:\"languages:language_interface\";i:1;s:5:\"theme\";i:2;s:8:\"timezone\";i:3;s:17:\"url.path.is_front\";i:4;s:16:\"user.permissions\";i:5;s:20:\"user.roles:anonymous\";i:6;s:24:\"user.roles:authenticated\";}s:4:\"tags\";a:5:{i:0;s:31:\"config:filter.format.basic_html\";i:1;s:18:\"config:system.site\";i:2;s:8:\"node:457\";i:3;s:9:\"node_view\";i:4;s:6:\"user:1\";}s:7:\"max-age\";i:-1;s:3:\"bin\";s:6:\"render\";}}',-1,1504654906.509,1,'config:filter.format.basic_html config:system.site node:457 node_view rendered user:1','279'),('entity_view:node:458:full:[languages:language_interface]=en:[theme]=yaffs:[timezone]=Europe/London:[url.path.is_front]=is_front.0:[user.permissions]=aa7fc4c8fb40c7a8665ccd12fea07926dff0f59b9ee3346bc513c6399bee5b0WVKC7g35D6BcYqn086pPrJ69YdSahwwz7DHjLKQUODY','a:5:{s:7:\"#markup\";O:25:\"Drupal\\Core\\Render\\Markup\":1:{s:9:\"\0*\0string\";s:4278:\"<article role=\"article\" about=\"/videos/preparing-build-linux-yaffs\" class=\"help-video full clearfix\">\n\n  \n    \n\n  \n  <div class=\"content\">\n    \n      <div class=\"field field--name-field-video field--type-video field--label-hidden field--items\">\n              <div class=\"field--item\"><video data-setup=\"{}\" class=\"video-js vjs-default-skin\" preload=\"none\" controls style=\"width:854px;height:480px;\" autoplay  >\n      <source src=\"https://yaffs.net/sites/default/files/videos/preparing-to-compile-linux-with-yaffs2.mp4\"/>\n  </video></div>\n          </div>\n  \n            <div class=\"field field--name-body field--type-text-with-summary field--label-hidden field--item\"><p> </p>\n\n<p>This video covers the preparation needed to include Linux in Yaffs - describing the kernel build-tools needed, how to get the kernel source code and Yaffs source code. It\'s about 175Mb and 6m30 long.</p>\n\n<p><em>Here\'s the script for the video:</em></p>\n\n<p>Hello, today I\'m going to show you the tools you need to compile Yaffs into the Linux kernel. If you\'ve compiled Linux before, then this tutorial is not appropriate for you, and you should skip to the next one.</p>\n\n<p>Yaffs is the most widely used file system which is specialised for Flash memory. It\'s used in millions of devices, both under Linux and other operatings systems. It\'s available under the GNU Public Licence – the GPL – and commercial terms. You can find out more about Yaffs at yaffs.net.</p>\n\n<p>This demo is being run on Intel x86 because the end result is available for you to experiment with under Vagrant and Virtualbox, but with some slight changes we could target another architecture – for instance ARM. If you\'ve never used Vagrant, it provides a way to get a virtual system up and running in a few minutes. You can download the Vagrant box from the Yaffs web site.</p>\n\n<p><em>Login</em></p>\n\n<p>We\'re starting off with a stock Ubunutu Precise 12.04 386 server. We\'re using 386 because it\'s the lowest common demoninator, so the virtualbox will run on any system capable of running Virtualbox, but this works just as well for 64 bit architecture.</p>\n\n<p>Here we are at the command-line of a brand-new installation. The server has been configured for the minimum – it only has ssh, and a couple of othre things required for Vagrant. Of course there\'s no requirement for any of this for Yaffs.</p>\n\n<p>We need git version control to download Yaffs and the kernel source</p>\n\n<p><strong>sudo apt-get install git</strong></p>\n\n<p>We need these tools to build the kernel</p>\n\n<p><strong>sudo apt-get install crash kexec-tools makedumpfile kernel-wedge</strong></p>\n\n<p><strong>sudo apt-get install ncurses-dev libncurses5-dev</strong></p>\n\n<p><strong>sudo apt-get install build-essential fakeroot</strong></p>\n\n<p>And we need this to automate the job of creating a debian kernel package</p>\n\n<p><strong>sudo apt-get install kernel-package</strong></p>\n\n<p>Okay, we have all the tools I\'ll be needing, so I\'m going to go ahead and make a working directory.</p>\n\n<p><strong>mkdir kernel</strong></p>\n\n<p><strong>cd kernel</strong></p>\n\n<p>Of course we\'re going to need Yaffs, so I\'ll go ahead and download that</p>\n\n<p><strong>git clone git://www.aleph1.co.uk/yaffs2</strong></p>\n\n<p>That puts it into the Yaffs directory.</p>\n\n<p><strong>ls</strong></p>\n\n<p>This copy of Yaffs is licensed under the GNU Public Licence – the GPL, so I must make changes available under the GPL too. We also license Yaffs under commercial terms, removing the need to make your code available to others. Check our website for details.</p>\n\n<p>Now I need a copy of the kernel source code. I could have used one directly from kernel.org, but because this demo is running on ubuntu, I\'m going to grab the ubuntu kernel. This has the benefit of including the debian build rules.</p>\n\n<p><strong>git clone git://kernel.ubuntu.com/ubuntu/ubuntu-precise.git source</strong></p>\n\n<p><strong>cd source</strong></p>\n\n<p>Here it is</p>\n\n<p><strong>ls</strong></p>\n\n<p>And that\'s everything necessary to build the kernel with Yaffs. In the next video we\'ll show you how to configure and compile the kernel with Yaffs. More information about Yaffs is available at www.yaffs.net. Thanks for watching.</p></div>\n      \n  </div>\n\n</article>\n\";}s:9:\"#attached\";a:2:{s:14:\"html_head_link\";a:3:{i:0;a:2:{i:0;a:2:{s:3:\"rel\";s:9:\"canonical\";s:4:\"href\";s:35:\"/videos/preparing-build-linux-yaffs\";}i:1;b:1;}i:1;a:2:{i:0;a:2:{s:3:\"rel\";s:9:\"shortlink\";s:4:\"href\";s:9:\"/node/458\";}i:1;b:1;}i:2;a:2:{i:0;a:2:{s:3:\"rel\";s:8:\"revision\";s:4:\"href\";s:35:\"/videos/preparing-build-linux-yaffs\";}i:1;b:1;}}s:7:\"library\";a:1:{i:0;s:15:\"videojs/videojs\";}}s:6:\"#cache\";a:3:{s:8:\"contexts\";a:7:{i:0;s:28:\"languages:language_interface\";i:1;s:5:\"theme\";i:2;s:8:\"timezone\";i:3;s:17:\"url.path.is_front\";i:4;s:16:\"user.permissions\";i:5;s:20:\"user.roles:anonymous\";i:6;s:24:\"user.roles:authenticated\";}s:4:\"tags\";a:5:{i:0;s:31:\"config:filter.format.basic_html\";i:1;s:18:\"config:system.site\";i:2;s:8:\"node:458\";i:3;s:9:\"node_view\";i:4;s:6:\"user:1\";}s:7:\"max-age\";i:-1;}s:17:\"#cache_properties\";a:1:{i:0;s:6:\"#title\";}s:6:\"#title\";O:25:\"Drupal\\Core\\Render\\Markup\":1:{s:9:\"\0*\0string\";s:49:\"<span>Preparing to build Linux with Yaffs</span>\n\";}}',-1,1504684380.267,1,'config:filter.format.basic_html config:system.site node:458 node_view rendered user:1','282'),('entity_view:node:458:full:[languages:language_interface]=en:[theme]=yaffs:[user.permissions]=aa7fc4c8fb40c7a8665ccd12fea07926dff0f59b9ee3346bc513c6399bee5b01:[user.roles:anonymous]=0','a:2:{s:15:\"#cache_redirect\";b:1;s:6:\"#cache\";a:5:{s:4:\"keys\";a:4:{i:0;s:11:\"entity_view\";i:1;s:4:\"node\";i:2;s:3:\"458\";i:3;s:4:\"full\";}s:8:\"contexts\";a:7:{i:0;s:28:\"languages:language_interface\";i:1;s:5:\"theme\";i:2;s:8:\"timezone\";i:3;s:17:\"url.path.is_front\";i:4;s:16:\"user.permissions\";i:5;s:20:\"user.roles:anonymous\";i:6;s:24:\"user.roles:authenticated\";}s:4:\"tags\";a:5:{i:0;s:31:\"config:filter.format.basic_html\";i:1;s:18:\"config:system.site\";i:2;s:8:\"node:458\";i:3;s:9:\"node_view\";i:4;s:6:\"user:1\";}s:7:\"max-age\";i:-1;s:3:\"bin\";s:6:\"render\";}}',-1,1504684380.264,1,'config:filter.format.basic_html config:system.site node:458 node_view rendered user:1','282'),('entity_view:node:458:search_result:[languages:language_interface]=en:[theme]=yaffs:[url.path.is_front]=is_front.0:[user.permissions]=aa7fc4c8fb40c7a8665ccd12fea07926dff0f59b9ee3346bc513c6399bee5b01','a:3:{s:7:\"#markup\";O:25:\"Drupal\\Core\\Render\\Markup\":1:{s:9:\"\0*\0string\";s:4162:\"<span>Preparing to build Linux with Yaffs</span>\n\n      <div class=\"field field--name-field-video field--type-video field--label-hidden field--items\">\n              <div class=\"field--item\"><video data-setup=\"{}\" class=\"video-js vjs-default-skin\" preload=\"none\" controls style=\"width:854px;height:480px;\" autoplay  >\n      <source src=\"https://yaffs.net/sites/default/files/videos/preparing-to-compile-linux-with-yaffs2.mp4\"/>\n  </video></div>\n          </div>\n  \n            <div class=\"field field--name-body field--type-text-with-summary field--label-hidden field--item\"><p> </p>\n\n<p>This video covers the preparation needed to include Linux in Yaffs - describing the kernel build-tools needed, how to get the kernel source code and Yaffs source code. It\'s about 175Mb and 6m30 long.</p>\n\n<p><em>Here\'s the script for the video:</em></p>\n\n<p>Hello, today I\'m going to show you the tools you need to compile Yaffs into the Linux kernel. If you\'ve compiled Linux before, then this tutorial is not appropriate for you, and you should skip to the next one.</p>\n\n<p>Yaffs is the most widely used file system which is specialised for Flash memory. It\'s used in millions of devices, both under Linux and other operatings systems. It\'s available under the GNU Public Licence – the GPL – and commercial terms. You can find out more about Yaffs at yaffs.net.</p>\n\n<p>This demo is being run on Intel x86 because the end result is available for you to experiment with under Vagrant and Virtualbox, but with some slight changes we could target another architecture – for instance ARM. If you\'ve never used Vagrant, it provides a way to get a virtual system up and running in a few minutes. You can download the Vagrant box from the Yaffs web site.</p>\n\n<p><em>Login</em></p>\n\n<p>We\'re starting off with a stock Ubunutu Precise 12.04 386 server. We\'re using 386 because it\'s the lowest common demoninator, so the virtualbox will run on any system capable of running Virtualbox, but this works just as well for 64 bit architecture.</p>\n\n<p>Here we are at the command-line of a brand-new installation. The server has been configured for the minimum – it only has ssh, and a couple of othre things required for Vagrant. Of course there\'s no requirement for any of this for Yaffs.</p>\n\n<p>We need git version control to download Yaffs and the kernel source</p>\n\n<p><strong>sudo apt-get install git</strong></p>\n\n<p>We need these tools to build the kernel</p>\n\n<p><strong>sudo apt-get install crash kexec-tools makedumpfile kernel-wedge</strong></p>\n\n<p><strong>sudo apt-get install ncurses-dev libncurses5-dev</strong></p>\n\n<p><strong>sudo apt-get install build-essential fakeroot</strong></p>\n\n<p>And we need this to automate the job of creating a debian kernel package</p>\n\n<p><strong>sudo apt-get install kernel-package</strong></p>\n\n<p>Okay, we have all the tools I\'ll be needing, so I\'m going to go ahead and make a working directory.</p>\n\n<p><strong>mkdir kernel</strong></p>\n\n<p><strong>cd kernel</strong></p>\n\n<p>Of course we\'re going to need Yaffs, so I\'ll go ahead and download that</p>\n\n<p><strong>git clone git://www.aleph1.co.uk/yaffs2</strong></p>\n\n<p>That puts it into the Yaffs directory.</p>\n\n<p><strong>ls</strong></p>\n\n<p>This copy of Yaffs is licensed under the GNU Public Licence – the GPL, so I must make changes available under the GPL too. We also license Yaffs under commercial terms, removing the need to make your code available to others. Check our website for details.</p>\n\n<p>Now I need a copy of the kernel source code. I could have used one directly from kernel.org, but because this demo is running on ubuntu, I\'m going to grab the ubuntu kernel. This has the benefit of including the debian build rules.</p>\n\n<p><strong>git clone git://kernel.ubuntu.com/ubuntu/ubuntu-precise.git source</strong></p>\n\n<p><strong>cd source</strong></p>\n\n<p>Here it is</p>\n\n<p><strong>ls</strong></p>\n\n<p>And that\'s everything necessary to build the kernel with Yaffs. In the next video we\'ll show you how to configure and compile the kernel with Yaffs. More information about Yaffs is available at www.yaffs.net. Thanks for watching.</p></div>\n      \";}s:9:\"#attached\";a:1:{s:7:\"library\";a:1:{i:0;s:15:\"videojs/videojs\";}}s:6:\"#cache\";a:3:{s:8:\"contexts\";a:4:{i:0;s:28:\"languages:language_interface\";i:1;s:5:\"theme\";i:2;s:17:\"url.path.is_front\";i:3;s:16:\"user.permissions\";}s:4:\"tags\";a:3:{i:0;s:31:\"config:filter.format.basic_html\";i:1;s:8:\"node:458\";i:2;s:9:\"node_view\";}s:7:\"max-age\";i:-1;}}',-1,1506637558.535,1,'config:filter.format.basic_html node:458 node_view rendered','269'),('entity_view:node:458:search_result:[languages:language_interface]=en:[theme]=yaffs:[user.permissions]=aa7fc4c8fb40c7a8665ccd12fea07926dff0f59b9ee3346bc513c6399bee5b01','a:2:{s:15:\"#cache_redirect\";b:1;s:6:\"#cache\";a:5:{s:4:\"keys\";a:4:{i:0;s:11:\"entity_view\";i:1;s:4:\"node\";i:2;s:3:\"458\";i:3;s:13:\"search_result\";}s:8:\"contexts\";a:4:{i:0;s:28:\"languages:language_interface\";i:1;s:5:\"theme\";i:2;s:17:\"url.path.is_front\";i:3;s:16:\"user.permissions\";}s:4:\"tags\";a:3:{i:0;s:31:\"config:filter.format.basic_html\";i:1;s:8:\"node:458\";i:2;s:9:\"node_view\";}s:7:\"max-age\";i:-1;s:3:\"bin\";s:6:\"render\";}}',-1,1506637558.533,1,'config:filter.format.basic_html node:458 node_view rendered','269'),('entity_view:node:459:full:[languages:language_interface]=en:[theme]=yaffs:[timezone]=Europe/London:[url.path.is_front]=is_front.0:[user.permissions]=aa7fc4c8fb40c7a8665ccd12fea07926dff0f59b9ee3346bc513c6399bee5b03lhaJaBki13GSOh_bz0-YdWcpNhlNV8_tPgYV6kXoE0','a:5:{s:7:\"#markup\";O:25:\"Drupal\\Core\\Render\\Markup\":1:{s:9:\"\0*\0string\";s:6521:\"<article role=\"article\" about=\"/videos/building-yaffs-linux\" class=\"help-video full clearfix\">\n\n  \n    \n\n  \n  <div class=\"content\">\n    \n      <div class=\"field field--name-field-video field--type-video field--label-hidden field--items\">\n              <div class=\"field--item\"><video data-setup=\"{}\" class=\"video-js vjs-default-skin\" preload=\"none\" controls style=\"width:854px;height:480px;\" autoplay  >\n      <source src=\"https://yaffs.net/sites/default/files/videos/preparing-to-compile-linux-with-yaffs2_0.mp4\"/>\n  </video></div>\n          </div>\n  \n            <div class=\"field field--name-body field--type-text-with-summary field--label-hidden field--item\">\n<p>&nbsp;</p>\n<p>This video shows you how to compile Yaffs into Linux. It’s just over 10 minutes long, and if you download it, it’s&nbsp;325MB. After watching this video you should be able to include Yaffs in Linux. Once you have Yaffs available you will be able to mount a simulated&nbsp;NAND&nbsp;device, or if you have a Flash device attached, you will be able to use it.&nbsp;The demo was run in a Virtualbox system, and is available as a&nbsp;<a href=\"http://www.yaffs.net/test-yaffs-under-linux-using-virtualbox-and-vagrant\">Vagrant box from our Downloads section</a>&nbsp;with details of how to build and use a simulated&nbsp;NAND&nbsp;device. &nbsp;</p>\n<p><em>The script for the video:</em></p>\n<p>Hello, today I\'m going to show you how to compile Yaffs into the linux kernel.&nbsp;Yaffs is the most widely used file system which is specialised for Flash memory. It\'s used in millions of devices, both under Linux and other operatings systems. It\'s available under the Gnu Public Licence – the GPL – and commercial terms.&nbsp;You can find out more about Yaffs at yaffs.net.</p>\n<p>Today we\'ll be targetting intel x86 but with some slight changes we could target another &nbsp;architecture – for instance ARM.&nbsp;This demo is being run in a Virtualbox machine, and the resulting system is available as a Vagrant box, so you can download the image and test it yourself.&nbsp;If you\'ve never used vagrant, it provides&nbsp; a way to get a virtual system up and running in a few minutes.</p>\n<p><strong>Login</strong></p>\n<p>We\'re starting off with a stock Ubunutu Precise 12.04 386 server. We\'re using 386 because it\'s the lowest common demoninator, so the virtualbox will run on any system capable of running virtualbox, but this works just as well for 64 bit architecture.</p>\n<p>Here we are at the command-line of a brand-new installation.&nbsp;To make a kernel with Yaffs you will need all the usual kernel-build tools for your distribution, the kernel source code, and the Yaffs source code.</p>\n<p>If you skipped the first video, you won\'t have seen how to download Yaffs. Here\'s a brief clip of retrieving a GPL licenced copy of the Yaffs source.</p>\n<p><strong>git clone git://<a href=\"http://www.aleph1.co.uk/yaffs2\">www.aleph1.co.uk/yaffs2</a></strong><br />\n<strong>ls</strong></p>\n<p>We\'re starting off in the directory where I stored the kernel and Yaffs source.<br />\nThe next step isn\'t strictly necessary, but it\'s useful to if you are going to be doing development: I\'m going to make a branch for my changes to the kernel. Of course if you are using subversion, cvs or some other system for version control then you\'ll want to skip this step or replace it</p>\n<p>Let\'s list the branches<br />\n<strong>git branch</strong><br />\nOnly one makes it easy.<br />\n<strong>Git checkout master -b yaffs-demo-x86</strong><br />\nOkay, so we\'ve created a branch.<br />\n<strong>git branch</strong><br />\nAnd the star indicates that we are working in our new branch.<br />\nNow we have the kernel source, but we need to include Yaffs.<br />\nLuckily Yaffs comes with a script which automates the source changes necessary to include it.<br />\n<strong>cd ../yaffs</strong><br />\nIt\'s always a good idea to check the README file. Especially if you are doing this yourself.<br />\n<strong>less readme-linux.txt</strong><br />\nSo the script we use to patch the kernel is<br />\n<strong>./patch-ker.sh c m ~/kernel/source</strong><br />\nThe c tells the script to copy the changes rather than linking them, and the m indicates that we want the multiprocess option because more than one process might be using Yaffs at one time.</p>\n<p>Right, Yaffs has been patched into the kernel.&nbsp;Now we need to configure the kernel build.<br />\nBecause I\'m working on a virtual machine, I don\'t need to worry about different flavours of the kernel configuration. I can just go ahead and edit the default configuration.&nbsp;To avoid a long compile, I\'m going to remove pretty much all of the non-essential drivers, and most of the hardware – remember this is running on a virtual machine.<br />\n<strong>make menuconfig</strong><br />\nTo include Yaffs we need to enable two things.&nbsp;<br />\nThe memory technology device support (MTD) and the caching block device access for MTD.<br />\nThe MTD settings are in the Device drivers section. Usually it will be on. The caching should be on too.&nbsp;Once those are enabled, Yaffs becomes available as an optional file system.<br />\nGo into File systems, Miscellaneous and enable Yaffs.</p>\n<p>Here\'s a look at the various options.</p>\n<p>I\'ve set up Yaffs. Now I\'m going to go ahead and turn off all the things that I don\'t need in this kernel. There are a lot of them, and there\'s no need to watch hundreds of items being unticked.<br />\n...Skipping ahead....<br />\nOnce the config is suitable, we can exit and save.</p>\n<p>Okay, we\'re ready to build the kernel.&nbsp;Just to make sure that everything is fine..</p>\n<p><strong>fakeroot make-kpkg clean</strong></p>\n<p>and let\'s kick the build off</p>\n<p><strong>fakeroot make-kpkg –initrd –append-to-version=yaffs kernel-image</strong></p>\n<p>and now, since this is running on a uniprocessor virtual machine, I\'ll be going for some lunch. But there\'s no need for you to wait...</p>\n<p>So, the build is finished. It took about 1/2 hour. Your mileage will vary.</p>\n<p>We have a Debian package, and I\'m going to go ahead and install that.</p>\n<p><strong>sudo dpkg&nbsp;–install</strong></p>\n<p>We should have our new build in the grub.&nbsp;If we reboot, we’ll have Yaffs available.&nbsp;In the next video we’ll show you how to set up a Yaffs file system.&nbsp;You can download a copy of the virtual machine but you’ll need vagrant to use it. Details are on the&nbsp;site.</p>\n<p>Thanks for&nbsp;watching.</p>\n</div>\n      \n  </div>\n\n</article>\n\";}s:9:\"#attached\";a:2:{s:14:\"html_head_link\";a:3:{i:0;a:2:{i:0;a:2:{s:3:\"rel\";s:9:\"canonical\";s:4:\"href\";s:28:\"/videos/building-yaffs-linux\";}i:1;b:1;}i:1;a:2:{i:0;a:2:{s:3:\"rel\";s:9:\"shortlink\";s:4:\"href\";s:9:\"/node/459\";}i:1;b:1;}i:2;a:2:{i:0;a:2:{s:3:\"rel\";s:8:\"revision\";s:4:\"href\";s:28:\"/videos/building-yaffs-linux\";}i:1;b:1;}}s:7:\"library\";a:1:{i:0;s:15:\"videojs/videojs\";}}s:6:\"#cache\";a:3:{s:8:\"contexts\";a:7:{i:0;s:28:\"languages:language_interface\";i:1;s:5:\"theme\";i:2;s:8:\"timezone\";i:3;s:17:\"url.path.is_front\";i:4;s:16:\"user.permissions\";i:5;s:20:\"user.roles:anonymous\";i:6;s:24:\"user.roles:authenticated\";}s:4:\"tags\";a:5:{i:0;s:30:\"config:filter.format.full_html\";i:1;s:18:\"config:system.site\";i:2;s:8:\"node:459\";i:3;s:9:\"node_view\";i:4;s:6:\"user:1\";}s:7:\"max-age\";i:-1;}s:17:\"#cache_properties\";a:1:{i:0;s:6:\"#title\";}s:6:\"#title\";O:25:\"Drupal\\Core\\Render\\Markup\":1:{s:9:\"\0*\0string\";s:39:\"<span>Building Yaffs into Linux</span>\n\";}}',-1,1504763960.444,1,'config:filter.format.full_html config:system.site node:459 node_view rendered user:1','311'),('entity_view:node:459:full:[languages:language_interface]=en:[theme]=yaffs:[user.permissions]=aa7fc4c8fb40c7a8665ccd12fea07926dff0f59b9ee3346bc513c6399bee5b01:[user.roles:anonymous]=0','a:2:{s:15:\"#cache_redirect\";b:1;s:6:\"#cache\";a:5:{s:4:\"keys\";a:4:{i:0;s:11:\"entity_view\";i:1;s:4:\"node\";i:2;s:3:\"459\";i:3;s:4:\"full\";}s:8:\"contexts\";a:7:{i:0;s:28:\"languages:language_interface\";i:1;s:5:\"theme\";i:2;s:8:\"timezone\";i:3;s:17:\"url.path.is_front\";i:4;s:16:\"user.permissions\";i:5;s:20:\"user.roles:anonymous\";i:6;s:24:\"user.roles:authenticated\";}s:4:\"tags\";a:5:{i:0;s:30:\"config:filter.format.full_html\";i:1;s:18:\"config:system.site\";i:2;s:8:\"node:459\";i:3;s:9:\"node_view\";i:4;s:6:\"user:1\";}s:7:\"max-age\";i:-1;s:3:\"bin\";s:6:\"render\";}}',-1,1504763960.442,1,'config:filter.format.full_html config:system.site node:459 node_view rendered user:1','311'),('entity_view:node:459:search_result:[languages:language_interface]=en:[theme]=yaffs:[url.path.is_front]=is_front.0:[user.permissions]=aa7fc4c8fb40c7a8665ccd12fea07926dff0f59b9ee3346bc513c6399bee5b01','a:3:{s:7:\"#markup\";O:25:\"Drupal\\Core\\Render\\Markup\":1:{s:9:\"\0*\0string\";s:6402:\"<span>Building Yaffs into Linux</span>\n\n      <div class=\"field field--name-field-video field--type-video field--label-hidden field--items\">\n              <div class=\"field--item\"><video data-setup=\"{}\" class=\"video-js vjs-default-skin\" preload=\"none\" controls style=\"width:854px;height:480px;\" autoplay  >\n      <source src=\"https://yaffs.net/sites/default/files/videos/preparing-to-compile-linux-with-yaffs2_0.mp4\"/>\n  </video></div>\n          </div>\n  \n            <div class=\"field field--name-body field--type-text-with-summary field--label-hidden field--item\">\n<p>&nbsp;</p>\n<p>This video shows you how to compile Yaffs into Linux. It’s just over 10 minutes long, and if you download it, it’s&nbsp;325MB. After watching this video you should be able to include Yaffs in Linux. Once you have Yaffs available you will be able to mount a simulated&nbsp;NAND&nbsp;device, or if you have a Flash device attached, you will be able to use it.&nbsp;The demo was run in a Virtualbox system, and is available as a&nbsp;<a href=\"http://www.yaffs.net/test-yaffs-under-linux-using-virtualbox-and-vagrant\">Vagrant box from our Downloads section</a>&nbsp;with details of how to build and use a simulated&nbsp;NAND&nbsp;device. &nbsp;</p>\n<p><em>The script for the video:</em></p>\n<p>Hello, today I\'m going to show you how to compile Yaffs into the linux kernel.&nbsp;Yaffs is the most widely used file system which is specialised for Flash memory. It\'s used in millions of devices, both under Linux and other operatings systems. It\'s available under the Gnu Public Licence – the GPL – and commercial terms.&nbsp;You can find out more about Yaffs at yaffs.net.</p>\n<p>Today we\'ll be targetting intel x86 but with some slight changes we could target another &nbsp;architecture – for instance ARM.&nbsp;This demo is being run in a Virtualbox machine, and the resulting system is available as a Vagrant box, so you can download the image and test it yourself.&nbsp;If you\'ve never used vagrant, it provides&nbsp; a way to get a virtual system up and running in a few minutes.</p>\n<p><strong>Login</strong></p>\n<p>We\'re starting off with a stock Ubunutu Precise 12.04 386 server. We\'re using 386 because it\'s the lowest common demoninator, so the virtualbox will run on any system capable of running virtualbox, but this works just as well for 64 bit architecture.</p>\n<p>Here we are at the command-line of a brand-new installation.&nbsp;To make a kernel with Yaffs you will need all the usual kernel-build tools for your distribution, the kernel source code, and the Yaffs source code.</p>\n<p>If you skipped the first video, you won\'t have seen how to download Yaffs. Here\'s a brief clip of retrieving a GPL licenced copy of the Yaffs source.</p>\n<p><strong>git clone git://<a href=\"http://www.aleph1.co.uk/yaffs2\">www.aleph1.co.uk/yaffs2</a></strong><br />\n<strong>ls</strong></p>\n<p>We\'re starting off in the directory where I stored the kernel and Yaffs source.<br />\nThe next step isn\'t strictly necessary, but it\'s useful to if you are going to be doing development: I\'m going to make a branch for my changes to the kernel. Of course if you are using subversion, cvs or some other system for version control then you\'ll want to skip this step or replace it</p>\n<p>Let\'s list the branches<br />\n<strong>git branch</strong><br />\nOnly one makes it easy.<br />\n<strong>Git checkout master -b yaffs-demo-x86</strong><br />\nOkay, so we\'ve created a branch.<br />\n<strong>git branch</strong><br />\nAnd the star indicates that we are working in our new branch.<br />\nNow we have the kernel source, but we need to include Yaffs.<br />\nLuckily Yaffs comes with a script which automates the source changes necessary to include it.<br />\n<strong>cd ../yaffs</strong><br />\nIt\'s always a good idea to check the README file. Especially if you are doing this yourself.<br />\n<strong>less readme-linux.txt</strong><br />\nSo the script we use to patch the kernel is<br />\n<strong>./patch-ker.sh c m ~/kernel/source</strong><br />\nThe c tells the script to copy the changes rather than linking them, and the m indicates that we want the multiprocess option because more than one process might be using Yaffs at one time.</p>\n<p>Right, Yaffs has been patched into the kernel.&nbsp;Now we need to configure the kernel build.<br />\nBecause I\'m working on a virtual machine, I don\'t need to worry about different flavours of the kernel configuration. I can just go ahead and edit the default configuration.&nbsp;To avoid a long compile, I\'m going to remove pretty much all of the non-essential drivers, and most of the hardware – remember this is running on a virtual machine.<br />\n<strong>make menuconfig</strong><br />\nTo include Yaffs we need to enable two things.&nbsp;<br />\nThe memory technology device support (MTD) and the caching block device access for MTD.<br />\nThe MTD settings are in the Device drivers section. Usually it will be on. The caching should be on too.&nbsp;Once those are enabled, Yaffs becomes available as an optional file system.<br />\nGo into File systems, Miscellaneous and enable Yaffs.</p>\n<p>Here\'s a look at the various options.</p>\n<p>I\'ve set up Yaffs. Now I\'m going to go ahead and turn off all the things that I don\'t need in this kernel. There are a lot of them, and there\'s no need to watch hundreds of items being unticked.<br />\n...Skipping ahead....<br />\nOnce the config is suitable, we can exit and save.</p>\n<p>Okay, we\'re ready to build the kernel.&nbsp;Just to make sure that everything is fine..</p>\n<p><strong>fakeroot make-kpkg clean</strong></p>\n<p>and let\'s kick the build off</p>\n<p><strong>fakeroot make-kpkg –initrd –append-to-version=yaffs kernel-image</strong></p>\n<p>and now, since this is running on a uniprocessor virtual machine, I\'ll be going for some lunch. But there\'s no need for you to wait...</p>\n<p>So, the build is finished. It took about 1/2 hour. Your mileage will vary.</p>\n<p>We have a Debian package, and I\'m going to go ahead and install that.</p>\n<p><strong>sudo dpkg&nbsp;–install</strong></p>\n<p>We should have our new build in the grub.&nbsp;If we reboot, we’ll have Yaffs available.&nbsp;In the next video we’ll show you how to set up a Yaffs file system.&nbsp;You can download a copy of the virtual machine but you’ll need vagrant to use it. Details are on the&nbsp;site.</p>\n<p>Thanks for&nbsp;watching.</p>\n</div>\n      \";}s:9:\"#attached\";a:1:{s:7:\"library\";a:1:{i:0;s:15:\"videojs/videojs\";}}s:6:\"#cache\";a:3:{s:8:\"contexts\";a:4:{i:0;s:28:\"languages:language_interface\";i:1;s:5:\"theme\";i:2;s:17:\"url.path.is_front\";i:3;s:16:\"user.permissions\";}s:4:\"tags\";a:3:{i:0;s:30:\"config:filter.format.full_html\";i:1;s:8:\"node:459\";i:2;s:9:\"node_view\";}s:7:\"max-age\";i:-1;}}',-1,1506307655.168,1,'config:filter.format.full_html node:459 node_view rendered','298'),('entity_view:node:459:search_result:[languages:language_interface]=en:[theme]=yaffs:[user.permissions]=aa7fc4c8fb40c7a8665ccd12fea07926dff0f59b9ee3346bc513c6399bee5b01','a:2:{s:15:\"#cache_redirect\";b:1;s:6:\"#cache\";a:5:{s:4:\"keys\";a:4:{i:0;s:11:\"entity_view\";i:1;s:4:\"node\";i:2;s:3:\"459\";i:3;s:13:\"search_result\";}s:8:\"contexts\";a:4:{i:0;s:28:\"languages:language_interface\";i:1;s:5:\"theme\";i:2;s:17:\"url.path.is_front\";i:3;s:16:\"user.permissions\";}s:4:\"tags\";a:3:{i:0;s:30:\"config:filter.format.full_html\";i:1;s:8:\"node:459\";i:2;s:9:\"node_view\";}s:7:\"max-age\";i:-1;s:3:\"bin\";s:6:\"render\";}}',-1,1506307655.165,1,'config:filter.format.full_html node:459 node_view rendered','298'),('entity_view:node:460:full:[languages:language_interface]=en:[theme]=yaffs:[timezone]=Europe/London:[url.path.is_front]=is_front.0:[user.permissions]=aa7fc4c8fb40c7a8665ccd12fea07926dff0f59b9ee3346bc513c6399bee5b0JY5_in7NNIQS6y9vapQI1TCrqi7HEfUrieiQ-tJHeCg','a:5:{s:7:\"#markup\";O:25:\"Drupal\\Core\\Render\\Markup\":1:{s:9:\"\0*\0string\";s:828:\"<article role=\"article\" about=\"/logos/leica-geosystems\" class=\"yaffs-user-logo full clearfix\">\n\n  \n    \n\n  \n  <div class=\"content\">\n    \n            <div class=\"field field--name-field-logo-link field--type-link field--label-hidden field--item\"><a href=\"http://www.leica-geosystems.com/\">Leica Geosystems</a></div>\n      \n            <div class=\"field field--name-body field--type-text-with-summary field--label-hidden field--item\"><p>Leica Geosystems products and services are trusted by professionals worldwide to help them capture, analyze, and present spatial information. Leica Geosystems is best known for its broad array of products that capture accurately, model quickly, analyze easily, and visualize and present spatial information.</p>\n\n<p>Leica Geosystems use Yaffs.</p>\n\n<p> </p></div>\n      \n  </div>\n\n</article>\n\";}s:9:\"#attached\";a:1:{s:14:\"html_head_link\";a:3:{i:0;a:2:{i:0;a:2:{s:3:\"rel\";s:9:\"canonical\";s:4:\"href\";s:23:\"/logos/leica-geosystems\";}i:1;b:1;}i:1;a:2:{i:0;a:2:{s:3:\"rel\";s:9:\"shortlink\";s:4:\"href\";s:9:\"/node/460\";}i:1;b:1;}i:2;a:2:{i:0;a:2:{s:3:\"rel\";s:8:\"revision\";s:4:\"href\";s:23:\"/logos/leica-geosystems\";}i:1;b:1;}}}s:6:\"#cache\";a:3:{s:8:\"contexts\";a:7:{i:0;s:28:\"languages:language_interface\";i:1;s:5:\"theme\";i:2;s:8:\"timezone\";i:3;s:17:\"url.path.is_front\";i:4;s:16:\"user.permissions\";i:5;s:20:\"user.roles:anonymous\";i:6;s:24:\"user.roles:authenticated\";}s:4:\"tags\";a:5:{i:0;s:31:\"config:filter.format.basic_html\";i:1;s:18:\"config:system.site\";i:2;s:8:\"node:460\";i:3;s:9:\"node_view\";i:4;s:6:\"user:1\";}s:7:\"max-age\";i:-1;}s:17:\"#cache_properties\";a:1:{i:0;s:6:\"#title\";}s:6:\"#title\";O:25:\"Drupal\\Core\\Render\\Markup\":1:{s:9:\"\0*\0string\";s:30:\"<span>Leica Geosystems</span>\n\";}}',-1,1504648955.462,1,'config:filter.format.basic_html config:system.site node:460 node_view rendered user:1','280'),('entity_view:node:460:full:[languages:language_interface]=en:[theme]=yaffs:[user.permissions]=aa7fc4c8fb40c7a8665ccd12fea07926dff0f59b9ee3346bc513c6399bee5b01:[user.roles:anonymous]=0','a:2:{s:15:\"#cache_redirect\";b:1;s:6:\"#cache\";a:5:{s:4:\"keys\";a:4:{i:0;s:11:\"entity_view\";i:1;s:4:\"node\";i:2;s:3:\"460\";i:3;s:4:\"full\";}s:8:\"contexts\";a:7:{i:0;s:28:\"languages:language_interface\";i:1;s:5:\"theme\";i:2;s:8:\"timezone\";i:3;s:17:\"url.path.is_front\";i:4;s:16:\"user.permissions\";i:5;s:20:\"user.roles:anonymous\";i:6;s:24:\"user.roles:authenticated\";}s:4:\"tags\";a:5:{i:0;s:31:\"config:filter.format.basic_html\";i:1;s:18:\"config:system.site\";i:2;s:8:\"node:460\";i:3;s:9:\"node_view\";i:4;s:6:\"user:1\";}s:7:\"max-age\";i:-1;s:3:\"bin\";s:6:\"render\";}}',-1,1504648955.459,1,'config:filter.format.basic_html config:system.site node:460 node_view rendered user:1','280'),('entity_view:node:462:full:[languages:language_interface]=en:[theme]=yaffs:[timezone]=Europe/London:[url.path.is_front]=is_front.0:[user.permissions]=aa7fc4c8fb40c7a8665ccd12fea07926dff0f59b9ee3346bc513c6399bee5b03-5ybru4Ow2-qn4bHc3n7kFuEtHNZT4G1disZLuuY-s','a:5:{s:7:\"#markup\";O:25:\"Drupal\\Core\\Render\\Markup\":1:{s:9:\"\0*\0string\";s:6232:\"<article role=\"article\" about=\"/licences-more-background-and-detail\" typeof=\"schema:WebPage\" class=\"page full clearfix\">\n\n  \n      <span property=\"schema:name\" content=\"Licences - more background and detail\" class=\"hidden\"></span>\n\n\n  \n  <div class=\"content\">\n    \n            <div property=\"schema:text\" class=\"field field--name-body field--type-text-with-summary field--label-hidden field--item\"><h3>What sorts of licence are there?</h3>\n\n<p>There are two; GNU General Public Licence version 2, and Paid licences.<br />\nAnyone can take our Yaffs file system from http://www.yaffs.net  free of charge; you can work and play with and test the code as much as you like, and make sure it suits your purposes. You will be doing so under the well known GNU GPL, described in detail at http://www.gnu.org/licenses/old-licenses/gpl-2.0.html</p>\n\n<h3>That sounds great! Why should I want a paid licence?</h3>\n\n<p>The GPL obliges you to release all associated code of your own that you use with any GPL software to anyone who asks for it.  If you do not wish to release your own code, then you can buy a Licence from Aleph One Ltd which does not have that obligation.</p>\n\n<h3>What sorts of systems use Yaffs?</h3>\n\n<p>There is a wide range including GPS equipment for surveyors, sewing machines, traffic control equipment, Point-of-Sale tills, Set-Top-Boxes, DVD writers, high-end video-filming equipment and so on and on - including Android telephones!  These have provided a very large test-bed for Yaffs, and of course they use it under GPL since Android is an Open Source project.</p>\n\n<h3>Who uses Yaffs now?</h3>\n\n<p>The Yaffs.net Home page shows (at its foot) the logos of some of the users, but the range is much wider than those displayed there.  They tend to have in common a need for great confidence in the robustness of the FS in demanding circumstances like heavy work, accumulated cell-failures, and random power failures.  A number of them have bought more than one Licence at different times because they know it works!</p>\n\n<h3>What are the terms of the paid licences like?</h3>\n\n<p>All Yaffs licences from Aleph One are non-exclusive, worldwide, perpetual, irrevocable and free of any royalty; they are paid for once when an agreement is signed, and they apply only to the one or more products specified at the time of the agreement.</p>\n\n<h3>What do we do next?</h3>\n\n<p>Tell us some more about the product you will use Yaffs in.  We like the Agreement to contain a brief description of the hardware involved and the part number or product name and any internal code name.  If you want us to sign a Non-Disclosure Agreement before you give us these details, send it to us; we are used to signing them.  We can send you a standard form if you do not have one.<br />\nThen we will send a draft Agreement and price to you, and negotiate until we are both satisfied.  Next we each sign and exchange copies of the Agreement and you pay us.</p>\n\n<h3>How does that help us?</h3>\n\n<p>After you pay for a Licence you get a tarball of files to put in your product which make clear in the file headers that you are using Yaffs under a licence from Aleph One Ltd.  That makes a paid licence different from a GNU General Public Licence.  We can do that because Aleph One Ltd owns Yaffs completely.<br />\nIts other virtues are that it handles different page sizes and large numbers of files, and it is economical on other resources such as RAM.  Like everyone else, Licence Holders have access to the continuing improvements which are being made in Yaffs.</p>\n\n<h3>What about the OS?</h3>\n\n<p>Yaffs is agnostic about the OS it is used with.  While many users combine it with Linux, it has been used with 32-bit and 64-bit OSs and with no OS at all.  Cases such as VxWorks and WinCE are a bit more complex.  We have done work on a wrapper to make it easier to use Yaffs with WinCE.  We are working on making Yaffs easy to use with VxWorks too; let us know if you are interested in the resuults. <br />\nThe relationship between the OS and the rest of Yaffs is illustrated in the diagram on the Home Page.  At the heart of Yaffs is the Yaffs Direct Interface, which is a well-documented sub-set of Yaffs.  Click on it in the diagram for more information.</p>\n\n<h3>How does this relate to the GPL?</h3>\n\n<p>The point of GNU General Public Licence v2 is to share work to improve Open Source software for the common good.  A huge amount of development takes place quietly and out of the public eye, and it is released into the common pool of software so others can both benefit from it and contribute to it.<br />\nOpen Source software is transparent to all who use it, and its development therefore requires sharing your contributions with anyone else who wants them.  The GPL was devised to make this possible.  It also makes perfectly clear that the open source code is supplied AS IS and without any warranty. This shields developers and contributors from litigators who want to blame them for a fault.<br />\nOne user of Yaffs makes seismic monitoring equipment capable of detecting underground nuclear explosions; they require Open Source software.</p>\n\n<h3>How does the LGPL bear on all of this?</h3>\n\n<p>Because Bootloaders are often proprietary we provide with Yaffs a few kBytes of bootloader code which is licensed under LGPL, the GNU Lesser Public Licence, rather than under GPL.  This avoids the risk of what proprietary code owners often describe as contamination of their code by code useful to Yaffs.<br />\nThe LGPL is shown at  http://www.gnu.org/licenses/lgpl.html  The tarball with modified headers you get from us will have your name only in the Yaffs file headers and not in the headers of tools such as the bootloader.  This practice is common in the Open Source world.</p>\n\n<h3>How much does a licence from Aleph One cost?</h3>\n\n<p>The price depends a bit on the sort of market you are working in; a firm making industrial control equipment or office copiers pays a base price, but a mobile phone maker pays more.  The base price is GBP10k. Note that is not US$ but GB Pounds Sterling.</p>\n\n<p><br />\nApril 2015</p>\n\n<p><br /><br /><br /><br /><br />\n </p></div>\n      \n  </div>\n\n</article>\n\";}s:9:\"#attached\";a:1:{s:14:\"html_head_link\";a:3:{i:0;a:2:{i:0;a:2:{s:3:\"rel\";s:9:\"canonical\";s:4:\"href\";s:36:\"/licences-more-background-and-detail\";}i:1;b:1;}i:1;a:2:{i:0;a:2:{s:3:\"rel\";s:9:\"shortlink\";s:4:\"href\";s:9:\"/node/462\";}i:1;b:1;}i:2;a:2:{i:0;a:2:{s:3:\"rel\";s:8:\"revision\";s:4:\"href\";s:36:\"/licences-more-background-and-detail\";}i:1;b:1;}}}s:6:\"#cache\";a:3:{s:8:\"contexts\";a:7:{i:0;s:28:\"languages:language_interface\";i:1;s:5:\"theme\";i:2;s:8:\"timezone\";i:3;s:17:\"url.path.is_front\";i:4;s:16:\"user.permissions\";i:5;s:20:\"user.roles:anonymous\";i:6;s:24:\"user.roles:authenticated\";}s:4:\"tags\";a:5:{i:0;s:31:\"config:filter.format.basic_html\";i:1;s:18:\"config:system.site\";i:2;s:8:\"node:462\";i:3;s:9:\"node_view\";i:4;s:6:\"user:4\";}s:7:\"max-age\";i:-1;}s:17:\"#cache_properties\";a:1:{i:0;s:6:\"#title\";}s:6:\"#title\";O:25:\"Drupal\\Core\\Render\\Markup\":1:{s:9:\"\0*\0string\";s:74:\"<span property=\"schema:name\">Licences - more background and detail</span>\n\";}}',-1,1504700448.123,1,'config:filter.format.basic_html config:system.site node:462 node_view rendered user:4','273'),('entity_view:node:462:full:[languages:language_interface]=en:[theme]=yaffs:[user.permissions]=aa7fc4c8fb40c7a8665ccd12fea07926dff0f59b9ee3346bc513c6399bee5b01:[user.roles:anonymous]=0','a:2:{s:15:\"#cache_redirect\";b:1;s:6:\"#cache\";a:5:{s:4:\"keys\";a:4:{i:0;s:11:\"entity_view\";i:1;s:4:\"node\";i:2;s:3:\"462\";i:3;s:4:\"full\";}s:8:\"contexts\";a:7:{i:0;s:28:\"languages:language_interface\";i:1;s:5:\"theme\";i:2;s:8:\"timezone\";i:3;s:17:\"url.path.is_front\";i:4;s:16:\"user.permissions\";i:5;s:20:\"user.roles:anonymous\";i:6;s:24:\"user.roles:authenticated\";}s:4:\"tags\";a:5:{i:0;s:31:\"config:filter.format.basic_html\";i:1;s:18:\"config:system.site\";i:2;s:8:\"node:462\";i:3;s:9:\"node_view\";i:4;s:6:\"user:4\";}s:7:\"max-age\";i:-1;s:3:\"bin\";s:6:\"render\";}}',-1,1504700448.121,1,'config:filter.format.basic_html config:system.site node:462 node_view rendered user:4','273'),('entity_view:node:462:search_result:[languages:language_interface]=en:[theme]=yaffs:[url.path.is_front]=is_front.0:[user.permissions]=aa7fc4c8fb40c7a8665ccd12fea07926dff0f59b9ee3346bc513c6399bee5b01','a:3:{s:7:\"#markup\";O:25:\"Drupal\\Core\\Render\\Markup\":1:{s:9:\"\0*\0string\";s:6020:\"<span property=\"schema:name\">Licences - more background and detail</span>\n\n            <div property=\"schema:text\" class=\"field field--name-body field--type-text-with-summary field--label-hidden field--item\"><h3>What sorts of licence are there?</h3>\n\n<p>There are two; GNU General Public Licence version 2, and Paid licences.<br />\nAnyone can take our Yaffs file system from http://www.yaffs.net  free of charge; you can work and play with and test the code as much as you like, and make sure it suits your purposes. You will be doing so under the well known GNU GPL, described in detail at http://www.gnu.org/licenses/old-licenses/gpl-2.0.html</p>\n\n<h3>That sounds great! Why should I want a paid licence?</h3>\n\n<p>The GPL obliges you to release all associated code of your own that you use with any GPL software to anyone who asks for it.  If you do not wish to release your own code, then you can buy a Licence from Aleph One Ltd which does not have that obligation.</p>\n\n<h3>What sorts of systems use Yaffs?</h3>\n\n<p>There is a wide range including GPS equipment for surveyors, sewing machines, traffic control equipment, Point-of-Sale tills, Set-Top-Boxes, DVD writers, high-end video-filming equipment and so on and on - including Android telephones!  These have provided a very large test-bed for Yaffs, and of course they use it under GPL since Android is an Open Source project.</p>\n\n<h3>Who uses Yaffs now?</h3>\n\n<p>The Yaffs.net Home page shows (at its foot) the logos of some of the users, but the range is much wider than those displayed there.  They tend to have in common a need for great confidence in the robustness of the FS in demanding circumstances like heavy work, accumulated cell-failures, and random power failures.  A number of them have bought more than one Licence at different times because they know it works!</p>\n\n<h3>What are the terms of the paid licences like?</h3>\n\n<p>All Yaffs licences from Aleph One are non-exclusive, worldwide, perpetual, irrevocable and free of any royalty; they are paid for once when an agreement is signed, and they apply only to the one or more products specified at the time of the agreement.</p>\n\n<h3>What do we do next?</h3>\n\n<p>Tell us some more about the product you will use Yaffs in.  We like the Agreement to contain a brief description of the hardware involved and the part number or product name and any internal code name.  If you want us to sign a Non-Disclosure Agreement before you give us these details, send it to us; we are used to signing them.  We can send you a standard form if you do not have one.<br />\nThen we will send a draft Agreement and price to you, and negotiate until we are both satisfied.  Next we each sign and exchange copies of the Agreement and you pay us.</p>\n\n<h3>How does that help us?</h3>\n\n<p>After you pay for a Licence you get a tarball of files to put in your product which make clear in the file headers that you are using Yaffs under a licence from Aleph One Ltd.  That makes a paid licence different from a GNU General Public Licence.  We can do that because Aleph One Ltd owns Yaffs completely.<br />\nIts other virtues are that it handles different page sizes and large numbers of files, and it is economical on other resources such as RAM.  Like everyone else, Licence Holders have access to the continuing improvements which are being made in Yaffs.</p>\n\n<h3>What about the OS?</h3>\n\n<p>Yaffs is agnostic about the OS it is used with.  While many users combine it with Linux, it has been used with 32-bit and 64-bit OSs and with no OS at all.  Cases such as VxWorks and WinCE are a bit more complex.  We have done work on a wrapper to make it easier to use Yaffs with WinCE.  We are working on making Yaffs easy to use with VxWorks too; let us know if you are interested in the resuults. <br />\nThe relationship between the OS and the rest of Yaffs is illustrated in the diagram on the Home Page.  At the heart of Yaffs is the Yaffs Direct Interface, which is a well-documented sub-set of Yaffs.  Click on it in the diagram for more information.</p>\n\n<h3>How does this relate to the GPL?</h3>\n\n<p>The point of GNU General Public Licence v2 is to share work to improve Open Source software for the common good.  A huge amount of development takes place quietly and out of the public eye, and it is released into the common pool of software so others can both benefit from it and contribute to it.<br />\nOpen Source software is transparent to all who use it, and its development therefore requires sharing your contributions with anyone else who wants them.  The GPL was devised to make this possible.  It also makes perfectly clear that the open source code is supplied AS IS and without any warranty. This shields developers and contributors from litigators who want to blame them for a fault.<br />\nOne user of Yaffs makes seismic monitoring equipment capable of detecting underground nuclear explosions; they require Open Source software.</p>\n\n<h3>How does the LGPL bear on all of this?</h3>\n\n<p>Because Bootloaders are often proprietary we provide with Yaffs a few kBytes of bootloader code which is licensed under LGPL, the GNU Lesser Public Licence, rather than under GPL.  This avoids the risk of what proprietary code owners often describe as contamination of their code by code useful to Yaffs.<br />\nThe LGPL is shown at  http://www.gnu.org/licenses/lgpl.html  The tarball with modified headers you get from us will have your name only in the Yaffs file headers and not in the headers of tools such as the bootloader.  This practice is common in the Open Source world.</p>\n\n<h3>How much does a licence from Aleph One cost?</h3>\n\n<p>The price depends a bit on the sort of market you are working in; a firm making industrial control equipment or office copiers pays a base price, but a mobile phone maker pays more.  The base price is GBP10k. Note that is not US$ but GB Pounds Sterling.</p>\n\n<p><br />\nApril 2015</p>\n\n<p><br /><br /><br /><br /><br />\n </p></div>\n      \";}s:9:\"#attached\";a:0:{}s:6:\"#cache\";a:3:{s:8:\"contexts\";a:4:{i:0;s:28:\"languages:language_interface\";i:1;s:5:\"theme\";i:2;s:17:\"url.path.is_front\";i:3;s:16:\"user.permissions\";}s:4:\"tags\";a:3:{i:0;s:31:\"config:filter.format.basic_html\";i:1;s:8:\"node:462\";i:2;s:9:\"node_view\";}s:7:\"max-age\";i:-1;}}',-1,1505188402.933,1,'config:filter.format.basic_html node:462 node_view rendered','264'),('entity_view:node:462:search_result:[languages:language_interface]=en:[theme]=yaffs:[user.permissions]=aa7fc4c8fb40c7a8665ccd12fea07926dff0f59b9ee3346bc513c6399bee5b01','a:2:{s:15:\"#cache_redirect\";b:1;s:6:\"#cache\";a:5:{s:4:\"keys\";a:4:{i:0;s:11:\"entity_view\";i:1;s:4:\"node\";i:2;s:3:\"462\";i:3;s:13:\"search_result\";}s:8:\"contexts\";a:4:{i:0;s:28:\"languages:language_interface\";i:1;s:5:\"theme\";i:2;s:17:\"url.path.is_front\";i:3;s:16:\"user.permissions\";}s:4:\"tags\";a:3:{i:0;s:31:\"config:filter.format.basic_html\";i:1;s:8:\"node:462\";i:2;s:9:\"node_view\";}s:7:\"max-age\";i:-1;s:3:\"bin\";s:6:\"render\";}}',-1,1505188402.930,1,'config:filter.format.basic_html node:462 node_view rendered','264'),('entity_view:node:466:full:[languages:language_interface]=en:[theme]=yaffs:[timezone]=Europe/London:[url.path.is_front]=is_front.0:[user.permissions]=aa7fc4c8fb40c7a8665ccd12fea07926dff0f59b9ee3346bc513c6399bee5b0sXNxIh-rooWnrmXh3eiBU3SU4OSspL3TrLy53x8e5zg','a:5:{s:7:\"#markup\";O:25:\"Drupal\\Core\\Render\\Markup\":1:{s:9:\"\0*\0string\";s:25287:\"<article role=\"article\" about=\"/documents/considerations-choosing-flash-file-system\" class=\"paper is-promoted full clearfix\">\n\n  \n    \n\n      <footer>\n      \n      <div class=\"author\">\n        Submitted by <span><span lang=\"\" about=\"/user/laurie\" typeof=\"schema:Person\" property=\"schema:name\" datatype=\"\">Laurie</span></span>\n on <span>28 May, 2014 - 1:53pm</span>\n        \n      </div>\n    </footer>\n  \n  <div class=\"content\">\n    \n      <div class=\"field field--name-upload field--type-file field--label-hidden field--items\">\n              <div class=\"field--item\"><span class=\"file file--mime-application-pdf file--application-pdf icon-before\"><span class=\"file-icon\"><span class=\"icon glyphicon glyphicon-file text-primary\" aria-hidden=\"true\"></span></span><span class=\"file-link\"><a href=\"https://yaffs.net/sites/default/files/downloads/ConsiderationsInChoosingAFlashFileSystem_0.pdf\" type=\"application/pdf; length=131376\" title=\"Open file in new window\" target=\"_blank\" data-toggle=\"tooltip\" data-placement=\"bottom\">ConsiderationsInChoosingAFlashFileSystem.pdf</a></span><span class=\"file-size\">128.3 KB</span></span></div>\n          </div>\n  \n            <div class=\"field field--name-body field--type-text-with-summary field--label-hidden field--item\">\n<p>We have been developing flash file system for embedded systems since 1995. During that time, we have gained a wealth of knowledge and experience.</p>\n<p>This document outlines some of the major issues that must be considered when selecting a Flash File system for embedded use. It also explains how using the Yaffs File System increases reliability, reduces risk and saves money.</p>\n<h1 class=\"western\" style=\"page-break-before: always\">Introduction</h1>\n<p>As embedded system complexity increases and flash storage prices decrease, we see more use of embedded file systems to store data, and so data corruption and loss has become an important cause of system failure.</p>\n<p>When Aleph One began the development of Yaffs in late 2001, we built on experience in flash file system design since 1995. This experience helped to identify the key factors in making Yaffs a fast and robust flash file system now being widely used around the world.</p>\n<p>Although it was originally developed for Linux, Yaffs was designed to be highly portable. This has allowed Yaffs to be ported to many different OSs (including Linux, BSD, Windows CE) and numerous RTOSs (including VxWorks, eCos and pSOS).</p>\n<p>Yaffs is written in fully portable C code and has been used on many different CPU architectures – both little- and big-endian. These include ARM, x86 and PowerPC, soft cores such as NIOS and Microblaze and even various DSP architectures.</p>\n<p>We believe that the Yaffs code base has been used on more OS types and more CPU types than any other file system code base.</p>\n<p>Since its introduction, Yaffs has been used in hundreds of different products and hundreds of millions of different devices in widely diverse application areas from mining to aerospace and everything in between.</p>\n<p>Specific examples include:</p>\n<ul>\n<li>\n<p>communications (two-way radios and infrastructure, mobile phones, cell towers, modems, routers...)</p>\n </li>\n<li>\n<p>retail (point of sale, inventory control...)</p>\n </li>\n<li>\n<p>entertaiment (video cameras, TV sets, DVD players, set-top boxes...)</p>\n </li>\n<li>\n<p>sewing machines and office copiers</p>\n </li>\n<li>\n<p>industrial equipment (PLCs, machinery control...)</p>\n </li>\n<li>\n<p>construction/surveying equipment (theodolites, machinery control...)</p>\n </li>\n<li>\n<p>avionics and satellite equipment</p>\n </li>\n<li>\n<p>transport (bus, train and traffic-signal management/information systems...)</p>\n </li>\n<li>\n<p>and many more.</p>\n </li>\n</ul>\n<p><br />\n<br />\n</p>\n<p><i><b>You may be using Yaffs every day without even realising it.</b></i></p>\n<p><i><b>We have a gratifying number of repeat customers for licences.</b></i></p>\n<h1 class=\"western\"><br />\n<br />\n</h1>\n<h1 class=\"western\" style=\"page-break-before: always\">Do Embedded Systems have different file system needs?</h1>\n<p>To answer this question, we really have to start by asking a slightly different question:</p>\n<p><i>How are embedded systems different than regular computers?</i></p>\n<p style=\"font-style: normal\">When a customer buys a regular computer system, they go shopping for a computer. They talk to the salesperson about Gigabytes, Megahertz and operating systems. They treat it as a computer and expect it to behave like a computer (including shutting it down properly and occasionally having file system problems or needing upgrades).</p>\n<p style=\"font-style: normal\">When they buy a fancy sewing machine, it probably has an embedded file system controlling it. The customer went shopping for a sewing machine and bought a computer that they don\'t even know about. They don\'t treat it like a computer, but like a sewing machine; they certainly do not expect it to have file system problems.</p>\n<h4 class=\"western\">How people treat computers differently from embedded systems</h4>\n<table cellpadding=\"4\" style=\"page-break-inside: avoid; width: 100%; border-spacing: 0px;\">\n<col width=\"85*\" /> <col width=\"85*\" /> <col width=\"85*\" />\n<tr valign=\"top\">\n <td style=\"border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0.1cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 33%;\">\n <p><span style=\"font-size: 11pt; font-size: small; font-size: small;\"><b>Issue</b></span></p>\n  </td>\n <td style=\"border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0.1cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 33%;\">\n <p><span style=\"font-size: 11pt; font-size: small; font-size: small;\"><b>Computer</b></span></p>\n  </td>\n <td style=\"border: 1px solid #000000; padding: 0.1cm; width: 33%;\">\n <p><span style=\"font-size: 11pt; font-size: small; font-size: small;\"><b>Embedded system</b></span></p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 33%;\">\n <p><span style=\"font-size: 11pt; font-size: small; font-size: small;\">Shut down</span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 33%;\">\n <p><span style=\"font-size: 11pt; font-size: small; font-size: small;\">User expects to do a clean shut down.</span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 33%;\">\n <p><span style=\"font-size: 11pt; font-size: small; font-size: small;\">User just unplugs device.</span></p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 33%;\">\n <p><span style=\"font-size: 11pt; font-size: small; font-size: small;\">Reinstalling software</span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 33%;\">\n <p><span style=\"font-size: 11pt; font-size: small; font-size: small;\">Users expect to have to deal with corruption and reinstall software occasionally.</span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 33%;\">\n <p><span style=\"font-size: 11pt; font-size: small; font-size: small;\">Users do not expect to deal with upgrades or data loss or corruption.</span></p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 33%; height: 11px;\">\n <p><span style=\"font-size: 11pt; font-size: small; font-size: small;\">Software Upgrade Failure</span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 33%;\">\n <p><span style=\"font-size: 11pt; font-size: small; font-size: small;\">Annoying</span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 33%;\">\n <p><span style=\"font-size: 11pt; font-size: small; font-size: small;\">Can be devastating</span></p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 33%;\">\n <p><span style=\"font-size: 11pt; font-size: small; font-size: small;\">Attitude to data loss</span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 33%;\">\n <p><span style=\"font-size: 11pt; font-size: small; font-size: small;\">Annoying, but expected</span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 33%;\">\n <p><span style=\"font-size: 11pt; font-size: small; font-size: small;\">System has failed.</span></p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 33%;\">\n <p><span style=\"font-size: 11pt; font-size: small; font-size: small;\">Cost of failure</span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 33%;\">\n <p><span style=\"font-size: 11pt; font-size: small; font-size: small;\">Relatively minor</span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 33%;\">\n <p><span style=\"font-size: 11pt; font-size: small; font-size: small;\">Can shut down factory or even cause injury/death.</span></p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 33%;\">\n <p><span style=\"font-size: 11pt; font-size: small; font-size: small;\">Delayed boot due to file system recovery</span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 33%;\">\n <p><span style=\"font-size: 11pt; font-size: small; font-size: small;\">Annoying, but expected.</span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 33%;\">\n <p><span style=\"font-size: 11pt; font-size: small; font-size: small;\">This is as bad as a failure.</span></p>\n  </td>\n</tr>\n</table>\n<p style=\"font-style: normal\"><br />\n<br />\n</p>\n<p>So people have different attitudes to computers and embedded systems. As a result, embedded systems need to be designed differently from computers. That is particularly important with reliability issues.</p>\n<p style=\"margin-bottom: 0.01cm\"><i><b>Data corruption is a leading cause of embedded system failure, </b></i> </p>\n<p style=\"margin-bottom: 0.01cm\"><i><b>product returns and warranty costs.</b></i> </p>\n<p style=\"margin-bottom: 0.01cm\"><br />\n<br />\n</p>\n<p>The differences outlined above show some of the reasons why embedded systems must perform differently to regular computers, particularly in the way data storage is handled. These examples allow us to identify some very important product-level criteria for embedded file systems:</p>\n<ul>\n<li>\n<p>High resilience against data corruption, particularly in the event of power loss.</p>\n </li>\n<li>\n<p>Prompt file system recovery after power loss - no excessive time penalty</p>\n </li>\n<li>\n<p>Simple data integrity model to ensure data is not compromised.</p>\n </li>\n</ul>\n<p>Of course we also want the embedded file system to have some other very useful features:</p>\n<ul>\n<li>\n<p>High read/write performance with low latency.</p>\n </li>\n<li>\n<p>Familiar programming models to facilitate development.</p>\n </li>\n<li>\n<p>Proven track record to reduce risk.</p>\n </li>\n<li>\n<p>Full source code access to aid development.</p>\n </li>\n<li>\n<p>Portability to provide a future-proof solution for new products.</p>\n </li>\n</ul>\n<p><i><b>Selecting an appropriate file system is crucial to product success.</b></i></p>\n<h1 class=\"western\" style=\"page-break-before: always\">Why does power failure corrupt data?</h1>\n<p>Most power fail data loss in a File System is caused through two mechanisms:</p>\n<ul>\n<li>\n<p>Corruption of allocation tables </p>\n </li>\n<li>\n<p>Loss of cached data that was not yet written to the flash.</p>\n </li>\n</ul>\n<h2 class=\"western\">Corruption of allocation tables and similar structures.</h2>\n<p>Most file systems have allocation tables, bitmaps or similar structures which hold pointers showing which parts of the file storage medium are being used and which parts of which file are stored there. These tables are critical to looking up files and data in the file system. If they are corrupted, then files and data become corrupted. In the most dramatic cases, table corruption can destroy the whole system. </p>\n<p>Some file systems make these tables more robust by keeping two copies, or by using journaling (which keeps a short log of changes, allowing the tables to be fixed up if the table changing gets interrupted) but this causes extra writes to the media, making the file system slower.</p>\n<p>These tables are typically updated many times during writing any file, so there are multiple opportunities for the tables to be corrupted or left in an inconsistent state due to a power loss.</p>\n<p>If power is interrupted at a critical point, then some restoration (such as Microsoft chkdsk or booting in <span style=\"font-style: normal\">safe mode</span>) is often required to try to restore the tables. This may be automatic, but then system start-up is delayed.</p>\n<p>Yaffs is very different; it is a log structured file system which writes tagged data to the flash, and does not store allocation tables or such.</p>\n<p><i><b>If it isn\'t even stored, it can\'t be corrupted!</b></i></p>\n<p>This has three dramatic effects:</p>\n<ul>\n<li>\n<p>Yaffs has no tables, so is immune to these failure modes.</p>\n </li>\n<li>\n<p>There are no extra tables to be written, so Yaffs does not have to resort to caching to achieve good performance.</p>\n </li>\n<li>\n<p>Fewer flash writes means less flash wear, improving product life and reducing power consumption.</p>\n </li>\n</ul>\n<p>When a Yaffs file system is booted, the normal boot up sequence takes care of building up system state. There is thus no need for any special restoration code to be run. A boot up after a power failure is not a special recovery condition, it is just a normal boot up.</p>\n<p><i><b>Yaffs does not have, or need, special recovery handling.</b></i></p>\n<h2 class=\"western\" style=\"page-break-after: avoid\"><span style=\"font-family: Liberation Sans, sans-serif;\"><i><b>Trade-off in cached data</b></i></span></h2>\n<p><span style=\"font-family: Liberation Sans, sans-serif;\"><span style=\"font-size: 11pt; font-size: small; font-size: small;\">File systems tend to be inefficient in the way they write data. Writing just one file requires many changes to the allocation tables; writing many files requires far more changes, often to those same tables. By delaying those writes and holding data in RAM briefly the file system can do fewer writes to achieve the same set of changes. This can improve write speed, at a price.</span></span></p>\n<p><span style=\"font-family: Liberation Sans, sans-serif;\"><span style=\"font-size: 11pt; font-size: small; font-size: small;\">Data which has not been written but just cached in RAM is vulnerable while it is there; it can all be lost if power fails, even including some that the FS had apparently written already.</span></span></p>\n<p><span style=\"font-family: Liberation Sans, sans-serif;\"><span style=\"font-size: 11pt; font-size: small; font-size: small;\">Most file systems support functions to reduce this inefficiency and force the cache to be written out, but this may take many seconds, leaving a significant period of vulnerability, and delaying system operations. Excessive use of these functions to improve reliability will typically impair write performance.</span></span></p>\n<p><span style=\"font-family: Liberation Sans, sans-serif;\"><span style=\"font-size: 11pt; font-size: small; font-size: small;\">A particularly serious example of critical data loss can occur if power or communication fails during a firmware upgrade. Such a failure cripples the product, which must be returned for servicing. Yaffs has caching policies and data integrity models which make it easier to avoid this kind of fatal failure, and which have been tested very extensively. </span></span> </p>\n<p><span style=\"font-family: Liberation Sans, sans-serif;\"><span style=\"font-size: 11pt; font-size: small; font-size: small;\">Since Yaffs is inherently faster and simpler, it does not need deep caching. The Yaffs cache is small and used only for data alignment purposes and improving the throughput of very small reads and writes. Yaffs files are always flushed from the cache when they are closed. Yaffs also provides its own cache-flushing functions, but these are very fast because the cache is small.</span></span></p>\n<p><span style=\"font-family: Liberation Sans, sans-serif;\"><span style=\"font-size: 11pt; font-size: small; font-size: small;\"><i><b>By the time Yaffs closes a file, all the data is guaranteed to be safe on the flash.</b></i></span></span></p>\n<p><span style=\"font-family: Liberation Sans, sans-serif;\"><span style=\"font-size: 11pt; font-size: small; font-size: small;\">This simple caching policy makes it very easy for programmers to write software that is robust against power loss and avoids obscure failure modes. The simplicity confers more reliable operation, faster product development and huge savings in development and maintenance costs.</span></span></p>\n<p><span style=\"font-family: Liberation Sans, sans-serif;\"><span style=\"font-size: 11pt; font-size: small; font-size: small;\"><i><b>Reliable file systems pay for themselves many times over.</b></i></span></span></p>\n<h1 class=\"western\" style=\"page-break-before: always\">Product risk reduction</h1>\n<p>At first glance, a file system seems like it should be a simple body of code: just a few functions that read, write data and look things up by name. However, the reality is much more complex than that.</p>\n<p>One of the most challenging aspects of file systems is that errors are stored and incremental. Unlike most software errors which can be cleared by a reset, storage errors are persistent.</p>\n<p><i><b>A reboot will typically not fix file-system errors.</b></i></p>\n<p>Customers might tolerate a product that needs to be reset once in a while, but file system failures are often fatal. As a result, file system issues can be very damaging to long-term product reliability.</p>\n<p>This is further complicated by flash memory. NAND flash is the only type of semiconductor hardware which leaves the factory with known variable errors, expecting the file system software to handle the problems.</p>\n<p>Flash, NAND in particular, has its own failure modes and these are best handled by a file system specifically designed for NAND.</p>\n<p><i><b>Yaffs was specifically designed to use with NAND and NOR flash chips.</b></i></p>\n<p>Flash memory chip errors may only show up after the product has been used a while, or in a fraction of the flash parts. Typical testing during development (e.g. bench testing) will often fail to expose all types of flash chip error, and others will only be exposed during pilot- or early-production. These put release dates at risk, which can cause huge revenue losses.</p>\n<p>We have a few clients who only determined that they had file system issues when they did a pilot run. That prompted them to try Yaffs and get their products shipping. While we are glad they ended up with a good product, unfortunately they lost revenue and customer goodwill.</p>\n<p><i><b>Finding problems late in development creates business risk.</b></i></p>\n<p>It is thus not surprising that much of our business is repeat business. </p>\n<h1 class=\"western\" style=\"page-break-before: always\">Yaffs testing</h1>\n<p>Testing on its own does not create good software but it does help to verify that the software is working correctly.</p>\n<p>Yaffs has many automated tests that are run on a regular basis. Automated tests allow the testing to be run without human intervention, thus allowing more testing to be done.</p>\n<p>The tests are too numerous to discuss completely (see the Further Information below). W<span style=\"font-weight: normal\">e</span> highlight one: the power-fail stress test.</p>\n<p>The power-fail stress test is a test harness that uses software simulations of flash devices and some software and scripts to simulate the effects of removing power from a Yaffs-based system <span style=\"font-weight: normal\">while it is writing</span> to flash. This test is normally run for 100,0000 to 1 million power-fail simulation cycles, taking many days.</p>\n<p>This particular test suite was originally developed in 2008 during the development of some new features. The tests are very rigorous. In the beginning, this test suite would find a problem after less than 100 power fail iterations. As we identified and fixed the bugs, this number crept up and we now run millions of cycles without seeing a single problem.</p>\n<p><i><b>Yaffs survives millions of power failures in simulation test benches.</b></i></p>\n<p>In addition, many of our clients have also run hardware power failure tests, using a relay and a micro-controller to kill power to the device under test. They have been very satisfied with the results.</p>\n<p style=\"margin-bottom: 0cm; orphans: 0; widows: 0; page-break-before: auto\"><br />\n</p>\n<p><span style=\"font-size: 16pt; font-size: large; font-size: large;\"><b>Licensing</b></span></p>\n<p>Yaffs is available under GNU Public License V2, GPL2, from our git repository at <a href=\"http://www.yaffs.net/\">www.yaffs.net</a>. You may use that code for testing free of charge and for as long as you want.</p>\n<p style=\"font-weight: normal\"><i>You will be using it under the conditions of GPL2 with the obligation to release your associated source code when you start to sell or distribute a product.</i></p>\n<p style=\"font-weight: normal\"><i>We can then sell you a Licence to use Yaffs which removes that obligation and protects your intellectual property.</i></p>\n<p><i><b>With Yaffs you can try before you buy!</b></i></p>\n<h1 class=\"western\">Conclusions</h1>\n<p>Selecting a robust flash file system is key to :</p>\n<ul>\n<li>\n<p>building a successful product.</p>\n </li>\n<li>\n<p>reducing risk, warranty costs and liability.</p>\n </li>\n<li>\n<p>reducing development costs.</p>\n </li>\n</ul>\n<p><i><b>Yaffs has proven itself and can pay for itself many times over.</b></i></p>\n<h1 class=\"western\">Further information</h1>\n<p>This document is intentionally brief. There are many documents at <a href=\"http://www.yaffs.net/\">http://www.yaffs.net</a> for those that want more information, including:</p>\n<p><b>How Yaffs Works:</b> detailed description of internal design.</p>\n<p><b>Yaffs Robustness and Testing:</b> how we know Yaffs handles various flash failure scenarios.</p>\n<p><br />\n<br />\n</p>\n<p>For further information please contact <a href=\"denied:mailto:info@yaffs.net\">info@yaffs.net</a> or access <a href=\"http://www.yaffs.net/\">http://www.yaffs.net</a></p>\n</div>\n      \n  </div>\n\n</article>\n\";}s:9:\"#attached\";a:1:{s:14:\"html_head_link\";a:3:{i:0;a:2:{i:0;a:2:{s:3:\"rel\";s:9:\"canonical\";s:4:\"href\";s:52:\"/documents/considerations-choosing-flash-file-system\";}i:1;b:1;}i:1;a:2:{i:0;a:2:{s:3:\"rel\";s:9:\"shortlink\";s:4:\"href\";s:9:\"/node/466\";}i:1;b:1;}i:2;a:2:{i:0;a:2:{s:3:\"rel\";s:8:\"revision\";s:4:\"href\";s:52:\"/documents/considerations-choosing-flash-file-system\";}i:1;b:1;}}}s:6:\"#cache\";a:3:{s:8:\"contexts\";a:7:{i:0;s:28:\"languages:language_interface\";i:1;s:5:\"theme\";i:2;s:8:\"timezone\";i:3;s:17:\"url.path.is_front\";i:4;s:16:\"user.permissions\";i:5;s:20:\"user.roles:anonymous\";i:6;s:24:\"user.roles:authenticated\";}s:4:\"tags\";a:6:{i:0;s:29:\"config:filter.format.raw_html\";i:1;s:18:\"config:system.site\";i:2;s:7:\"file:77\";i:3;s:8:\"node:466\";i:4;s:9:\"node_view\";i:5;s:6:\"user:4\";}s:7:\"max-age\";i:-1;}s:17:\"#cache_properties\";a:1:{i:0;s:6:\"#title\";}s:6:\"#title\";O:25:\"Drupal\\Core\\Render\\Markup\":1:{s:9:\"\0*\0string\";s:60:\"<span>Considerations in Choosing a Flash File System</span>\n\";}}',-1,1504631857.512,1,'config:filter.format.raw_html config:system.site file:77 node:466 node_view rendered user:4','291'),('entity_view:node:466:full:[languages:language_interface]=en:[theme]=yaffs:[user.permissions]=aa7fc4c8fb40c7a8665ccd12fea07926dff0f59b9ee3346bc513c6399bee5b01:[user.roles:anonymous]=0','a:2:{s:15:\"#cache_redirect\";b:1;s:6:\"#cache\";a:5:{s:4:\"keys\";a:4:{i:0;s:11:\"entity_view\";i:1;s:4:\"node\";i:2;s:3:\"466\";i:3;s:4:\"full\";}s:8:\"contexts\";a:7:{i:0;s:28:\"languages:language_interface\";i:1;s:5:\"theme\";i:2;s:8:\"timezone\";i:3;s:17:\"url.path.is_front\";i:4;s:16:\"user.permissions\";i:5;s:20:\"user.roles:anonymous\";i:6;s:24:\"user.roles:authenticated\";}s:4:\"tags\";a:6:{i:0;s:29:\"config:filter.format.raw_html\";i:1;s:18:\"config:system.site\";i:2;s:7:\"file:77\";i:3;s:8:\"node:466\";i:4;s:9:\"node_view\";i:5;s:6:\"user:4\";}s:7:\"max-age\";i:-1;s:3:\"bin\";s:6:\"render\";}}',-1,1504631857.510,1,'config:filter.format.raw_html config:system.site file:77 node:466 node_view rendered user:4','291'),('entity_view:node:466:rss:[languages:language_interface]=en:[theme]=yaffs:[timezone]=Europe/London:[url.path.is_front]=is_front.0:[user.permissions]=aa7fc4c8fb40c7a8665ccd12fea07926dff0f59b9ee3346bc513c6399bee5b01','a:3:{s:7:\"#markup\";O:25:\"Drupal\\Core\\Render\\Markup\":1:{s:9:\"\0*\0string\";s:25048:\"<span>Considerations in Choosing a Flash File System</span>\n<span><span lang=\"\" about=\"/user/laurie\" typeof=\"schema:Person\" property=\"schema:name\" datatype=\"\">Laurie</span></span>\n<span>28 May, 2014 - 1:53pm</span>\n\n      <div class=\"field field--name-upload field--type-file field--label-hidden field--items\">\n              <div class=\"field--item\"><span class=\"file file--mime-application-pdf file--application-pdf icon-before\"><span class=\"file-icon\"><span class=\"icon glyphicon glyphicon-file text-primary\" aria-hidden=\"true\"></span></span><span class=\"file-link\"><a href=\"https://yaffs.net/sites/default/files/downloads/ConsiderationsInChoosingAFlashFileSystem_0.pdf\" type=\"application/pdf; length=131376\" title=\"Open file in new window\" target=\"_blank\" data-toggle=\"tooltip\" data-placement=\"bottom\">ConsiderationsInChoosingAFlashFileSystem.pdf</a></span><span class=\"file-size\">128.3 KB</span></span></div>\n          </div>\n  \n            <div class=\"field field--name-body field--type-text-with-summary field--label-hidden field--item\">\n<p>We have been developing flash file system for embedded systems since 1995. During that time, we have gained a wealth of knowledge and experience.</p>\n<p>This document outlines some of the major issues that must be considered when selecting a Flash File system for embedded use. It also explains how using the Yaffs File System increases reliability, reduces risk and saves money.</p>\n<h1 class=\"western\" style=\"page-break-before: always\">Introduction</h1>\n<p>As embedded system complexity increases and flash storage prices decrease, we see more use of embedded file systems to store data, and so data corruption and loss has become an important cause of system failure.</p>\n<p>When Aleph One began the development of Yaffs in late 2001, we built on experience in flash file system design since 1995. This experience helped to identify the key factors in making Yaffs a fast and robust flash file system now being widely used around the world.</p>\n<p>Although it was originally developed for Linux, Yaffs was designed to be highly portable. This has allowed Yaffs to be ported to many different OSs (including Linux, BSD, Windows CE) and numerous RTOSs (including VxWorks, eCos and pSOS).</p>\n<p>Yaffs is written in fully portable C code and has been used on many different CPU architectures – both little- and big-endian. These include ARM, x86 and PowerPC, soft cores such as NIOS and Microblaze and even various DSP architectures.</p>\n<p>We believe that the Yaffs code base has been used on more OS types and more CPU types than any other file system code base.</p>\n<p>Since its introduction, Yaffs has been used in hundreds of different products and hundreds of millions of different devices in widely diverse application areas from mining to aerospace and everything in between.</p>\n<p>Specific examples include:</p>\n<ul>\n<li>\n<p>communications (two-way radios and infrastructure, mobile phones, cell towers, modems, routers...)</p>\n </li>\n<li>\n<p>retail (point of sale, inventory control...)</p>\n </li>\n<li>\n<p>entertaiment (video cameras, TV sets, DVD players, set-top boxes...)</p>\n </li>\n<li>\n<p>sewing machines and office copiers</p>\n </li>\n<li>\n<p>industrial equipment (PLCs, machinery control...)</p>\n </li>\n<li>\n<p>construction/surveying equipment (theodolites, machinery control...)</p>\n </li>\n<li>\n<p>avionics and satellite equipment</p>\n </li>\n<li>\n<p>transport (bus, train and traffic-signal management/information systems...)</p>\n </li>\n<li>\n<p>and many more.</p>\n </li>\n</ul>\n<p><br />\n<br />\n</p>\n<p><i><b>You may be using Yaffs every day without even realising it.</b></i></p>\n<p><i><b>We have a gratifying number of repeat customers for licences.</b></i></p>\n<h1 class=\"western\"><br />\n<br />\n</h1>\n<h1 class=\"western\" style=\"page-break-before: always\">Do Embedded Systems have different file system needs?</h1>\n<p>To answer this question, we really have to start by asking a slightly different question:</p>\n<p><i>How are embedded systems different than regular computers?</i></p>\n<p style=\"font-style: normal\">When a customer buys a regular computer system, they go shopping for a computer. They talk to the salesperson about Gigabytes, Megahertz and operating systems. They treat it as a computer and expect it to behave like a computer (including shutting it down properly and occasionally having file system problems or needing upgrades).</p>\n<p style=\"font-style: normal\">When they buy a fancy sewing machine, it probably has an embedded file system controlling it. The customer went shopping for a sewing machine and bought a computer that they don\'t even know about. They don\'t treat it like a computer, but like a sewing machine; they certainly do not expect it to have file system problems.</p>\n<h4 class=\"western\">How people treat computers differently from embedded systems</h4>\n<table cellpadding=\"4\" style=\"page-break-inside: avoid; width: 100%; border-spacing: 0px;\">\n<col width=\"85*\" /> <col width=\"85*\" /> <col width=\"85*\" />\n<tr valign=\"top\">\n <td style=\"border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0.1cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 33%;\">\n <p><span style=\"font-size: 11pt; font-size: small; font-size: small;\"><b>Issue</b></span></p>\n  </td>\n <td style=\"border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0.1cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 33%;\">\n <p><span style=\"font-size: 11pt; font-size: small; font-size: small;\"><b>Computer</b></span></p>\n  </td>\n <td style=\"border: 1px solid #000000; padding: 0.1cm; width: 33%;\">\n <p><span style=\"font-size: 11pt; font-size: small; font-size: small;\"><b>Embedded system</b></span></p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 33%;\">\n <p><span style=\"font-size: 11pt; font-size: small; font-size: small;\">Shut down</span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 33%;\">\n <p><span style=\"font-size: 11pt; font-size: small; font-size: small;\">User expects to do a clean shut down.</span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 33%;\">\n <p><span style=\"font-size: 11pt; font-size: small; font-size: small;\">User just unplugs device.</span></p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 33%;\">\n <p><span style=\"font-size: 11pt; font-size: small; font-size: small;\">Reinstalling software</span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 33%;\">\n <p><span style=\"font-size: 11pt; font-size: small; font-size: small;\">Users expect to have to deal with corruption and reinstall software occasionally.</span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 33%;\">\n <p><span style=\"font-size: 11pt; font-size: small; font-size: small;\">Users do not expect to deal with upgrades or data loss or corruption.</span></p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 33%; height: 11px;\">\n <p><span style=\"font-size: 11pt; font-size: small; font-size: small;\">Software Upgrade Failure</span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 33%;\">\n <p><span style=\"font-size: 11pt; font-size: small; font-size: small;\">Annoying</span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 33%;\">\n <p><span style=\"font-size: 11pt; font-size: small; font-size: small;\">Can be devastating</span></p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 33%;\">\n <p><span style=\"font-size: 11pt; font-size: small; font-size: small;\">Attitude to data loss</span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 33%;\">\n <p><span style=\"font-size: 11pt; font-size: small; font-size: small;\">Annoying, but expected</span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 33%;\">\n <p><span style=\"font-size: 11pt; font-size: small; font-size: small;\">System has failed.</span></p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 33%;\">\n <p><span style=\"font-size: 11pt; font-size: small; font-size: small;\">Cost of failure</span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 33%;\">\n <p><span style=\"font-size: 11pt; font-size: small; font-size: small;\">Relatively minor</span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 33%;\">\n <p><span style=\"font-size: 11pt; font-size: small; font-size: small;\">Can shut down factory or even cause injury/death.</span></p>\n  </td>\n</tr>\n<tr valign=\"top\">\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 33%;\">\n <p><span style=\"font-size: 11pt; font-size: small; font-size: small;\">Delayed boot due to file system recovery</span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; width: 33%;\">\n <p><span style=\"font-size: 11pt; font-size: small; font-size: small;\">Annoying, but expected.</span></p>\n  </td>\n <td style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; width: 33%;\">\n <p><span style=\"font-size: 11pt; font-size: small; font-size: small;\">This is as bad as a failure.</span></p>\n  </td>\n</tr>\n</table>\n<p style=\"font-style: normal\"><br />\n<br />\n</p>\n<p>So people have different attitudes to computers and embedded systems. As a result, embedded systems need to be designed differently from computers. That is particularly important with reliability issues.</p>\n<p style=\"margin-bottom: 0.01cm\"><i><b>Data corruption is a leading cause of embedded system failure, </b></i> </p>\n<p style=\"margin-bottom: 0.01cm\"><i><b>product returns and warranty costs.</b></i> </p>\n<p style=\"margin-bottom: 0.01cm\"><br />\n<br />\n</p>\n<p>The differences outlined above show some of the reasons why embedded systems must perform differently to regular computers, particularly in the way data storage is handled. These examples allow us to identify some very important product-level criteria for embedded file systems:</p>\n<ul>\n<li>\n<p>High resilience against data corruption, particularly in the event of power loss.</p>\n </li>\n<li>\n<p>Prompt file system recovery after power loss - no excessive time penalty</p>\n </li>\n<li>\n<p>Simple data integrity model to ensure data is not compromised.</p>\n </li>\n</ul>\n<p>Of course we also want the embedded file system to have some other very useful features:</p>\n<ul>\n<li>\n<p>High read/write performance with low latency.</p>\n </li>\n<li>\n<p>Familiar programming models to facilitate development.</p>\n </li>\n<li>\n<p>Proven track record to reduce risk.</p>\n </li>\n<li>\n<p>Full source code access to aid development.</p>\n </li>\n<li>\n<p>Portability to provide a future-proof solution for new products.</p>\n </li>\n</ul>\n<p><i><b>Selecting an appropriate file system is crucial to product success.</b></i></p>\n<h1 class=\"western\" style=\"page-break-before: always\">Why does power failure corrupt data?</h1>\n<p>Most power fail data loss in a File System is caused through two mechanisms:</p>\n<ul>\n<li>\n<p>Corruption of allocation tables </p>\n </li>\n<li>\n<p>Loss of cached data that was not yet written to the flash.</p>\n </li>\n</ul>\n<h2 class=\"western\">Corruption of allocation tables and similar structures.</h2>\n<p>Most file systems have allocation tables, bitmaps or similar structures which hold pointers showing which parts of the file storage medium are being used and which parts of which file are stored there. These tables are critical to looking up files and data in the file system. If they are corrupted, then files and data become corrupted. In the most dramatic cases, table corruption can destroy the whole system. </p>\n<p>Some file systems make these tables more robust by keeping two copies, or by using journaling (which keeps a short log of changes, allowing the tables to be fixed up if the table changing gets interrupted) but this causes extra writes to the media, making the file system slower.</p>\n<p>These tables are typically updated many times during writing any file, so there are multiple opportunities for the tables to be corrupted or left in an inconsistent state due to a power loss.</p>\n<p>If power is interrupted at a critical point, then some restoration (such as Microsoft chkdsk or booting in <span style=\"font-style: normal\">safe mode</span>) is often required to try to restore the tables. This may be automatic, but then system start-up is delayed.</p>\n<p>Yaffs is very different; it is a log structured file system which writes tagged data to the flash, and does not store allocation tables or such.</p>\n<p><i><b>If it isn\'t even stored, it can\'t be corrupted!</b></i></p>\n<p>This has three dramatic effects:</p>\n<ul>\n<li>\n<p>Yaffs has no tables, so is immune to these failure modes.</p>\n </li>\n<li>\n<p>There are no extra tables to be written, so Yaffs does not have to resort to caching to achieve good performance.</p>\n </li>\n<li>\n<p>Fewer flash writes means less flash wear, improving product life and reducing power consumption.</p>\n </li>\n</ul>\n<p>When a Yaffs file system is booted, the normal boot up sequence takes care of building up system state. There is thus no need for any special restoration code to be run. A boot up after a power failure is not a special recovery condition, it is just a normal boot up.</p>\n<p><i><b>Yaffs does not have, or need, special recovery handling.</b></i></p>\n<h2 class=\"western\" style=\"page-break-after: avoid\"><span style=\"font-family: Liberation Sans, sans-serif;\"><i><b>Trade-off in cached data</b></i></span></h2>\n<p><span style=\"font-family: Liberation Sans, sans-serif;\"><span style=\"font-size: 11pt; font-size: small; font-size: small;\">File systems tend to be inefficient in the way they write data. Writing just one file requires many changes to the allocation tables; writing many files requires far more changes, often to those same tables. By delaying those writes and holding data in RAM briefly the file system can do fewer writes to achieve the same set of changes. This can improve write speed, at a price.</span></span></p>\n<p><span style=\"font-family: Liberation Sans, sans-serif;\"><span style=\"font-size: 11pt; font-size: small; font-size: small;\">Data which has not been written but just cached in RAM is vulnerable while it is there; it can all be lost if power fails, even including some that the FS had apparently written already.</span></span></p>\n<p><span style=\"font-family: Liberation Sans, sans-serif;\"><span style=\"font-size: 11pt; font-size: small; font-size: small;\">Most file systems support functions to reduce this inefficiency and force the cache to be written out, but this may take many seconds, leaving a significant period of vulnerability, and delaying system operations. Excessive use of these functions to improve reliability will typically impair write performance.</span></span></p>\n<p><span style=\"font-family: Liberation Sans, sans-serif;\"><span style=\"font-size: 11pt; font-size: small; font-size: small;\">A particularly serious example of critical data loss can occur if power or communication fails during a firmware upgrade. Such a failure cripples the product, which must be returned for servicing. Yaffs has caching policies and data integrity models which make it easier to avoid this kind of fatal failure, and which have been tested very extensively. </span></span> </p>\n<p><span style=\"font-family: Liberation Sans, sans-serif;\"><span style=\"font-size: 11pt; font-size: small; font-size: small;\">Since Yaffs is inherently faster and simpler, it does not need deep caching. The Yaffs cache is small and used only for data alignment purposes and improving the throughput of very small reads and writes. Yaffs files are always flushed from the cache when they are closed. Yaffs also provides its own cache-flushing functions, but these are very fast because the cache is small.</span></span></p>\n<p><span style=\"font-family: Liberation Sans, sans-serif;\"><span style=\"font-size: 11pt; font-size: small; font-size: small;\"><i><b>By the time Yaffs closes a file, all the data is guaranteed to be safe on the flash.</b></i></span></span></p>\n<p><span style=\"font-family: Liberation Sans, sans-serif;\"><span style=\"font-size: 11pt; font-size: small; font-size: small;\">This simple caching policy makes it very easy for programmers to write software that is robust against power loss and avoids obscure failure modes. The simplicity confers more reliable operation, faster product development and huge savings in development and maintenance costs.</span></span></p>\n<p><span style=\"font-family: Liberation Sans, sans-serif;\"><span style=\"font-size: 11pt; font-size: small; font-size: small;\"><i><b>Reliable file systems pay for themselves many times over.</b></i></span></span></p>\n<h1 class=\"western\" style=\"page-break-before: always\">Product risk reduction</h1>\n<p>At first glance, a file system seems like it should be a simple body of code: just a few functions that read, write data and look things up by name. However, the reality is much more complex than that.</p>\n<p>One of the most challenging aspects of file systems is that errors are stored and incremental. Unlike most software errors which can be cleared by a reset, storage errors are persistent.</p>\n<p><i><b>A reboot will typically not fix file-system errors.</b></i></p>\n<p>Customers might tolerate a product that needs to be reset once in a while, but file system failures are often fatal. As a result, file system issues can be very damaging to long-term product reliability.</p>\n<p>This is further complicated by flash memory. NAND flash is the only type of semiconductor hardware which leaves the factory with known variable errors, expecting the file system software to handle the problems.</p>\n<p>Flash, NAND in particular, has its own failure modes and these are best handled by a file system specifically designed for NAND.</p>\n<p><i><b>Yaffs was specifically designed to use with NAND and NOR flash chips.</b></i></p>\n<p>Flash memory chip errors may only show up after the product has been used a while, or in a fraction of the flash parts. Typical testing during development (e.g. bench testing) will often fail to expose all types of flash chip error, and others will only be exposed during pilot- or early-production. These put release dates at risk, which can cause huge revenue losses.</p>\n<p>We have a few clients who only determined that they had file system issues when they did a pilot run. That prompted them to try Yaffs and get their products shipping. While we are glad they ended up with a good product, unfortunately they lost revenue and customer goodwill.</p>\n<p><i><b>Finding problems late in development creates business risk.</b></i></p>\n<p>It is thus not surprising that much of our business is repeat business. </p>\n<h1 class=\"western\" style=\"page-break-before: always\">Yaffs testing</h1>\n<p>Testing on its own does not create good software but it does help to verify that the software is working correctly.</p>\n<p>Yaffs has many automated tests that are run on a regular basis. Automated tests allow the testing to be run without human intervention, thus allowing more testing to be done.</p>\n<p>The tests are too numerous to discuss completely (see the Further Information below). W<span style=\"font-weight: normal\">e</span> highlight one: the power-fail stress test.</p>\n<p>The power-fail stress test is a test harness that uses software simulations of flash devices and some software and scripts to simulate the effects of removing power from a Yaffs-based system <span style=\"font-weight: normal\">while it is writing</span> to flash. This test is normally run for 100,0000 to 1 million power-fail simulation cycles, taking many days.</p>\n<p>This particular test suite was originally developed in 2008 during the development of some new features. The tests are very rigorous. In the beginning, this test suite would find a problem after less than 100 power fail iterations. As we identified and fixed the bugs, this number crept up and we now run millions of cycles without seeing a single problem.</p>\n<p><i><b>Yaffs survives millions of power failures in simulation test benches.</b></i></p>\n<p>In addition, many of our clients have also run hardware power failure tests, using a relay and a micro-controller to kill power to the device under test. They have been very satisfied with the results.</p>\n<p style=\"margin-bottom: 0cm; orphans: 0; widows: 0; page-break-before: auto\"><br />\n</p>\n<p><span style=\"font-size: 16pt; font-size: large; font-size: large;\"><b>Licensing</b></span></p>\n<p>Yaffs is available under GNU Public License V2, GPL2, from our git repository at <a href=\"http://www.yaffs.net/\">www.yaffs.net</a>. You may use that code for testing free of charge and for as long as you want.</p>\n<p style=\"font-weight: normal\"><i>You will be using it under the conditions of GPL2 with the obligation to release your associated source code when you start to sell or distribute a product.</i></p>\n<p style=\"font-weight: normal\"><i>We can then sell you a Licence to use Yaffs which removes that obligation and protects your intellectual property.</i></p>\n<p><i><b>With Yaffs you can try before you buy!</b></i></p>\n<h1 class=\"western\">Conclusions</h1>\n<p>Selecting a robust flash file system is key to :</p>\n<ul>\n<li>\n<p>building a successful product.</p>\n </li>\n<li>\n<p>reducing risk, warranty costs and liability.</p>\n </li>\n<li>\n<p>reducing development costs.</p>\n </li>\n</ul>\n<p><i><b>Yaffs has proven itself and can pay for itself many times over.</b></i></p>\n<h1 class=\"western\">Further information</h1>\n<p>This document is intentionally brief. There are many documents at <a href=\"http://www.yaffs.net/\">http://www.yaffs.net</a> for those that want more information, including:</p>\n<p><b>How Yaffs Works:</b> detailed description of internal design.</p>\n<p><b>Yaffs Robustness and Testing:</b> how we know Yaffs handles various flash failure scenarios.</p>\n<p><br />\n<br />\n</p>\n<p>For further information please contact <a href=\"denied:mailto:info@yaffs.net\">info@yaffs.net</a> or access <a href=\"http://www.yaffs.net/\">http://www.yaffs.net</a></p>\n</div>\n      \";}s:9:\"#attached\";a:0:{}s:6:\"#cache\";a:3:{s:8:\"contexts\";a:5:{i:0;s:28:\"languages:language_interface\";i:1;s:5:\"theme\";i:2;s:8:\"timezone\";i:3;s:17:\"url.path.is_front\";i:4;s:16:\"user.permissions\";}s:4:\"tags\";a:5:{i:0;s:29:\"config:filter.format.raw_html\";i:1;s:7:\"file:77\";i:2;s:8:\"node:466\";i:3;s:9:\"node_view\";i:4;s:6:\"user:4\";}s:7:\"max-age\";i:-1;}}',-1,1504783535.641,1,'config:filter.format.raw_html file:77 node:466 node_view rendered user:4','285'),('entity_view:node:466:rss:[languages:language_interface]=en:[theme]=yaffs:[user.permissions]=aa7fc4c8fb40c7a8665ccd12fea07926dff0f59b9ee3346bc513c6399bee5b01','a:2:{s:15:\"#cache_redirect\";b:1;s:6:\"#cache\";a:5:{s:4:\"keys\";a:4:{i:0;s:11:\"entity_view\";i:1;s:4:\"node\";i:2;s:3:\"466\";i:3;s:3:\"rss\";}s:8:\"contexts\";a:5:{i:0;s:28:\"languages:language_interface\";i:1;s:5:\"theme\";i:2;s:8:\"timezone\";i:3;s:17:\"url.path.is_front\";i:4;s:16:\"user.permissions\";}s:4:\"tags\";a:5:{i:0;s:29:\"config:filter.format.raw_html\";i:1;s:7:\"file:77\";i:2;s:8:\"node:466\";i:3;s:9:\"node_view\";i:4;s:6:\"user:4\";}s:7:\"max-age\";i:-1;s:3:\"bin\";s:6:\"render\";}}',-1,1504783535.626,1,'config:filter.format.raw_html file:77 node:466 node_view rendered user:4','285'),