('paper',0,420,421,'und',0,'<h3>1 Background</h3><p>\r\n<style type=\"text/css\">\r\n<!--\r\n		@page { margin: 2cm }\r\n		P { margin-bottom: 0.21cm; text-align: justify }\r\n		P.western { so-language: en-GB }\r\n		P.sdfootnote-western { margin-left: 0.5cm; text-indent: -0.5cm; margin-bottom: 0cm; font-size: 10pt; so-language: en-GB; text-align: left }\r\n		P.sdfootnote-cjk { margin-left: 0.5cm; text-indent: -0.5cm; margin-bottom: 0cm; font-size: 10pt; text-align: left }\r\n		P.sdfootnote-ctl { margin-left: 0.5cm; text-indent: -0.5cm; margin-bottom: 0cm; font-size: 10pt; text-align: left }\r\n		H1 { margin-bottom: 0.21cm }\r\n		H1.western { font-family: \"Arial\", sans-serif; font-size: 16pt; so-language: en-GB }\r\n		H1.cjk { font-family: \"DejaVu Sans\"; font-size: 16pt }\r\n		H1.ctl { font-family: \"Lohit Hindi\"; font-size: 16pt }\r\n		H2 { margin-bottom: 0.21cm; background: transparent; page-break-before: auto }\r\n		H2.western { font-family: \"Arial\", sans-serif; font-size: 14pt; so-language: en-GB; font-style: italic }\r\n		H2.cjk { font-size: 14pt; font-style: italic; font-weight: normal }\r\n		H2.ctl { font-family: \"Lohit Hindi\"; font-size: 14pt; font-style: italic }\r\n		A.sdfootnoteanc { font-size: 57% }\r\n	--></style>\r\n</p><p class=\"western\">Cheaper CPUs and flash have driven up embedded system functionality. These increased functions often require file system storage.</p><p class=\"western\">The original flash file storage mechanisms were the use of a flash translation layer (FTL) – a driver model which makes flash memory appear as a disk drive – in conjunction with a disk-oriented file system such as FAT. This storage methodology has various performance and robustness limitations, leading to the development of file systems designed specifically for flash memory. These are known as flash file systems.</p><p class=\"western\">Flash memory has various limitations when compared with a disk. For example, flash memory pages cannot be individually re-written but instead the whole block must be erased and rewritten with the modified page. Typical FTL achieve this with various logical to physical mapping schemes. Thus emulating disk-like behaviour on flash memory adds an extra layer of software which slows down write performance. Worse still, it adds extra state which is prone to corruption due to power failure.</p><p class=\"western\">A typical FTL-based solution will use a file system such as FAT. FAT always stores tables in the same disk blocks. Since flash memory blocks can endure a limited number of write/erasure cycles, the FTL must move the physical location of the block around to prevent the high traffic blocks from wearing out. This requires wear levelling – a further burden.</p><p class=\"western\">Some systems try to mitigate against the performance penalties by caching a lot of data to reduce writes. While this can go some way towards reducing the apparent write time, it does make the solution prone to data loss in the event of a power failure.</p><p class=\"western\">As well as limitations, flash memory also has certain advantages when compared to rotating media. There is no spin up time, making it more responsive. There is no read head so there is no read penalty if data is fragmented. Flash file systems can be designed to exploit these advantages.</p><p class=\"western\">True flash file systems<a class=\"sdfootnoteanc\" href=\"#sdfootnote1sym\" name=\"sdfootnote1anc\"><sup>1</sup></a>, on the other hand, are a single code body designed to take the features and limitations of flash into consideration. Flash file systems can thus be far more “flash friendly”. Well designed flash file systems will avoid using “flash unfriendly” techniques such as allocation tables and in-place rewriting.</p><p class=\"western\">Yaffs is a flash file system, originally designed specifically for NAND flash though also used with great success on NOR flash too. Yaffs development started in 2001 when 32Mbytes of flash was considered large. Since then, yaffs has been expanded to work properly with different flash types and far larger memory arrays (many GBytes).</p><p class=\"western\">Yaffs was originally deployed in Linux, but was written in an OS-neutral way, mainly to facilitate modular development and testing. This turned out to be fotunate when we hadrequests to port Yaffs to other operating systems. Since then, Yaffs has been used with many different operating systems, CPU types and all sorts of application areas. Some examples are . . . .</p><h2 class=\"western\">Flash File System considerations</h2><p class=\"western\">There are many criteria that are important when selecting a flash file system. These are some that out customers have found to be most important:</p><ul><li><p class=\"western\">Robustness: It really is not worth having a file system that loses or corrupts data and prevents the system from working properly. Some flash file systems are only robust when synced (flushed) after files have been written. That requires extra code, slows the system and leaves the file system in a non-deterministic state until the sync has been completed. Some file systems need to perform disk repair operations (eg. check disk) in the event of a power failure. This can add considerable time to the start up, preventing the system from being operational.</p></li><li><p class=\"western\">Performance: In many embedded system designs, slow read/write performance can delay tasks and cause system degradation or even failure. It is thus important that read/write performance be acceptable. Note that many flash file systems need to perform extra actions such as garbage collection. In some cases these actions can cause the file system to stall for a long time. It is thus important that these factors be taken into consideration. Performance can sometimes be improved by adding a write caching layer. These caching layers make the file system calls (write etc) proceed quickly, without actually writing the data to flash. This is a two-edged sword as data in the cache will be lost on a power failure and syncing the file system will take a long time. Thus, most flash file systems offer either speed or robustness – not both.</p></li><li><p class=\"western\">Proven: It is very easy for a file system vendor to provide a list of claims saying “100% power safe” or similar, but what evidence do they have to back this up? All file systems, including flash file systems, are complex bodies of software with extremely complex state. They need very significant testing to prove that they work correctly.</p></li><li><p class=\"western\">Portable: Software is a huge investment and it is increasingly important to be able to port the software between OSs and CPU architectures. Most flash file systems are limited to a single operating system which makes it difficult to migrate software between different platforms. In yaffs\' case portability extends to being able to seamlessly migrate the core yaffs code into a test framework which enhances testing.</p></li></ul><h2 class=\"western\" style=\"page-break-before: always;\">How YAFFS achieves robustness and performance</h2><p class=\"western\">Yaffs was designed from the ground up specifically to work well with NAND flash. The author had already developed another flash file system, so was already familiar with the design challenges of flash.</p><p class=\"western\">As yaffs is not just adapting a disk-oriented file system to work with flash it is not surprising that yaffs is very different in design to most other file systems. The key difference is that yaffs is a log-structured. file system<a class=\"sdfootnoteanc\" href=\"#sdfootnote2sym\" name=\"sdfootnote2anc\"><sup>2</sup></a>.</p><p class=\"western\">In essence, a log structured file system writes file system changes as a sequential log. The log structure is particularly suitable for various reasons including:</p><ul><li><p class=\"western\">All writes are at the end of the log. When a file is modified, there is no need to erase and rewrite a part of the flash. Changes are just appended to the log. Thus there is no need to erase and copy old data just to change some existing pages in a file. This tends to make writes much faster. There is no need to do a lot of caching to achieve performance. Data can be written to the log immediately meaning that sync time is very low. Data robustness is improved dramatically.</p></li><li><p class=\"western\">There are no allocation tables or similar. This reduces the amount of data being written to the flash, and that there are no tables to corrupt.</p></li><li><p class=\"western\">Since all writes are to the end of the log there are no “high traffic” blocks. This means yaffs only needs a simpler wear leveling strategy.</p></li><li><p class=\"western\">In the event of a power failure, the file system state is easily re-created from the log. This means there is no need to perform disk repair operations to correct for an unclean shutdown.</p></li></ul><p class=\"western\">So why don\'t we see many log structured file systems for disk file systems? The answer to this is that log file systems tend to spread the writes around on the media. That is typically very problematic for mechanical storage which must physically move the read/write head from one location to another making the access time very slow. Of course that does not apply for flash memory By designing specifically for flash, yaffs can ignore this issue and write fast.</p><p class=\"western\">Many flash file systems need make a compromise between robustness against performance. Thanks to the log structure, yaffs does not need to. Yaffs can provide high performance without giving up on robustness.</p><p class=\"western\">Those familiar with log structured file system design will know that some log structured file systems have problems with garbage collection<a class=\"sdfootnoteanc\" href=\"#sdfootnote3sym\" name=\"sdfootnote3anc\"><sup>3</sup></a>. Garbage collection is used to clean up the log and make more free space available. Some log structured file system designs did not pay enough attention to garbage collection and can stall for a considerable time while garbage collection happens. Yaffs was designed differently. The potential impact of garbage collection was considered throughout the yaffs design process. As a result, yaffs has a very simple garbage collection model that allows a lot of flexibility in garbage collection scheduling. This prevents the garbage collection from making the file system unresponsive.</p><p class=\"western\">Most file systems are developed within the context, and framework of, a single operating system. This typically makes the code difficult to explore, debug and port. Yaffs on the other hand was developed from the start inside a portable development/testing framework. Yaffs is then ported to various operating systems through the addition of glue code.</p><p class=\"western\">There are many benefits to this approach:</p><ul><li><p class=\"western\">A development framework runs in user space which provides a richer development environment than inside an OS kernel. It is much easier to attach debuggers and perform logging and create reproducible testing.</p></li><li><p class=\"western\">The code is structured to be portable. That makes it relatively easy to port to a new OS or RTOS with a high level of confidence.</p></li><li><p class=\"western\">There is a choice of porting interfaces allowing more flexibility to determine which porting method will be simpler. For example, the Linux wrapper accesses the yaffs core directly while the Windows CE wrapper access the Yaffs Direct Interface<a class=\"sdfootnoteanc\" href=\"#sdfootnote4sym\" name=\"sdfootnote4anc\"><sup>4</sup></a>.</p></li><li><p class=\"western\">Each different environment provides different test tools. For example, Linux provides a raft of file system test tools that do different kinds of testing to the power fail test harness. Since the vast majority of the code is in the portable Yaffs core, that code gets the advantage of all test methods combined. The many millions of Android phone users that use Yaffs-based devices are helping test the core code that is also used on a wide variety of different operating systems and a wide range of different device types.</p></li><li><p class=\"western\">Its Open Source status means any interested parson can take a version from git and test it to make sure it meets their needs.</p></li></ul><h2 class=\"western\" style=\"page-break-before: always;\">Testing</h2><p class=\"western\">It is all very well to design software to be robust, but it needs thorough testing to build the confidence of users in the author and the supplier.</p><p class=\"western\">File systems have incredibly complex state so it is not at all surprising that operating system designers find file systems some of the most challenging code to test.</p><p class=\"western\">There is no single test methodology that can test all cases, and exhaustive state testing is impossible. The best we can do is to have a suite of test methodologies that combine to provide thorough testing.</p><p class=\"western\">Approximately 60% of yaffs development effort is directed towards testing and improving the test environment. We are constantly researching new methodologies.</p><p class=\"western\">The following are descriptions of the most important test strategies used in yaffs.</p><h3 class=\"western\">Power Fail Stress Testing</h3><p class=\"western\">By far the most important consideration in yaffs testing is that it is robust to corruptions caused by power failure. We want yaffs to provide the basis for reliable products in typical embedded system environments.</p><p class=\"western\">The first power fail testing was done by companies integrating yaffs into their products. Some of these built test jigs which would automatically interrupt power while running a real hardware device. This approach is better than nothing, but has some limitations:</p><ul><li><p class=\"western\">It is relatively costly to set up. Flash has a limited lifetime meaning that test devices wear out with time and must be replaced.</p></li><li><p class=\"western\">It is relatively slow since each cycle takes many seconds to boot, run the application for a while and then reboot.</p></li><li><p class=\"western\">Many, and perhaps most, of the power interruptions will happen at times when the file system is inactive and thus be wasted cycles.</p></li></ul><p class=\"western\">In 2008 we developed a simulated power-fail-test environment. This simulates power failures using simulated flash memory while running various consistency checks.</p><p class=\"western\">The benefits of a software-based test harness are numerous:</p><ul><li><p class=\"western\">The test harness controls the point at which the simulated power failures happen. That means every test cycle counts.</p></li><li><p class=\"western\">No special hardware is required.</p></li><li><p class=\"western\">Test loops run faster. A quad-core computer can simulate ten to twenty power failures per second. That means about a million power failure simulations per day.</p></li></ul><p class=\"western\">The effectiveness of the new software based testing is dramatic.. A few times we have tested some user-suggested changes that had passed a week or more of real-world power fail testing only to have problems caught by the software simulation in a matter of minutes.</p><p class=\"western\">We regularly run the power fail simulation test over a weekend, testing millions of power fail cycles.</p><h3 class=\"western\">Testing the Yaffs Direct Interface API</h3><p class=\"western\">Yaffs Direct Interface (YDI) is a POSIX-like wrapper around the yaffs core. This provides a set of function calls; yaffs_open(), yaffs_write() and the like.</p><p class=\"western\">Each function can return numerous error codes and has to handle numerous different parameters.</p><p class=\"western\">Although there were already significant tests for the YDI, an extensive test harness was developed in 2010 to comprehensively test each of the error paths and generate all of the required errors.</p><p class=\"western\">This provides a high level of confidence that the test interfaces do what they should and that POSIX-like functionality provides relatively clean porting of existing code.</p><h3 class=\"western\">Linux Testing</h3><p class=\"western\">The main purpose of the Linux testing is to test the Linux wrapper code. It does, however, still exercise the yaffs core code differently to other testing and thus adds to the test fabric.</p><p class=\"western\">The Linux testing does not do power fail testing but instead tests other aspects such as clean shutdowns, cache integrity and write performance. This gives a useful way to assess the effects of modifications.</p><p class=\"western\">Linux testing is done on both real hardware and on simulated hardware (nandsim).</p><p class=\"western\">Does the term nandsim need explanation?</p><p class=\"western\">As with the Power Fail Stress Testing described above, the simulated testing is done using</p><h3 class=\"western\">Fuzz Testing</h3><p class=\"western\">Fuzz testing deliberately corrupts the flash image and ensures that yaffs still mounts. This is done to ensure that yaffs does not crash on corrupted data.</p><p class=\"western\">Clearly fuzz testing can corrupt the contents of individual files (that\'s its job), but the file system integrity should not be compromised.</p><h3 class=\"western\">Software checking</h3><p class=\"western\">Although code checking is not actual testing per se, it does help to verify code changes.</p><p class=\"western\">The yaffs code has been checked with Coverity<a class=\"sdfootnoteanc\" href=\"#sdfootnote5sym\" name=\"sdfootnote5anc\"><sup>5</sup></a> – a market leader in code checking.</p><p class=\"western\">We are investigating the use of KLEE and other tools.</p><h3 class=\"western\">Open Source Use</h3><p class=\"western\">Open Source use of yaffs opens it up to testing by the many different projects. Many of these participate in some way with the yaffs mailing list, helping to uncover issues and generally provide feedback.</p><p class=\"western\">Each different project uses yaffs in a different way, meaning that a wider range of operation sequences are tested.</p><h2 class=\"western\">Universities</h2><p class=\"western\">Over its lifetime, yaffs has been used as a teaching framework for various university course in many different counties around the world.</p><p class=\"western\">For example, Oregon State University uses Yaffs as a test bench for their post-graduate software testing course. They essentially test the test tools by injecting errors into the yaffs code and seeing if these are discovered. Of course this has the side effect of running these tests over the original Yaffs code too. Those interested in test methods are encouraged to read some of the Oregon State papers</p><p class=\"western\">We expect to adopt and extend some of the Oregon State ideas and use these to extend our in-house test suite.</p><p class=\"western\">Many other examples of academic studies of Yaffs can be found using a standard search engine. Some examples are:-</p><p class=\"western\">Utah State University, School of Computing, used Yaffs as a Case Study in their work on Swarm Testing in 2011.</p><p class=\"western\">Nationa Taiwan University, Dept of Computer Science, published on <i>Effiiciemnt Initilazation and Crash Recovery for Log-based File Systems obver Flash Memory</i><span style=\"font-style: normal\"> in 2006</span></p><h2 class=\"western\">Conclusions</h2><p class=\"western\">Software development is an iterative process of design and testing. Robust software solutions are only possible with extensive testing.</p><p class=\"western\">Embedded systems increasingly need to store data in file systems as a critical part of their operation. It is thus important to have a file system that is predictable and robust to power failure and similar interruptions.</p><p class=\"western\">Yaffs has been designed from scratch to be robust to power failure and that robustness has been verified with a multi-pronged test strategy that is continuously being improved.</p><h3 class=\"western\" style=\"page-break-before: always;\">References</h3><p align=\"LEFT\" class=\"western\">A. Groce et al, “Swarm Testing” from Oregon State University, School of EE and Computer Science and Utah State University, School of Computing, 2011.&nbsp;<a href=\"http://www.ct.utah.edu/%7Eregehr/papers/swarm12.pdf\">http://</a><a href=\"http://www.ct.utah.edu/%7Eregehr/papers/swarm12.pdf\">www.ct.utah.edu/~regehr/papers/swarm12.pdf</a></p><p align=\"LEFT\" class=\"western\"><em>Wu CH, “Efficient Initialization and Crash Recovery</em> for. <em>Log</em>-<em>based File Systems</em> over Flash Memory” from National Taiwan University, Dept of Computer Science, 2006.&nbsp;http://<cite>www.cis.nctu.edu.tw/~lpchang/papers/SAC_wu_sac06.pdf</cite></p><div id=\"sdfootnote1\"><p class=\"sdfootnote-western\"><a class=\"sdfootnotesym\" href=\"#sdfootnote1anc\" name=\"sdfootnote1sym\">1</a>Note that flash translation layers (FTLs) are erroneously refered to as flash file systems. For example, despite the name, M-Systems TrueFFS is not a flash file system but a flash translation layer (FTL).</p></div><div id=\"sdfootnote2\"><p class=\"sdfootnote-western\"><a class=\"sdfootnotesym\" href=\"#sdfootnote2anc\" name=\"sdfootnote2sym\">2</a>This document only provides a brief overview of the yaffs architecture and design. The ” document provides an in-depth explanation of the yaffs design and architecture. [Insert URL]</p></div><div id=\"sdfootnote3\"><p class=\"sdfootnote-western\"><a class=\"sdfootnotesym\" href=\"#sdfootnote3anc\" name=\"sdfootnote3sym\">3</a>Refer to the “How Yaffs Works” document to understand the need for garbage collection and how yaffs does garbage collection.</p></div><div id=\"sdfootnote4\"><p class=\"sdfootnote-western\"><a class=\"sdfootnotesym\" href=\"#sdfootnote4anc\" name=\"sdfootnote4sym\">4</a>For more information on Yaffs Direct Interface, please read the various documents on the subject.</p></div><div id=\"sdfootnote5\"><p class=\"sdfootnote-western\"><a class=\"sdfootnotesym\" href=\"#sdfootnote5anc\" name=\"sdfootnote5sym\">5</a>http://www.coverity.com</p></div><p>&nbsp;</p>','<p class=\"western\">This document describes some of the important design criteria and design features used to achieve a robust design suitable for modern embedded systems which need to store critical data.&nbsp; The test methodologies are also described.</p>','full_html'),('paper',0,420,480,'und',0,'<h2>1 Background</h2><p>Cheaper CPUs and flash have driven up embedded system functionality. These increased functions often require file system storage.</p><p class=\"western\">The original flash file storage mechanisms were the use of a flash translation layer (FTL) – a driver model which makes flash memory appear as a disk drive – in conjunction with a disk-oriented file system such as FAT. This storage methodology has various performance and robustness limitations, leading to the development of file systems designed specifically for flash memory. These are known as Flash File Systems.</p><p class=\"western\">Flash memory has various limitations when compared with a disk. For example, flash memory pages cannot be individually re-written but instead a whole block must be erased and rewritten with the modified page. Typical FTL achieve this with various logical to physical mapping schemes. Thus emulating disk-like behaviour on flash memory adds an extra layer of software. This slows down write performance and adds extra state which is prone to corruption due to power failure.</p><p class=\"western\">The traditional FTL-based solution always stores FA Tables in the same disk blocks. Since flash memory blocks can endure a limited number of write/erasure cycles, the FTL must move the physical location of the block around to prevent the high traffic blocks from wearing out. This requires wear levelling – a further burden.</p><p class=\"western\">Some File Systems, FSs, try to mitigate the performance penalties by caching a lot of data to reduce writes. While this can reduce the apparent write time, it does make the FS prone to data loss in the event of a power failure.</p><p class=\"western\">But flash memory also has advantages when compared to rotating media. There is no spin up time, making it more responsive. There is no read head so there is no read penalty if data is fragmented. Flash FSs can be designed to exploit these advantages.</p><p class=\"western\">A true Flash File System, FFS<a class=\"sdfootnoteanc\" href=\"#sdfootnote1sym\" name=\"sdfootnote1anc\"><sup>1</sup></a> on the other hand is a single code body designed to take the features and limitations of flash into consideration. FFSs can avoid using unsuitable techniques such as allocation tables and in-place rewriting.</p><p class=\"western\">Yaffs is a FFS originally designed specifically for NAND flash, and also used with great success on NOR flash too. Yaffs development started in 2001 when 32Mbytes of flash was considered large. Since then, yaffs has been expanded to work properly with different flash types and far larger memory arrays (many GBytes).</p><p class=\"western\">Yaffs was originally deployed in Linux, but was written in an OS-neutral way to facilitate modular development and testing. This turned out to be convenient when we ported it to other OSs such as WinCE, eCos, pSOS, ThreadX, vXworks</p><p class=\"western\">Since then Yaffs has been used in many application areas including point-of-sale equipment, telecoms equipment (including Android phones), industrial control systems and other, many of them criticially dependent on reliability for their value.</p><h2 class=\"western\">2 Flash File System considerations</h2><p class=\"western\">There are many criteria that are important when selecting a FFS. These are some that out customers have found to be most important:</p><ul><li><p class=\"western\">Robustness: It really is not worth having a file system that loses or corrupts data and prevents the system from working. Some flash file systems are only robust when synced (flushed) after files have been written. That requires extra code, slows the system and leaves the file system in a non-deterministic state until the sync has been completed. Some file systems need to perform disk repair operations (eg. check disk) in the event of a power failure. This can add considerable time to the start up, delaying system operation.</p></li><li><p class=\"western\">Performance: In many embedded system designs, slow read/write performance can delay tasks and cause system degradation or even failure. It is thus important that read/write performance be acceptable. Note that many FFSs need to perform extra actions such as garbage collection. In some cases these actions can cause the file system to stall for a long time. It is thus important that these factors be taken into consideration. Performance can sometimes be improved by adding a write caching layer. These caching layers make the file system calls (write etc) proceed quickly, without actually writing the data to flash. This is risky as data in the cache will be lost on a power failure and syncing the file system will take a long time. Thus, most flash file systems offer either speed or robustness – not both.</p></li><li><p class=\"western\">Proven: It is very easy for a file system vendor to provide a list of claims saying “100% power safe” or similar, but what evidence do they have to back this up? All file systems, including flash file systems, are complex bodies of software with extremely complex state. They need very significant testing to prove that they work correctly.</p></li><li><p class=\"western\">Portable: Software is a huge investment, and it is increasingly important to be able to port the software between OSs and CPU architectures. Most flash file systems are limited to a single OS which makes it difficult to migrate software between different platforms. The portability of yaffs extends to being able to seamlessly migrate the core yaffs code into a test framework (which enhances testing) and being easy to adapt to fresh platforms</p></li></ul><h2 class=\"western\" style=\"page-break-before: always;\">3 How YAFFS achieves robustness and performance</h2><p class=\"western\">Yaffs was designed from the ground up specifically to work well with NAND flash. The author had already developed another FFS and was familiar with the design challenges of flash.</p><p class=\"western\">Yaffs is not just a disk-oriented FS adapted to work with flash, so it is not surprising that yaffs is very different in design to most other file systems. The key difference is that yaffs is a log-structured file system<a class=\"sdfootnoteanc\" href=\"#sdfootnote2sym\" name=\"sdfootnote2anc\"><sup>2</sup></a>.</p><p class=\"western\">In essence, a log structured file system writes file system changes as a sequential log. The log structure is particularly suitable because:</p><ul><li><p class=\"western\">All writes are at the end of the log. When a file is modified, there is no need to erase and rewrite a part of the flash. Changes are just appended to the log. Thus there is no need to erase and copy old data just to change some existing pages in a file. This tends to make writes much faster. There is no need to do a lot of caching to achieve performance. Data can be written to the log immediately meaning that sync time is very low. Data robustness is improved dramatically.</p></li><li><p class=\"western\">There are no allocation tables; this reduces the amount of data being written to the flash, and there are no tables to corrupt.</p></li><li><p class=\"western\">Since all writes are to the end of the log there are no “high traffic” blocks. This means yaffs only needs a simple wear levelling strategy.</p></li><li><p class=\"western\">In the event of a power failure, the file system state is easily re-created from the log. This means there is no need to perform disk repair operations to correct for a bad shutdown.</p></li></ul><p class=\"western\">So why don\'t we see many log structured file systems for disk file systems? The answer is that log file systems tend to spread the writes around on the media. That is typically very problematic for mechanical storage which must physically move the read/write head from one location to another making the access time very slow. Of course that does not apply for flash memory. By designing specifically for flash, yaffs can write fast.</p><p class=\"western\">Many FFSs need to compromise robustness and performance. Thanks to the log structure, yaffs does not need to; it can provide high performance without giving up on robustness.</p><p class=\"western\">Those familiar with log structured file system design will know that some log structured file systems have problems with garbage collection, GC<a class=\"sdfootnoteanc\" href=\"#sdfootnote3sym\" name=\"sdfootnote3anc\"><sup>3</sup></a>. Garbage collection cleans up the log and makes more free space available. Some log-structured file system designs did not pay enough attention to GC and can stall for a considerable time while it happens. Yaffs was designed differently. The potential impact of GC was considered throughout the design process. As a result, yaffs has a very simple GC model that allows a lot of flexibility in scheduling. This prevents the GC from making the file system slow and unresponsive.</p><p class=\"western\">Most file systems are developed within the context and framework of a single OS. This typically makes the code difficult to explore, debug and port. Yaffs on the other hand was developed from the start inside a portable development/testing framework. Yaffs is then ported to various operating systems through the addition of glue code.</p><p class=\"western\">[ibimage==236==original==none==self==null]</p><p class=\"western\">There are many benefits to this approach:</p><ul><li><p class=\"western\">A development framework runs in user space which provides a richer development environment than inside an OS kernel. It is much easier to attach debuggers and perform logging and create reproducible testing.</p></li><li><p class=\"western\">The code is structured to be portable. That makes it relatively easy to port to a new OS or RTOS with a high level of confidence.</p></li><li><p class=\"western\">There is a choice of porting interfaces allowing more flexibility to determine which porting method will be simpler. For example, the Linux wrapper accesses the yaffs core directly while the Windows CE wrapper access the Yaffs Direct Interface<a class=\"sdfootnoteanc\" href=\"#sdfootnote4sym\" name=\"sdfootnote4anc\"><sup>4</sup></a>.</p></li><li><p class=\"western\">Each different environment provides different test tools. For example, Linux provides a raft of file system test tools that do different kinds of testing to the power fail test harness. Since the vast majority of the code is in the portable yaffs core, that code gets the advantage of all test methods combined. The many millions of Android phone users that use yaffs-based devices are helping test the core code that is also used on a wide variety of different operating systems and a wide range of different device types.</p></li><li><p class=\"western\">Its Open Source status means any interested parson can take a version from git and test it to make sure it meets their needs.</p></li></ul><h2 class=\"western\" style=\"page-break-before: always;\">4 Testing</h2><p class=\"western\">It is all very well to design software to be robust, but it needs thorough testing to build the confidence of users in the author and the supplier.</p><p class=\"western\">File systems have incredibly complex state so it is not at all surprising that OS designers find FSs some of the most challenging code to test.</p><p class=\"western\">There is no single test methodology that can test all cases, and exhaustive state testing is impossible. The best we can do is to have a suite of test methodologies that combine to provide thorough testing.</p><p class=\"western\">Approximately 60% of yaffs development effort is now directed towards testing and improving the test environment. We are constantly researching new methodologies.</p><p class=\"western\">The following are descriptions of the most important test strategies used in yaffs.</p><h3 class=\"western\">Power Fail Stress Testing</h3><p class=\"western\">By far the most important consideration in yaffs testing is that it is robust to corruption caused by power failure. We want yaffs to provide the basis for reliable products in typical embedded systems.</p><p class=\"western\">The first power fail testing was done by companies integrating yaffs into their products. Some of these built test jigs which would automatically interrupt power while running a real hardware device. This approach is better than nothing, but has some limitations:</p><ul><li><p class=\"western\">It is relatively costly to set up. Flash has a limited lifetime meaning that test devices wear out with time and must be replaced.</p></li><li><p class=\"western\">It is relatively slow since each cycle takes many seconds to boot, run the application for a while and then reboot.</p></li><li><p class=\"western\">Many, and perhaps most, of the power interruptions will happen at times when the file system is inactive and thus be wasted cycles.</p></li></ul><p class=\"western\">In 2008 we developed a power-fail-test environment. This simulates power failures using simulated flash memory while running various consistency checks.</p><p class=\"western\">The benefits of a software-based test harness are numerous:</p><ul><li><p class=\"western\">The test harness controls the point at which the simulated power failures happen. That means every test cycle counts.</p></li><li><p class=\"western\">No special hardware is required.</p></li><li><p class=\"western\">Test loops run faster; a quad-core computer can simulate ten to twenty power failures per second. That means about a million power failure simulations per day.</p></li></ul><p class=\"western\">The effectiveness of the new software-based testing is dramatic.&nbsp; A few times we have tested some user-suggested changes that had passed a week or more of real-world power fail testing only to have problems caught by the software simulation in a matter of minutes.</p><p class=\"western\">We regularly run the power fail simulation test over a weekend, testing millions of power fail cycles.</p><h3 class=\"western\">Testing the Yaffs Direct Interface API</h3><p class=\"western\">Yaffs Direct Interface (YDI) is a POSIX-like wrapper around the yaffs core. This provides a set of function calls; yaffs_open(), yaffs_write() and the like.</p><p class=\"western\">Each function can return numerous error codes and has to handle numerous different parameters.</p><p class=\"western\">Although there were already significant tests for the YDI, an extensive test harness was developed in 2010 to comprehensively test <strong>each</strong> of the error paths and generate all of the required errors.</p><p class=\"western\">This provides a high level of confidence that the test interfaces do what they should and that POSIX-like functionality provides relatively clean porting of existing code.</p><h3 class=\"western\">Linux Testing</h3><p class=\"western\">The main purpose of the Linux testing is to test the Linux wrapper code. It does, however, still exercise the yaffs core code in different ways from other testing, and thus adds to the strength of the test fabric.</p><p class=\"western\">The Linux testing does not do power fail testing but instead tests other aspects such as clean shutdowns, cache integrity and write performance. This gives a useful way to assess the effects of modifications.</p><p class=\"western\">Linux testing is done on both real hardware and on simulated hardware (nandsim).</p><p class=\"western\">As with the Power Fail Stress Testing described above, the simulated testing is done using:</p><h3 class=\"western\">Fuzz Testing</h3><p class=\"western\">Fuzz testing deliberately corrupts the flash image and ensures that yaffs still mounts. This is done to ensure that yaffs does not crash on corrupted data.</p><p class=\"western\">Clearly fuzz testing can corrupt the contents of individual files (that\'s its job), but the file system integrity should not be compromised.</p><h3 class=\"western\">Software checking</h3><p class=\"western\">Although code checking is not actual testing per se, it does help to verify code changes.</p><p class=\"western\">The yaffs code has been checked with Coverity<a class=\"sdfootnoteanc\" href=\"#sdfootnote5sym\" name=\"sdfootnote5anc\"><sup>5</sup></a> – a market leader in code checking.</p><p class=\"western\">We are investigating the use of KLEE and other tools.</p><h3 class=\"western\">Open Source Use</h3><p>Each different project uses yaffs in a different way, so that collectively a wider range of operation sequences are tested.</p><p class=\"western\">&nbsp;Many of these users participate in some way on the yaffs mailing list, helping to uncover issues and generally provide feedback.</p><h2 class=\"western\">5 Universities</h2><p class=\"western\">Over its lifetime, yaffs has been used as a teaching framework for various university course in many counties around the world.</p><p class=\"western\">For example, Oregon State University uses Yaffs as a test bench for their post-graduate software testing course. They essentially test the test tools by injecting errors into the yaffs code and seeing if these are discovered. Of course this has the side effect of running these tests over the original Yaffs code too. Those interested in test methods are encouraged to read some of the OSU papers</p><p class=\"western\">We expect to adopt and extend some of the OSU ideas and use these to extend our in-house test suite.</p><p class=\"western\">Many other examples of academic studies of Yaffs can be found using a standard search engine. Some examples are:-</p><p class=\"western\">Utah State University, School of Computing, used Yaffs as a Case Study in their work on Swarm Testing in 2011.&nbsp; www.cs.utah.edu/~regehr/papers/swarm12.pdf</p><p class=\"western\">National Taiwan University, Dept of Computer Science, published on <i>Effiicient Initialization and Crash Recovery for Log-based File Systems Over Flash Memory</i><span style=\"font-style: normal\">&nbsp;</span> Copyright 2006 ACM 1-59593-108-2/06/0004&nbsp; and http://www.cis.nctu.edu.tw/~lpchang/papers/SAC_wu_sac06.pdf</p><p class=\"western\">DeDupe in YAFFS, K Narayan &amp; P S Vijayakrishnan, Comp Sci, U Wisconsin.&nbsp; http://pages.cs.wisc.edu/~knarayan/dedup-yaffs.pdf&nbsp; (2011)<br>&nbsp;</p><h2 class=\"western\">6 Conclusions</h2><p class=\"western\">Software development is an iterative process of design and testing. Robust software solutions are only possible with extensive testing.</p><p class=\"western\">Embedded systems increasingly need to store data in file systems as a critical part of their operation. It is thus imperative to have a file system that is predictable and robust to power failure and similar interruptions.</p><p class=\"western\">Yaffs has been designed from scratch to be robust to power failure and that robustness has been verified with a multi-pronged test strategy that is continuously being improved.</p><h3 class=\"western\" style=\"page-break-before: always;\">References</h3><div id=\"sdfootnote1\"><p class=\"sdfootnote-western\"><a class=\"sdfootnotesym\" href=\"#sdfootnote1anc\" name=\"sdfootnote1sym\">1</a>Note that flash translation layers (FTLs) are erroneously referred to as flash file systems. For example, despite the name, M-Systems TrueFFS is not a flash file system but a flash translation layer (FTL).</p></div><div id=\"sdfootnote2\"><p class=\"sdfootnote-western\"><a class=\"sdfootnotesym\" href=\"#sdfootnote2anc\" name=\"sdfootnote2sym\">2</a>This document only provides a brief overview of the yaffs architecture and design.&nbsp; For more details of the yaffs design and architecture see&nbsp; <a href=\"http://yaffs.net/documents/how-yaffs-works\">http://yaffs.net/documents/how-yaffs-works</a></p></div><div id=\"sdfootnote3\"><p class=\"sdfootnote-western\"><a class=\"sdfootnotesym\" href=\"#sdfootnote3anc\" name=\"sdfootnote3sym\">3</a>Refer to the “How Yaffs Works” document to understand the need for garbage collection and how yaffs does it.</p></div><div id=\"sdfootnote4\"><p class=\"sdfootnote-western\"><a class=\"sdfootnotesym\" href=\"#sdfootnote4anc\" name=\"sdfootnote4sym\">4</a>For more information on Yaffs Direct Interface, please&nbsp; see <a href=\"http://yaffs.net/documents\">http://yaffs.net/documents/yaffs-direct-interface </a></p></div><div id=\"sdfootnote5\"><p class=\"sdfootnote-western\"><a class=\"sdfootnotesym\" href=\"#sdfootnote5anc\" name=\"sdfootnote5sym\">5</a>http://www.coverity.com</p></div><p>&nbsp;</p>','<p>This document describes some of the important design criteria and design features used to achieve a robust design suitable for modern embedded systems which need to store critical data.&nbsp; The test methodologies are also described.</p>','full_html'),('paper',0,420,532,'und',0,'<h2>1 Background</h2><p>Cheaper CPUs and flash have driven up embedded system functionality. These increased functions often require file system storage.</p><p class=\"western\">The original flash file storage mechanisms were the use of a flash translation layer (FTL) – a driver model which makes flash memory appear as a disk drive – in conjunction with a disk-oriented file system such as FAT. This storage methodology has various performance and robustness limitations, leading to the development of file systems designed specifically for flash memory. These are known as Flash File Systems.</p><p class=\"western\">Flash memory has various limitations when compared with a disk. For example, flash memory pages cannot be individually re-written but instead a whole block must be erased and rewritten with the modified page. Typical FTL achieve this with various logical to physical mapping schemes. Thus emulating disk-like behaviour on flash memory adds an extra layer of software. This slows down write performance and adds extra state which is prone to corruption due to power failure.</p><p class=\"western\">The traditional FTL-based solution always stores FA Tables in the same disk blocks. Since flash memory blocks can endure a limited number of write/erasure cycles, the FTL must move the physical location of the block around to prevent the high traffic blocks from wearing out. This requires wear levelling – a further burden.</p><p class=\"western\">Some File Systems, FSs, try to mitigate the performance penalties by caching a lot of data to reduce writes. While this can reduce the apparent write time, it does make the FS prone to data loss in the event of a power failure.</p><p class=\"western\">But flash memory also has advantages when compared to rotating media. There is no spin up time, making it more responsive. There is no read head so there is no read penalty if data is fragmented. Flash FSs can be designed to exploit these advantages.</p><p class=\"western\">A true Flash File System, FFS<a class=\"sdfootnoteanc\" href=\"#sdfootnote1sym\" name=\"sdfootnote1anc\"><sup>1</sup></a> on the other hand is a single code body designed to take the features and limitations of flash into consideration. FFSs can avoid using unsuitable techniques such as allocation tables and in-place rewriting.</p><p class=\"western\">Yaffs is a FFS originally designed specifically for NAND flash, and also used with great success on NOR flash too. Yaffs development started in 2001 when 32Mbytes of flash was considered large. Since then, yaffs has been expanded to work properly with different flash types and far larger memory arrays (many GBytes).</p><p class=\"western\">Yaffs was originally deployed in Linux, but was written in an OS-neutral way to facilitate modular development and testing. This turned out to be convenient when we ported it to other OSs such as WinCE, eCos, pSOS, ThreadX, vXworks</p><p class=\"western\">Since then Yaffs has been used in many application areas including point-of-sale equipment, telecoms equipment (including Android phones), industrial control systems and other, many of them criticially dependent on reliability for their value.</p><h2 class=\"western\">2 Flash File System considerations</h2><p class=\"western\">There are many criteria that are important when selecting a FFS. These are some that out customers have found to be most important:</p><ul><li><p class=\"western\">Robustness: It really is not worth having a file system that loses or corrupts data and prevents the system from working. Some flash file systems are only robust when synced (flushed) after files have been written. That requires extra code, slows the system and leaves the file system in a non-deterministic state until the sync has been completed. Some file systems need to perform disk repair operations (eg. check disk) in the event of a power failure. This can add considerable time to the start up, delaying system operation.</p></li><li><p class=\"western\">Performance: In many embedded system designs, slow read/write performance can delay tasks and cause system degradation or even failure. It is thus important that read/write performance be acceptable. Note that many FFSs need to perform extra actions such as garbage collection. In some cases these actions can cause the file system to stall for a long time. It is thus important that these factors be taken into consideration. Performance can sometimes be improved by adding a write caching layer. These caching layers make the file system calls (write etc) proceed quickly, without actually writing the data to flash. This is risky as data in the cache will be lost on a power failure and syncing the file system will take a long time. Thus, most flash file systems offer either speed or robustness – not both.</p></li><li><p class=\"western\">Proven: It is very easy for a file system vendor to provide a list of claims saying “100% power safe” or similar, but what evidence do they have to back this up? All file systems, including flash file systems, are complex bodies of software with extremely complex state. They need very significant testing to prove that they work correctly.</p></li><li><p class=\"western\">Portable: Software is a huge investment, and it is increasingly important to be able to port the software between OSs and CPU architectures. Most flash file systems are limited to a single OS which makes it difficult to migrate software between different platforms. The portability of yaffs extends to being able to seamlessly migrate the core yaffs code into a test framework (which enhances testing) and being easy to adapt to fresh platforms</p></li></ul><h2 class=\"western\" style=\"page-break-before: always;\">3 How YAFFS achieves robustness and performance</h2><p class=\"western\">Yaffs was designed from the ground up specifically to work well with NAND flash. The author had already developed another FFS and was familiar with the design challenges of flash.</p><p class=\"western\">Yaffs is not just a disk-oriented FS adapted to work with flash, so it is not surprising that yaffs is very different in design to most other file systems. The key difference is that yaffs is a log-structured file system<a class=\"sdfootnoteanc\" href=\"#sdfootnote2sym\" name=\"sdfootnote2anc\"><sup>2</sup></a>.</p><p class=\"western\">In essence, a log structured file system writes file system changes as a sequential log. The log structure is particularly suitable because:</p><ul><li><p class=\"western\">All writes are at the end of the log. When a file is modified, there is no need to erase and rewrite a part of the flash. Changes are just appended to the log. Thus there is no need to erase and copy old data just to change some existing pages in a file. This tends to make writes much faster. There is no need to do a lot of caching to achieve performance. Data can be written to the log immediately meaning that sync time is very low. Data robustness is improved dramatically.</p></li><li><p class=\"western\">There are no allocation tables; this reduces the amount of data being written to the flash, and there are no tables to corrupt.</p></li><li><p class=\"western\">Since all writes are to the end of the log there are no “high traffic” blocks. This means yaffs only needs a simple wear levelling strategy.</p></li><li><p class=\"western\">In the event of a power failure, the file system state is easily re-created from the log. This means there is no need to perform disk repair operations to correct for a bad shutdown.</p></li></ul><p class=\"western\">So why don\'t we see many log structured file systems for disk file systems? The answer is that log file systems tend to spread the writes around on the media. That is typically very problematic for mechanical storage which must physically move the read/write head from one location to another making the access time very slow. Of course that does not apply for flash memory. By designing specifically for flash, yaffs can write fast.</p><p class=\"western\">Many FFSs need to compromise robustness and performance. Thanks to the log structure, yaffs does not need to; it can provide high performance without giving up on robustness.</p><p class=\"western\">Those familiar with log structured file system design will know that some log structured file systems have problems with garbage collection, GC<a class=\"sdfootnoteanc\" href=\"#sdfootnote3sym\" name=\"sdfootnote3anc\"><sup>3</sup></a>. Garbage collection cleans up the log and makes more free space available. Some log-structured file system designs did not pay enough attention to GC and can stall for a considerable time while it happens. Yaffs was designed differently. The potential impact of GC was considered throughout the design process. As a result, yaffs has a very simple GC model that allows a lot of flexibility in scheduling. This prevents the GC from making the file system slow and unresponsive.</p><p class=\"western\">Most file systems are developed within the context and framework of a single OS. This typically makes the code difficult to explore, debug and port. Yaffs on the other hand was developed from the start inside a portable development/testing framework. Yaffs is then ported to various operating systems through the addition of glue code.</p><p class=\"western\">[ibimage==236==original==none==self==null]</p><p class=\"western\">There are many benefits to this approach:</p><ul><li><p class=\"western\">A development framework runs in user space which provides a richer development environment than inside an OS kernel. It is much easier to attach debuggers and perform logging and create reproducible testing.</p></li><li><p class=\"western\">The code is structured to be portable. That makes it relatively easy to port to a new OS or RTOS with a high level of confidence.</p></li><li><p class=\"western\">There is a choice of porting interfaces allowing more flexibility to determine which porting method will be simpler. For example, the Linux wrapper accesses the yaffs core directly while the Windows CE wrapper access the Yaffs Direct Interface<a class=\"sdfootnoteanc\" href=\"#sdfootnote4sym\" name=\"sdfootnote4anc\"><sup>4</sup></a>.</p></li><li><p class=\"western\">Each different environment provides different test tools. For example, Linux provides a raft of file system test tools that do different kinds of testing to the power fail test harness. Since the vast majority of the code is in the portable yaffs core, that code gets the advantage of all test methods combined. The many millions of Android phone users that use yaffs-based devices are helping test the core code that is also used on a wide variety of different operating systems and a wide range of different device types.</p></li><li><p class=\"western\">Its Open Source status means any interested parson can take a version from git and test it to make sure it meets their needs.</p></li></ul><h2 class=\"western\" style=\"page-break-before: always;\">4 Testing</h2><p class=\"western\">It is all very well to design software to be robust, but it needs thorough testing to build the confidence of users in the author and the supplier.</p><p class=\"western\">File systems have incredibly complex state so it is not at all surprising that OS designers find FSs some of the most challenging code to test.</p><p class=\"western\">There is no single test methodology that can test all cases, and exhaustive state testing is impossible. The best we can do is to have a suite of test methodologies that combine to provide thorough testing.</p><p class=\"western\">Approximately 60% of yaffs development effort is now directed towards testing and improving the test environment. We are constantly researching new methodologies.</p><p class=\"western\">The following are descriptions of the most important test strategies used in yaffs.</p><h3 class=\"western\">Power Fail Stress Testing</h3><p class=\"western\">By far the most important consideration in yaffs testing is that it is robust to corruption caused by power failure. We want yaffs to provide the basis for reliable products in typical embedded systems.</p><p class=\"western\">The first power fail testing was done by companies integrating yaffs into their products. Some of these built test jigs which would automatically interrupt power while running a real hardware device. This approach is better than nothing, but has some limitations:</p><ul><li><p class=\"western\">It is relatively costly to set up. Flash has a limited lifetime meaning that test devices wear out with time and must be replaced.</p></li><li><p class=\"western\">It is relatively slow since each cycle takes many seconds to boot, run the application for a while and then reboot.</p></li><li><p class=\"western\">Many, and perhaps most, of the power interruptions will happen at times when the file system is inactive and thus be wasted cycles.</p></li></ul><p class=\"western\">In 2008 we developed a power-fail-test environment. This simulates power failures using simulated flash memory while running various consistency checks.</p><p class=\"western\">The benefits of a software-based test harness are numerous:</p><ul><li><p class=\"western\">The test harness controls the point at which the simulated power failures happen. That means every test cycle counts.</p></li><li><p class=\"western\">No special hardware is required.</p></li><li><p class=\"western\">Test loops run faster; a quad-core computer can simulate ten to twenty power failures per second. That means about a million power failure simulations per day.</p></li></ul><p class=\"western\">The effectiveness of the new software-based testing is dramatic.&nbsp; A few times we have tested some user-suggested changes that had passed a week or more of real-world power fail testing only to have problems caught by the software simulation in a matter of minutes.</p><p class=\"western\">We regularly run the power fail simulation test over a weekend, testing millions of power fail cycles.</p><h3 class=\"western\">Testing the Yaffs Direct Interface API</h3><p class=\"western\">Yaffs Direct Interface (YDI) is a POSIX-like wrapper around the yaffs core. This provides a set of function calls; yaffs_open(), yaffs_write() and the like.</p><p class=\"western\">Each function can return numerous error codes and has to handle numerous different parameters.</p><p class=\"western\">Although there were already significant tests for the YDI, an extensive test harness was developed in 2010 to comprehensively test <strong>each</strong> of the error paths and generate all of the required errors.</p><p class=\"western\">This provides a high level of confidence that the test interfaces do what they should and that POSIX-like functionality provides relatively clean porting of existing code.</p><h3 class=\"western\">Linux Testing</h3><p class=\"western\">The main purpose of the Linux testing is to test the Linux wrapper code. It does, however, still exercise the yaffs core code in different ways from other testing, and thus adds to the strength of the test fabric.</p><p class=\"western\">The Linux testing does not do power fail testing but instead tests other aspects such as clean shutdowns, cache integrity and write performance. This gives a useful way to assess the effects of modifications.</p><p class=\"western\">Linux testing is done on both real hardware and on simulated hardware (nandsim).</p><p class=\"western\">As with the Power Fail Stress Testing described above, the simulated testing is done using:</p><h3 class=\"western\">Fuzz Testing</h3><p class=\"western\">Fuzz testing deliberately corrupts the flash image and ensures that yaffs still mounts. This is done to ensure that yaffs does not crash on corrupted data.</p><p class=\"western\">Clearly fuzz testing can corrupt the contents of individual files (that\'s its job), but the file system integrity should not be compromised.</p><h3 class=\"western\">Software checking</h3><p class=\"western\">Although code checking is not actual testing per se, it does help to verify code changes.</p><p class=\"western\">The yaffs code has been checked with Coverity<a class=\"sdfootnoteanc\" href=\"#sdfootnote5sym\" name=\"sdfootnote5anc\"><sup>5</sup></a> – a market leader in code checking.</p><p class=\"western\">We are investigating the use of KLEE and other tools.</p><h3 class=\"western\">Open Source Use</h3><p>Each different project uses yaffs in a different way, so that collectively a wider range of operation sequences are tested.</p><p class=\"western\">&nbsp;Many of these users participate in some way on the yaffs mailing list, helping to uncover issues and generally provide feedback.</p><h2 class=\"western\">5 Universities</h2><p class=\"western\">Over its lifetime, yaffs has been used as a teaching framework for various university course in many counties around the world.</p><p class=\"western\">For example, Oregon State University uses Yaffs as a test bench for their post-graduate software testing course. They essentially test the test tools by injecting errors into the yaffs code and seeing if these are discovered. Of course this has the side effect of running these tests over the original Yaffs code too. Those interested in test methods are encouraged to read some of the OSU papers</p><p class=\"western\">We expect to adopt and extend some of the OSU ideas and use these to extend our in-house test suite.</p><p class=\"western\">Many other examples of academic studies of Yaffs can be found using a standard search engine. Some examples are:-</p><p class=\"western\">Utah State University, School of Computing, used Yaffs as a Case Study in their work on Swarm Testing in 2011.&nbsp; www.cs.utah.edu/~regehr/papers/swarm12.pdf</p><p class=\"western\">National Taiwan University, Dept of Computer Science, published on <i>Effiicient Initialization and Crash Recovery for Log-based File Systems Over Flash Memory</i><span style=\"font-style: normal\">&nbsp;</span> Copyright 2006 ACM 1-59593-108-2/06/0004&nbsp; and http://www.cis.nctu.edu.tw/~lpchang/papers/SAC_wu_sac06.pdf</p><p class=\"western\">DeDupe in YAFFS, K Narayan &amp; P S Vijayakrishnan, Comp Sci, U Wisconsin.&nbsp; http://pages.cs.wisc.edu/~knarayan/dedup-yaffs.pdf&nbsp; (2011)<br>&nbsp;</p><h2 class=\"western\">6 Conclusions</h2><p class=\"western\">Software development is an iterative process of design and testing. Robust software solutions are only possible with extensive testing.</p><p class=\"western\">Embedded systems increasingly need to store data in file systems as a critical part of their operation. It is thus imperative to have a file system that is predictable and robust to power failure and similar interruptions.</p><p class=\"western\">Yaffs has been designed from scratch to be robust to power failure and that robustness has been verified with a multi-pronged test strategy that is continuously being improved.</p><h3 class=\"western\" style=\"page-break-before: always;\">References</h3><div id=\"sdfootnote1\"><p class=\"sdfootnote-western\"><a class=\"sdfootnotesym\" href=\"#sdfootnote1anc\" name=\"sdfootnote1sym\">1</a>Note that flash translation layers (FTLs) are erroneously referred to as flash file systems. For example, despite the name, M-Systems TrueFFS is not a flash file system but a flash translation layer (FTL).</p></div><div id=\"sdfootnote2\"><p class=\"sdfootnote-western\"><a class=\"sdfootnotesym\" href=\"#sdfootnote2anc\" name=\"sdfootnote2sym\">2</a>This document only provides a brief overview of the yaffs architecture and design.&nbsp; For more details of the yaffs design and architecture see&nbsp; <a href=\"http://yaffs.net/documents/how-yaffs-works\">http://yaffs.net/documents/how-yaffs-works</a></p></div><div id=\"sdfootnote3\"><p class=\"sdfootnote-western\"><a class=\"sdfootnotesym\" href=\"#sdfootnote3anc\" name=\"sdfootnote3sym\">3</a>Refer to the “How Yaffs Works” document to understand the need for garbage collection and how yaffs does it.</p></div><div id=\"sdfootnote4\"><p class=\"sdfootnote-western\"><a class=\"sdfootnotesym\" href=\"#sdfootnote4anc\" name=\"sdfootnote4sym\">4</a>For more information on Yaffs Direct Interface, please&nbsp; see <a href=\"http://yaffs.net/documents\">http://yaffs.net/documents/yaffs-direct-interface </a></p></div><div id=\"sdfootnote5\"><p class=\"sdfootnote-western\"><a class=\"sdfootnotesym\" href=\"#sdfootnote5anc\" name=\"sdfootnote5sym\">5</a>http://www.coverity.com</p></div><p>&nbsp;</p>','<p>This document describes some of the important design criteria and design features used to achieve a robust design suitable for modern embedded systems which need to store critical data.&nbsp; The test methodologies are also described.</p>','full_html'),('paper',0,420,603,'und',0,'\r\n\r\n	<p class=\"western\">Many embedded systems need to store critical\r\n	data, making reliable file systems an important part of modern\r\n	embedded system design. That robustness is not achieved through\r\n	chance. Robustness is only achieved through design and extensive\r\n	testing to verify that the file system functions correctly and is\r\n	resistant to power failure.</p>\r\n	<p class=\"western\">This document describes some of the important\r\n	design criteria and design features used to achieve a robust design.</p>\r\n	\r\n<p class=\"western\" style=\"page-break-before: always\"><h1 class=\"western\">1 Background</h1>\r\n<p class=\"western\">Cheaper CPUs and flash have driven up embedded\r\nsystem functionality. These increased functions often require file\r\nsystem storage.</p>\r\n<p class=\"western\">The original flash file storage mechanisms were\r\nthe use of a flash translation layer (FTL) – a driver model which\r\nmakes flash memory appear as a disk drive – in conjunction with a\r\ndisk-oriented file system such as FAT. This storage methodology has\r\nvarious performance and robustness limitations, leading to the\r\ndevelopment of file systems designed specifically for flash memory.\r\nThese are known as flash file systems.</p>\r\n<p class=\"western\">Flash memory has various limitations when compared\r\nwith a disk. For example, flash memory pages cannot be individually\r\nre-written but instead the whole block must be  erased and rewritten\r\nwith the modified page. Typical FTL achieve this with various logical\r\nto physical mapping schemes. Thus emulating disk-like behaviour on\r\nflash memory adds an extra layer of software which slows down write\r\nperformance. Worse still, it adds extra state which is prone to\r\ncorruption due to power failure.</p>\r\n<p class=\"western\">A typical FTL-based solution will use a file\r\nsystem such as FAT. FAT always stores tables in the same disk blocks\r\nand must thus change the same blocks often. Since flash memory blocks\r\ncan endure a limited number of write/erasure cycles, the FTL must\r\nmove the physical location of the block around to prevent  the high\r\ntraffic blocks from wearing out. This requires wear levelling – a\r\nfurther burden.</p>\r\n<p class=\"western\">Some systems try to mitigate against the\r\nperformance penalties by caching a lot of data to reduce writes.\r\nWhile this can go some way towards reducing the apparent write time,\r\nit does make the solution prone to data loss in the event of a power\r\nfailure.</p>\r\n<p class=\"western\">As well as limitations, flash memory also has\r\ncertain advantages when compared to rotating media. There is no spin\r\nup time, making it more responsive. There is no read head so there is\r\nno read penalty if data is fragmented. Flash file systems can be\r\ndesigned to exploit these advantages.</p>\r\n<p class=\"western\">True flash file systems<a class=\"sdfootnoteanc\" name=\"sdfootnote1anc\" href=\"#sdfootnote1sym\"><sup>1</sup></a>,\r\non the other hand, are a single code body designed to take the\r\nfeatures and limitations of flash into consideration. Flash file\r\nsystems can thus be far more “flash friendly”. Well designed\r\nflash file systems will avoid using “flash unfriendly” techniques\r\nsuch as allocation tables and in-place rewriting.</p>\r\n<p class=\"western\">Yaffs is a flash file system, originally designed\r\nspecifically for NAND flash though also used with great success on\r\nNOR flash too. Yaffs development started in 2001 when 32Mbytes of\r\nflash was considered large. Since then, Yaffs has been expanded to\r\nwork properly with different flash types and far larger memory arrays\r\n(many GBytes).</p>\r\n<p class=\"western\">Yaffs was originally deployed in Linux, but was\r\nwritten in an OS neutral way, mainly to facilitate modular\r\ndevelopment and testing. This turned out to be useful when we had\r\nrequests to port Yaffs to other operating systems. Since then, Yaffs\r\nhas been used in many different products in a wide variety of\r\napplications from consumer products such as cell phones and sewing\r\nmachines to aerospace, industrial and medical applications including\r\nprocess control, building management, communications infrastructure\r\nand many others.</p>\r\n<p class=\"western\">Yaffs is not tied to any endian ordering and has\r\nbeen used on a wide variety of architectures including ARM, MIPS,\r\nPowerPC, x86, some DSPs. Yaffs has been deployed using a wide variety\r\nof compilers from many different vendors.</p>\r\n<p class=\"western\">Nor is Yaffs tied to any particular operating\r\nsystem. Yaffs has been used with Linux, eCOS, Windows Embedded\r\nCompact (previously Windows CE), VxWorks and others.</p>\r\n<h1 class=\"western\">2 Flash File System considerations</h1>\r\n<p class=\"western\">There are many criteria that are important when\r\nselecting a flash file system. These are some that out customers have\r\nfound to be most important:</p>\r\n<ul>\r\n	<li/>\r\n<p class=\"western\">Robustness: It really is not worth having a\r\n	file system that loses or corrupts data and prevents the system from\r\n	working properly. Some flash file systems are only robust when\r\n	synced (flushed) after files have been written. That requires extra\r\n	code, slows the system and leaves the file system in a\r\n	non-deterministic state until the sync has been completed. Some file\r\n	systems need to perform disk repair operations (eg. check disk) in\r\n	the event of a power failure. This can add considerable time to the\r\n	start up, preventing the system from being operational.</p>\r\n	<li/>\r\n<p class=\"western\">Performance: In many embedded system\r\n	designs, slow read/write performance can delay tasks and cause\r\n	system degradation or even failure. It is thus important that\r\n	read/write performance be acceptable. Note that many flash file\r\n	systems need to perform extra actions such as garbage collection. In\r\n	some cases these actions can cause the file system to stall for a\r\n	long time. It is thus important that these factors be taken into\r\n	consideration. Performance can sometimes be improved by adding a\r\n	write caching layer. These caching layers make the file system calls\r\n	(write etc) proceed quickly, without actually writing the data to\r\n	flash. This is a two-edged sword as data in the cache will be lost\r\n	on a power failure and syncing the file system will take a long\r\n	time. Thus, most flash file systems offer either speed or robustness\r\n	– not both.</p>\r\n	<li/>\r\n<p class=\"western\">Proven: It is very easy for a file system\r\n	vendor to provide a list of claims saying “100% power safe” or\r\n	similar, but what evidence do they have to back this up? All file\r\n	systems, including flash file systems, are complex bodies of\r\n	software with extremely complex state. They need very significant\r\n	testing to prove that they work correctly.</p>\r\n	<li/>\r\n<p class=\"western\">Portable: Software is a huge investment and\r\n	it is increasingly important to be able to port the software between\r\n	OSs and CPU architectures. Most flash file systems are limited to a\r\n	single operating system which makes it difficult to migrate software\r\n	between different platforms. In Yaffs\' case portability extends to\r\n	being able to seamlessly migrate the core Yaffs code into a test\r\n	framework which enhances testing.</p>\r\n</ul>\r\n<h1 class=\"western\">3 How Yaffs achieves robustness and performance</h1>\r\n<p class=\"western\">Yaffs was designed from the ground up specifically\r\nto work well with NAND flash. The author had already developed\r\nanother flash file system, so was already familiar with the  design\r\nchallenges of flash.</p>\r\n<p class=\"western\">As Yaffs is not just adapting a disk-oriented file\r\nsystem to work with flash it is not surprising that Yaffs is very\r\ndifferent in design to most other file systems. The key difference is\r\nthat Yaffs is a log-structured. file system<a class=\"sdfootnoteanc\" name=\"sdfootnote2anc\" href=\"#sdfootnote2sym\"><sup>2</sup></a>.</p>\r\n<p class=\"western\">In essence, a log structured file system writes\r\nfile system changes as a sequential log.  The log structure is\r\nparticularly suitable for various reasons including:</p>\r\n<ul>\r\n	<li/>\r\n<p class=\"western\">All writes are at the end of the log. When\r\n	a file is modified, there is no need to erase and rewrite a part of\r\n	the flash. Changes are just appended to the log. Thus there is no\r\n	need to erase and copy old data just to change some existing pages\r\n	in a file. This tends to make writes much faster. There is no need\r\n	to do a lot of caching to achieve performance. Data can be written\r\n	to the log immediately meaning that sync time is very low. Data\r\n	robustness is improved dramatically.</p>\r\n	<li/>\r\n<p class=\"western\">There are no allocation tables or similar.\r\n	This reduces the amount of data being written to the flash, and that\r\n	there are no tables to corrupt.</p>\r\n	<li/>\r\n<p class=\"western\">Since all writes are to the end of the log\r\n	there are no “high traffic” blocks. This means Yaffs only needs\r\n	a simpler wear leveling strategy.</p>\r\n	<li/>\r\n<p class=\"western\">In the event of a power failure, the file\r\n	system state is easily re-created from the log. This means there is\r\n	no need to perform disk repair operations to correct for an unclean\r\n	shutdown.</p>\r\n</ul>\r\n<p class=\"western\">So why don\'t we see many log structured file\r\nsystems for disk file systems? The answer to this is that log file\r\nsystems tend to spread the writes around on the media. That is\r\ntypically very problematic for mechanical storage which must\r\nphysically move the read/write head from one location to another\r\nmaking the access time very slow. Of course that does not apply for\r\nflash memory. By designing specifically for flash, Yaffs can ignore\r\nthis issue and write fast.</p>\r\n<p class=\"western\">Many flash file systems need make a compromise\r\nbetween robustness against performance. Thanks to the log structure,\r\nYaffs does not need to. Yaffs can provide high performance without\r\ngiving up on robustness.</p>\r\n<p class=\"western\">Those familiar with log structured file system\r\ndesign will know that some log structured file systems have problems\r\nwith garbage collection<a class=\"sdfootnoteanc\" name=\"sdfootnote3anc\" href=\"#sdfootnote3sym\"><sup>3</sup></a>.\r\nGarbage collection is used to clean up the log and make more free\r\nspace available. Some log structured file system designs did not pay\r\nenough attention to garbage collection and can stall for a\r\nconsiderable time while garbage collection happens. Yaffs was\r\ndesigned differently. The potential impact of garbage collection was\r\nconsidered throughout the Yaffs design process. As a result, Yaffs\r\nhas a very simple garbage collection model that allows a lot of\r\nflexibility in garbage collection scheduling. This prevents the\r\ngarbage collection from making the file system unresponsive.</p>\r\n<p class=\"western\">Most file systems are developed within the\r\ncontext, and framework of, a single operating system. This typically\r\nmakes the code difficult to explore, debug and port. Yaffs on the\r\nother hand was developed from the start inside a portable\r\ndevelopment/testing framework. Yaffs is then ported to various\r\noperating systems through the addition of glue code.</p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\"><img src=\"data:image/png;base64,[encoded data, 38784 characters]\" name=\"Object1\" align=\"left\" width=\"552\" height=\"524\"/>\r\n<br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\">There are many benefits to this approach:</p>\r\n<ul>\r\n	<li/>\r\n<p class=\"western\">A development framework runs in user space\r\n	which provides a richer development environment than inside an OS\r\n	kernel. It is much easier to attach debuggers and perform logging\r\n	and create reproducible testing.</p>\r\n	<li/>\r\n<p class=\"western\">The code is structured to be portable. That\r\n	makes it relatively easy to port to a new OS or RTOS with a high\r\n	level of confidence.</p>\r\n	<li/>\r\n<p class=\"western\">There is a choice of porting interfaces\r\n	allowing more flexibility to determine which porting method will be\r\n	simpler. For example, the Linux wrapper accesses the Yaffs core\r\n	directly while the Windows CE wrapper access the Yaffs Direct\r\n	Interface<a class=\"sdfootnoteanc\" name=\"sdfootnote4anc\" href=\"#sdfootnote4sym\"><sup>4</sup></a>.</p>\r\n	<li/>\r\n<p class=\"western\">Each different environment provides\r\n	different test tools. For example, Linux provides a raft of file\r\n	system test tools that do different kinds of testing to the power\r\n	fail test harness. Since the vast majority of the code is in the\r\n	portable Yaffs core, that code gets the advantage of all test\r\n	methods combined. The many millions of Android phone users that use\r\n	Yaffs-based devices are helping test the core code that is also used\r\n	on a wide variety of different operating systems and a wide range of\r\n	different device types.</p>\r\n	<li/>\r\n<p class=\"western\">Its Open Source status means any interested\r\n	person can take a version from git and test it to make sure that it\r\n	meets their needs.</p>\r\n</ul>\r\n<h1 class=\"western\">4 Testing</h1>\r\n<p class=\"western\">It is all very well to design software to be\r\nrobust, but it needs thorough testing to build confidence in the\r\nsoftware and in the code authors and supplier.</p>\r\n<p class=\"western\">File systems have incredibly complex state so it\r\nis not at all surprising that operating system designers find file\r\nsystems some of the most challenging code to test.</p>\r\n<p class=\"western\">There is no single test methodology that can test\r\nall cases, and exhaustive state testing is impossible. The best we\r\ncan do is to have a suite of test methodologies that combine to\r\nprovide thorough testing.</p>\r\n<p class=\"western\">Approximately 60% of Yaffs development effort is\r\ndirected towards testing and improving the test environment. We are\r\nconstantly researching new methodologies.</p>\r\n<p class=\"western\">The following are descriptions of the most\r\nimportant test strategies used in Yaffs.</p>\r\n<h2 class=\"western\">4.1Power Fail Stress Testing</h2>\r\n<p class=\"western\">By far the most important consideration in Yaffs\r\ntesting is that it is robust to corruptions caused by power failure.\r\nWe want Yaffs to provide the basis for reliable products in typical\r\nembedded system environments.</p>\r\n<p class=\"western\">The first power fail testing was done by companies\r\nintegrating Yaffs into their products. Some of these built test jigs\r\nwhich would automatically interrupt power while running a real\r\nhardware device. This approach is better than nothing, but has some\r\nlimitations:</p>\r\n<ul>\r\n	<li/>\r\n<p class=\"western\">It is relatively costly to set up. Flash\r\n	has a limited lifetime meaning that test devices wear out with time\r\n	and must be replaced.</p>\r\n	<li/>\r\n<p class=\"western\">It is relatively slow since each cycle\r\n	takes many seconds to boot, run the application for a while and then\r\n	reboot.</p>\r\n	<li/>\r\n<p class=\"western\">Many, and perhaps most, of the power\r\n	interruptions will happen at times when the file system is inactive\r\n	and thus be wasted cycles.</p>\r\n</ul>\r\n<p class=\"western\">In 2008 we developed a simulated power-fail-test\r\nenvironment. This simulates power failures using simulated flash\r\nmemory while running various consistency checks.</p>\r\n<p class=\"western\">The benefits of a software-based test harness are\r\nnumerous:</p>\r\n<ul>\r\n	<li/>\r\n<p class=\"western\">The test harness controls the point at\r\n	which the simulated power failures happen. That means every test\r\n	cycle counts.</p>\r\n	<li/>\r\n<p class=\"western\">No special hardware is required.</p>\r\n	<li/>\r\n<p class=\"western\">Test loops run faster. A quad-core computer\r\n	can simulate ten to twenty power failures per second. That means\r\n	about a million power failure simulations per day.</p>\r\n</ul>\r\n<p class=\"western\">The effectiveness of the new software based\r\ntesting is dramatic.. A few times we have tested some user-suggested\r\nchanges that had passed a week or more of real-world power fail\r\ntesting only to have problems caught by the software simulation in a\r\nmatter of minutes.</p>\r\n<p class=\"western\">We regularly run the power fail simulation test\r\nover a weekend, testing millions of power fail cycles.</p>\r\n<h2 class=\"western\">4.2Testing the Yaffs Direct Interface API</h2>\r\n<p class=\"western\">Yaffs Direct Interface (YDI) is a POSIX-like\r\nwrapper around the Yaffs core. This provides a set of function calls,\r\nyaffs_open(), yaffs_write() and the like.</p>\r\n<p class=\"western\">Each function can return numerous error codes and\r\nhas to handle numerous different parameters.</p>\r\n<p class=\"western\">Although there were already significant tests for\r\nthe YDI, an extensive test harness was developed in 2010 to\r\ncomprehensively test each of the error paths and generate all of the\r\nrequired errors.</p>\r\n<p class=\"western\">This provides a high level of confidence that the\r\ntest interfaces do what they should and that POSIX-like functionality\r\nprovides relatively clean porting of existing code.</p>\r\n<h2 class=\"western\">4.3Linux Testing</h2>\r\n<p class=\"western\">The main purpose of the Linux testing is to test\r\nthe Linux wrapper code. It does, however, still exercise the Yaffs\r\ncore code differently to other testing and thus adds to the test\r\nfabric.</p>\r\n<p class=\"western\">The Linux testing does not do power fail testing\r\nbut instead tests other aspects such as clean shutdowns, cache\r\nintegrity and write performance. This gives a useful way to assess\r\nthe effects of modifications.</p>\r\n<p class=\"western\">Linux testing is done on both real hardware and on\r\nsimulated hardware using the Linux mtd nand simulator.</p>\r\n<p class=\"western\">As with the Power Fail Stress Testing described\r\nabove, the simulated testing is done using a scrippted environment\r\nwhich is typically run for a few days at a time.</p>\r\n<h2 class=\"western\">4.4Fuzz Testing</h2>\r\n<p class=\"western\">Fuzz testing deliberately corrupts the flash image\r\nand ensures that Yaffs still mounts. This is done to ensure that\r\nYaffs does not crash on corrupted data.</p>\r\n<p class=\"western\">Clearly fuzz testing can corrupt the contents of\r\nindividual files (that\'s its job), but the file system integrity\r\nshould not be compromised. \r\n</p>\r\n<h2 class=\"western\">4.5Software checking</h2>\r\n<p class=\"western\">Although code checking is  not actual testing per\r\nse, it does help to verify code changes.</p>\r\n<p class=\"western\">The Yaffs code has been checked with Coverity<a class=\"sdfootnoteanc\" name=\"sdfootnote5anc\" href=\"#sdfootnote5sym\"><sup>5</sup></a>\r\n– a market leader in code checking.</p>\r\n<p class=\"western\">We are investigating the use of KLEE and other\r\ntools.</p>\r\n<h2 class=\"western\">4.6Open Source Usage</h2>\r\n<p class=\"western\">Open Source usage of Yaffs opens it up to testing\r\nby the many different projects. Many of these participate in some way\r\nwith the Yaffs mailing list, helping to uncover issues and generally\r\nprovide feedback.</p>\r\n<p class=\"western\">Each different project uses Yaffs in a different\r\nway, meaning that a wider range of operation sequences are tested.</p>\r\n<h2 class=\"western\">4.7Universities</h2>\r\n<p class=\"western\">Over its lifetime, Yaffs has been used as a\r\nteaching framework for various university course in many different\r\ncounties around the world.</p>\r\n<p class=\"western\">For example, Oregon State and Utah State\r\nUniversities have used Yaffs as a test bench for their post-graduate\r\nsoftware testing courses. They essentially test the test tools by\r\ninjecting errors into the Yaffs code and seeing if these are\r\ndiscovered by the test tools they are testing. Of course this has the\r\nside effect of running these tests over the original Yaffs code too. \r\n</p>\r\n<p class=\"western\">Those interested in test methods are encouraged to\r\nread some of the university papers in the references of this\r\ndocument.</p>\r\n<p class=\"western\">We expect to adopt and extend some of the Oregon\r\nState ideas and use these to extend our in-house test suite.</p>\r\n<h1 class=\"western\">5 Conclusions</h1>\r\n<p class=\"western\">Software development is an iterative process of\r\ndesign and testing. Robust software solutions are only possible with\r\nextensive testing.</p>\r\n<p class=\"western\">Embedded systems increasingly need to store data\r\nin file systems as a critical part of their operation. It is thus\r\nimportant to have a file system that is predictable and robust to\r\npower failure and similar interruptions.</p>\r\n<p class=\"western\">Yaffs has been designed from scratch to be robust\r\nto power failure and that robustness has been verified with a\r\nmulti-pronged test strategy that is continuously being improved.</p>\r\n<h1 class=\"western\" style=\"page-break-before: always\">6References</h1>\r\n<p class=\"western\" align=\"left\">Charles Manning, “How Yaffs\r\nWorks”.<br/>\r\n<a href=\"http://users.actrix.co.nz/manningc/yaffs-docs/HowYaffsWorks.pdf\">http://users.actrix.co.nz/manningc/yaffs-docs/HowYaffsWorks.pdf</a></p>\r\n<p class=\"western\" align=\"left\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\" align=\"left\">A. Groce et al, “Swarm Testing”\r\nfrom Oregon State University, School of EE and Computer Science and\r\nUtah State University, School of Computing,\r\n2011.<br/>\r\n<a href=\"http://www.ct.utah.edu/~regehr/papers/swarm12.pdf\">http://</a><a href=\"http://www.ct.utah.edu/~regehr/papers/swarm12.pdf\">www.ct.utah.edu/~regehr/papers/swarm12.pdf</a></p>\r\n<p class=\"western\" align=\"left\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\" align=\"left\"><em>Wu CH, “Efficient\r\nInitialization and Crash Recovery</em> for. <em>Log</em>-<em>based\r\nFile Systems</em> over Flash Memory” from National Taiwan\r\nUniversity, Dept of Computer Science,<span style=\"font-style: normal\">\r\n2006.<br/>\r\nhttp://</span><cite>www.cis.nctu.edu.tw/~lpchang/papers/SAC_wu_sac06.pdf</cite></p>\r\n<p class=\"western\" align=\"left\" style=\"font-style: normal\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<div id=\"sdfootnote1\">\r\n	<p class=\"sdfootnote-western\"><a class=\"sdfootnotesym\" name=\"sdfootnote1sym\" href=\"#sdfootnote1anc\">1</a>Note\r\n	that flash translation layers (FTLs) are erroneously refered to as\r\n	flash file systems. For example, despite the name, M-Systems TrueFFS\r\n	is not a flash file system but a flash translation layer (FTL).</p>\r\n</div>\r\n<div id=\"sdfootnote2\">\r\n	<p class=\"sdfootnote-western\"><a class=\"sdfootnotesym\" name=\"sdfootnote2sym\" href=\"#sdfootnote2anc\">2</a>This\r\n	document only provides a brief overview of the Yaffs architecture\r\n	and design. The “How Yaffs Works” document provides an in-depth\r\n	explanation of the Yaffs design and architecture.</p>\r\n</div>\r\n<div id=\"sdfootnote3\">\r\n	<p class=\"sdfootnote-western\"><a class=\"sdfootnotesym\" name=\"sdfootnote3sym\" href=\"#sdfootnote3anc\">3</a>Refer\r\n	to the “How Yaffs Works” document to understand the need for\r\n	garbage collection and how Yaffs does garbage collection.</p>\r\n</div>\r\n<div id=\"sdfootnote4\">\r\n	<p class=\"sdfootnote-western\"><a class=\"sdfootnotesym\" name=\"sdfootnote4sym\" href=\"#sdfootnote4anc\">4</a>For\r\n	more information on Yaffs Direct Interface, please read the various\r\n	documents on the subject.</p>\r\n</div>\r\n<div id=\"sdfootnote5\">\r\n	<p class=\"sdfootnote-western\"><a class=\"sdfootnotesym\" name=\"sdfootnote5sym\" href=\"#sdfootnote5anc\">5</a>http://www.coverity.com</p>\r\n</div>','<p>This document describes some of the important design criteria and design features used to achieve a robust design suitable for modern embedded systems which need to store critical data.&nbsp; The test methodologies are also described.</p>','raw_html'),('paper',0,420,604,'und',0,'\r\n	<p class=\"western\">Many embedded systems need to store critical\r\n	data, making reliable file systems an important part of modern\r\n	embedded system design. That robustness is not achieved through\r\n	chance. Robustness is only achieved through design and extensive\r\n	testing to verify that the file system functions correctly and is\r\n	resistant to power failure.</p>\r\n	<p class=\"western\">This document describes some of the important\r\n	design criteria and design features used to achieve a robust design.</p>\r\n	\r\n<p class=\"western\" style=\"page-break-before: always\"><h1 class=\"western\">1 Background</h1>\r\n<p class=\"western\">Cheaper CPUs and flash have driven up embedded\r\nsystem functionality. These increased functions often require file\r\nsystem storage.</p>\r\n<p class=\"western\">The original flash file storage mechanisms were\r\nthe use of a flash translation layer (FTL) – a driver model which\r\nmakes flash memory appear as a disk drive – in conjunction with a\r\ndisk-oriented file system such as FAT. This storage methodology has\r\nvarious performance and robustness limitations, leading to the\r\ndevelopment of file systems designed specifically for flash memory.\r\nThese are known as flash file systems.</p>\r\n<p class=\"western\">Flash memory has various limitations when compared\r\nwith a disk. For example, flash memory pages cannot be individually\r\nre-written but instead the whole block must be  erased and rewritten\r\nwith the modified page. Typical FTL achieve this with various logical\r\nto physical mapping schemes. Thus emulating disk-like behaviour on\r\nflash memory adds an extra layer of software which slows down write\r\nperformance. Worse still, it adds extra state which is prone to\r\ncorruption due to power failure.</p>\r\n<p class=\"western\">A typical FTL-based solution will use a file\r\nsystem such as FAT. FAT always stores tables in the same disk blocks\r\nand must thus change the same blocks often. Since flash memory blocks\r\ncan endure a limited number of write/erasure cycles, the FTL must\r\nmove the physical location of the block around to prevent  the high\r\ntraffic blocks from wearing out. This requires wear levelling – a\r\nfurther burden.</p>\r\n<p class=\"western\">Some systems try to mitigate against the\r\nperformance penalties by caching a lot of data to reduce writes.\r\nWhile this can go some way towards reducing the apparent write time,\r\nit does make the solution prone to data loss in the event of a power\r\nfailure.</p>\r\n<p class=\"western\">As well as limitations, flash memory also has\r\ncertain advantages when compared to rotating media. There is no spin\r\nup time, making it more responsive. There is no read head so there is\r\nno read penalty if data is fragmented. Flash file systems can be\r\ndesigned to exploit these advantages.</p>\r\n<p class=\"western\">True flash file systems<a class=\"sdfootnoteanc\" name=\"sdfootnote1anc\" href=\"#sdfootnote1sym\"><sup>1</sup></a>,\r\non the other hand, are a single code body designed to take the\r\nfeatures and limitations of flash into consideration. Flash file\r\nsystems can thus be far more “flash friendly”. Well designed\r\nflash file systems will avoid using “flash unfriendly” techniques\r\nsuch as allocation tables and in-place rewriting.</p>\r\n<p class=\"western\">Yaffs is a flash file system, originally designed\r\nspecifically for NAND flash though also used with great success on\r\nNOR flash too. Yaffs development started in 2001 when 32Mbytes of\r\nflash was considered large. Since then, Yaffs has been expanded to\r\nwork properly with different flash types and far larger memory arrays\r\n(many GBytes).</p>\r\n<p class=\"western\">Yaffs was originally deployed in Linux, but was\r\nwritten in an OS neutral way, mainly to facilitate modular\r\ndevelopment and testing. This turned out to be useful when we had\r\nrequests to port Yaffs to other operating systems. Since then, Yaffs\r\nhas been used in many different products in a wide variety of\r\napplications from consumer products such as cell phones and sewing\r\nmachines to aerospace, industrial and medical applications including\r\nprocess control, building management, communications infrastructure\r\nand many others.</p>\r\n<p class=\"western\">Yaffs is not tied to any endian ordering and has\r\nbeen used on a wide variety of architectures including ARM, MIPS,\r\nPowerPC, x86, some DSPs. Yaffs has been deployed using a wide variety\r\nof compilers from many different vendors.</p>\r\n<p class=\"western\">Nor is Yaffs tied to any particular operating\r\nsystem. Yaffs has been used with Linux, eCOS, Windows Embedded\r\nCompact (previously Windows CE), VxWorks and others.</p>\r\n<h1 class=\"western\">2 Flash File System considerations</h1>\r\n<p class=\"western\">There are many criteria that are important when\r\nselecting a flash file system. These are some that out customers have\r\nfound to be most important:</p>\r\n<ul>\r\n	<li/>\r\n<p class=\"western\">Robustness: It really is not worth having a\r\n	file system that loses or corrupts data and prevents the system from\r\n	working properly. Some flash file systems are only robust when\r\n	synced (flushed) after files have been written. That requires extra\r\n	code, slows the system and leaves the file system in a\r\n	non-deterministic state until the sync has been completed. Some file\r\n	systems need to perform disk repair operations (eg. check disk) in\r\n	the event of a power failure. This can add considerable time to the\r\n	start up, preventing the system from being operational.</p>\r\n	<li/>\r\n<p class=\"western\">Performance: In many embedded system\r\n	designs, slow read/write performance can delay tasks and cause\r\n	system degradation or even failure. It is thus important that\r\n	read/write performance be acceptable. Note that many flash file\r\n	systems need to perform extra actions such as garbage collection. In\r\n	some cases these actions can cause the file system to stall for a\r\n	long time. It is thus important that these factors be taken into\r\n	consideration. Performance can sometimes be improved by adding a\r\n	write caching layer. These caching layers make the file system calls\r\n	(write etc) proceed quickly, without actually writing the data to\r\n	flash. This is a two-edged sword as data in the cache will be lost\r\n	on a power failure and syncing the file system will take a long\r\n	time. Thus, most flash file systems offer either speed or robustness\r\n	– not both.</p>\r\n	<li/>\r\n<p class=\"western\">Proven: It is very easy for a file system\r\n	vendor to provide a list of claims saying “100% power safe” or\r\n	similar, but what evidence do they have to back this up? All file\r\n	systems, including flash file systems, are complex bodies of\r\n	software with extremely complex state. They need very significant\r\n	testing to prove that they work correctly.</p>\r\n	<li/>\r\n<p class=\"western\">Portable: Software is a huge investment and\r\n	it is increasingly important to be able to port the software between\r\n	OSs and CPU architectures. Most flash file systems are limited to a\r\n	single operating system which makes it difficult to migrate software\r\n	between different platforms. In Yaffs\' case portability extends to\r\n	being able to seamlessly migrate the core Yaffs code into a test\r\n	framework which enhances testing.</p>\r\n</ul>\r\n<h1 class=\"western\">3 How Yaffs achieves robustness and performance</h1>\r\n<p class=\"western\">Yaffs was designed from the ground up specifically\r\nto work well with NAND flash. The author had already developed\r\nanother flash file system, so was already familiar with the  design\r\nchallenges of flash.</p>\r\n<p class=\"western\">As Yaffs is not just adapting a disk-oriented file\r\nsystem to work with flash it is not surprising that Yaffs is very\r\ndifferent in design to most other file systems. The key difference is\r\nthat Yaffs is a log-structured. file system<a class=\"sdfootnoteanc\" name=\"sdfootnote2anc\" href=\"#sdfootnote2sym\"><sup>2</sup></a>.</p>\r\n<p class=\"western\">In essence, a log structured file system writes\r\nfile system changes as a sequential log.  The log structure is\r\nparticularly suitable for various reasons including:</p>\r\n<ul>\r\n	<li/>\r\n<p class=\"western\">All writes are at the end of the log. When\r\n	a file is modified, there is no need to erase and rewrite a part of\r\n	the flash. Changes are just appended to the log. Thus there is no\r\n	need to erase and copy old data just to change some existing pages\r\n	in a file. This tends to make writes much faster. There is no need\r\n	to do a lot of caching to achieve performance. Data can be written\r\n	to the log immediately meaning that sync time is very low. Data\r\n	robustness is improved dramatically.</p>\r\n	<li/>\r\n<p class=\"western\">There are no allocation tables or similar.\r\n	This reduces the amount of data being written to the flash, and that\r\n	there are no tables to corrupt.</p>\r\n	<li/>\r\n<p class=\"western\">Since all writes are to the end of the log\r\n	there are no “high traffic” blocks. This means Yaffs only needs\r\n	a simpler wear leveling strategy.</p>\r\n	<li/>\r\n<p class=\"western\">In the event of a power failure, the file\r\n	system state is easily re-created from the log. This means there is\r\n	no need to perform disk repair operations to correct for an unclean\r\n	shutdown.</p>\r\n</ul>\r\n<p class=\"western\">So why don\'t we see many log structured file\r\nsystems for disk file systems? The answer to this is that log file\r\nsystems tend to spread the writes around on the media. That is\r\ntypically very problematic for mechanical storage which must\r\nphysically move the read/write head from one location to another\r\nmaking the access time very slow. Of course that does not apply for\r\nflash memory. By designing specifically for flash, Yaffs can ignore\r\nthis issue and write fast.</p>\r\n<p class=\"western\">Many flash file systems need make a compromise\r\nbetween robustness against performance. Thanks to the log structure,\r\nYaffs does not need to. Yaffs can provide high performance without\r\ngiving up on robustness.</p>\r\n<p class=\"western\">Those familiar with log structured file system\r\ndesign will know that some log structured file systems have problems\r\nwith garbage collection<a class=\"sdfootnoteanc\" name=\"sdfootnote3anc\" href=\"#sdfootnote3sym\"><sup>3</sup></a>.\r\nGarbage collection is used to clean up the log and make more free\r\nspace available. Some log structured file system designs did not pay\r\nenough attention to garbage collection and can stall for a\r\nconsiderable time while garbage collection happens. Yaffs was\r\ndesigned differently. The potential impact of garbage collection was\r\nconsidered throughout the Yaffs design process. As a result, Yaffs\r\nhas a very simple garbage collection model that allows a lot of\r\nflexibility in garbage collection scheduling. This prevents the\r\ngarbage collection from making the file system unresponsive.</p>\r\n<p class=\"western\">Most file systems are developed within the\r\ncontext, and framework of, a single operating system. This typically\r\nmakes the code difficult to explore, debug and port. Yaffs on the\r\nother hand was developed from the start inside a portable\r\ndevelopment/testing framework. Yaffs is then ported to various\r\noperating systems through the addition of glue code.</p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\"><img src=\"data:image/png;base64,[encoded data, 38784 characters]\" name=\"Object1\" align=\"left\" width=\"552\" height=\"524\"/>\r\n<br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\">There are many benefits to this approach:</p>\r\n<ul>\r\n	<li/>\r\n<p class=\"western\">A development framework runs in user space\r\n	which provides a richer development environment than inside an OS\r\n	kernel. It is much easier to attach debuggers and perform logging\r\n	and create reproducible testing.</p>\r\n	<li/>\r\n<p class=\"western\">The code is structured to be portable. That\r\n	makes it relatively easy to port to a new OS or RTOS with a high\r\n	level of confidence.</p>\r\n	<li/>\r\n<p class=\"western\">There is a choice of porting interfaces\r\n	allowing more flexibility to determine which porting method will be\r\n	simpler. For example, the Linux wrapper accesses the Yaffs core\r\n	directly while the Windows CE wrapper access the Yaffs Direct\r\n	Interface<a class=\"sdfootnoteanc\" name=\"sdfootnote4anc\" href=\"#sdfootnote4sym\"><sup>4</sup></a>.</p>\r\n	<li/>\r\n<p class=\"western\">Each different environment provides\r\n	different test tools. For example, Linux provides a raft of file\r\n	system test tools that do different kinds of testing to the power\r\n	fail test harness. Since the vast majority of the code is in the\r\n	portable Yaffs core, that code gets the advantage of all test\r\n	methods combined. The many millions of Android phone users that use\r\n	Yaffs-based devices are helping test the core code that is also used\r\n	on a wide variety of different operating systems and a wide range of\r\n	different device types.</p>\r\n	<li/>\r\n<p class=\"western\">Its Open Source status means any interested\r\n	person can take a version from git and test it to make sure that it\r\n	meets their needs.</p>\r\n</ul>\r\n<h1 class=\"western\">4 Testing</h1>\r\n<p class=\"western\">It is all very well to design software to be\r\nrobust, but it needs thorough testing to build confidence in the\r\nsoftware and in the code authors and supplier.</p>\r\n<p class=\"western\">File systems have incredibly complex state so it\r\nis not at all surprising that operating system designers find file\r\nsystems some of the most challenging code to test.</p>\r\n<p class=\"western\">There is no single test methodology that can test\r\nall cases, and exhaustive state testing is impossible. The best we\r\ncan do is to have a suite of test methodologies that combine to\r\nprovide thorough testing.</p>\r\n<p class=\"western\">Approximately 60% of Yaffs development effort is\r\ndirected towards testing and improving the test environment. We are\r\nconstantly researching new methodologies.</p>\r\n<p class=\"western\">The following are descriptions of the most\r\nimportant test strategies used in Yaffs.</p>\r\n<h2 class=\"western\">4.1Power Fail Stress Testing</h2>\r\n<p class=\"western\">By far the most important consideration in Yaffs\r\ntesting is that it is robust to corruptions caused by power failure.\r\nWe want Yaffs to provide the basis for reliable products in typical\r\nembedded system environments.</p>\r\n<p class=\"western\">The first power fail testing was done by companies\r\nintegrating Yaffs into their products. Some of these built test jigs\r\nwhich would automatically interrupt power while running a real\r\nhardware device. This approach is better than nothing, but has some\r\nlimitations:</p>\r\n<ul>\r\n	<li/>\r\n<p class=\"western\">It is relatively costly to set up. Flash\r\n	has a limited lifetime meaning that test devices wear out with time\r\n	and must be replaced.</p>\r\n	<li/>\r\n<p class=\"western\">It is relatively slow since each cycle\r\n	takes many seconds to boot, run the application for a while and then\r\n	reboot.</p>\r\n	<li/>\r\n<p class=\"western\">Many, and perhaps most, of the power\r\n	interruptions will happen at times when the file system is inactive\r\n	and thus be wasted cycles.</p>\r\n</ul>\r\n<p class=\"western\">In 2008 we developed a simulated power-fail-test\r\nenvironment. This simulates power failures using simulated flash\r\nmemory while running various consistency checks.</p>\r\n<p class=\"western\">The benefits of a software-based test harness are\r\nnumerous:</p>\r\n<ul>\r\n	<li/>\r\n<p class=\"western\">The test harness controls the point at\r\n	which the simulated power failures happen. That means every test\r\n	cycle counts.</p>\r\n	<li/>\r\n<p class=\"western\">No special hardware is required.</p>\r\n	<li/>\r\n<p class=\"western\">Test loops run faster. A quad-core computer\r\n	can simulate ten to twenty power failures per second. That means\r\n	about a million power failure simulations per day.</p>\r\n</ul>\r\n<p class=\"western\">The effectiveness of the new software based\r\ntesting is dramatic.. A few times we have tested some user-suggested\r\nchanges that had passed a week or more of real-world power fail\r\ntesting only to have problems caught by the software simulation in a\r\nmatter of minutes.</p>\r\n<p class=\"western\">We regularly run the power fail simulation test\r\nover a weekend, testing millions of power fail cycles.</p>\r\n<h2 class=\"western\">4.2Testing the Yaffs Direct Interface API</h2>\r\n<p class=\"western\">Yaffs Direct Interface (YDI) is a POSIX-like\r\nwrapper around the Yaffs core. This provides a set of function calls,\r\nyaffs_open(), yaffs_write() and the like.</p>\r\n<p class=\"western\">Each function can return numerous error codes and\r\nhas to handle numerous different parameters.</p>\r\n<p class=\"western\">Although there were already significant tests for\r\nthe YDI, an extensive test harness was developed in 2010 to\r\ncomprehensively test each of the error paths and generate all of the\r\nrequired errors.</p>\r\n<p class=\"western\">This provides a high level of confidence that the\r\ntest interfaces do what they should and that POSIX-like functionality\r\nprovides relatively clean porting of existing code.</p>\r\n<h2 class=\"western\">4.3Linux Testing</h2>\r\n<p class=\"western\">The main purpose of the Linux testing is to test\r\nthe Linux wrapper code. It does, however, still exercise the Yaffs\r\ncore code differently to other testing and thus adds to the test\r\nfabric.</p>\r\n<p class=\"western\">The Linux testing does not do power fail testing\r\nbut instead tests other aspects such as clean shutdowns, cache\r\nintegrity and write performance. This gives a useful way to assess\r\nthe effects of modifications.</p>\r\n<p class=\"western\">Linux testing is done on both real hardware and on\r\nsimulated hardware using the Linux mtd nand simulator.</p>\r\n<p class=\"western\">As with the Power Fail Stress Testing described\r\nabove, the simulated testing is done using a scrippted environment\r\nwhich is typically run for a few days at a time.</p>\r\n<h2 class=\"western\">4.4Fuzz Testing</h2>\r\n<p class=\"western\">Fuzz testing deliberately corrupts the flash image\r\nand ensures that Yaffs still mounts. This is done to ensure that\r\nYaffs does not crash on corrupted data.</p>\r\n<p class=\"western\">Clearly fuzz testing can corrupt the contents of\r\nindividual files (that\'s its job), but the file system integrity\r\nshould not be compromised. \r\n</p>\r\n<h2 class=\"western\">4.5Software checking</h2>\r\n<p class=\"western\">Although code checking is  not actual testing per\r\nse, it does help to verify code changes.</p>\r\n<p class=\"western\">The Yaffs code has been checked with Coverity<a class=\"sdfootnoteanc\" name=\"sdfootnote5anc\" href=\"#sdfootnote5sym\"><sup>5</sup></a>\r\n– a market leader in code checking.</p>\r\n<p class=\"western\">We are investigating the use of KLEE and other\r\ntools.</p>\r\n<h2 class=\"western\">4.6Open Source Usage</h2>\r\n<p class=\"western\">Open Source usage of Yaffs opens it up to testing\r\nby the many different projects. Many of these participate in some way\r\nwith the Yaffs mailing list, helping to uncover issues and generally\r\nprovide feedback.</p>\r\n<p class=\"western\">Each different project uses Yaffs in a different\r\nway, meaning that a wider range of operation sequences are tested.</p>\r\n<h2 class=\"western\">4.7Universities</h2>\r\n<p class=\"western\">Over its lifetime, Yaffs has been used as a\r\nteaching framework for various university course in many different\r\ncounties around the world.</p>\r\n<p class=\"western\">For example, Oregon State and Utah State\r\nUniversities have used Yaffs as a test bench for their post-graduate\r\nsoftware testing courses. They essentially test the test tools by\r\ninjecting errors into the Yaffs code and seeing if these are\r\ndiscovered by the test tools they are testing. Of course this has the\r\nside effect of running these tests over the original Yaffs code too. \r\n</p>\r\n<p class=\"western\">Those interested in test methods are encouraged to\r\nread some of the university papers in the references of this\r\ndocument.</p>\r\n<p class=\"western\">We expect to adopt and extend some of the Oregon\r\nState ideas and use these to extend our in-house test suite.</p>\r\n<h1 class=\"western\">5 Conclusions</h1>\r\n<p class=\"western\">Software development is an iterative process of\r\ndesign and testing. Robust software solutions are only possible with\r\nextensive testing.</p>\r\n<p class=\"western\">Embedded systems increasingly need to store data\r\nin file systems as a critical part of their operation. It is thus\r\nimportant to have a file system that is predictable and robust to\r\npower failure and similar interruptions.</p>\r\n<p class=\"western\">Yaffs has been designed from scratch to be robust\r\nto power failure and that robustness has been verified with a\r\nmulti-pronged test strategy that is continuously being improved.</p>\r\n<h1 class=\"western\" style=\"page-break-before: always\">6References</h1>\r\n<p class=\"western\" align=\"left\">Charles Manning, “How Yaffs\r\nWorks”.<br/>\r\n<a href=\"http://users.actrix.co.nz/manningc/yaffs-docs/HowYaffsWorks.pdf\">http://users.actrix.co.nz/manningc/yaffs-docs/HowYaffsWorks.pdf</a></p>\r\n<p class=\"western\" align=\"left\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\" align=\"left\">A. Groce et al, “Swarm Testing”\r\nfrom Oregon State University, School of EE and Computer Science and\r\nUtah State University, School of Computing,\r\n2011.<br/>\r\n<a href=\"http://www.ct.utah.edu/~regehr/papers/swarm12.pdf\">http://</a><a href=\"http://www.ct.utah.edu/~regehr/papers/swarm12.pdf\">www.ct.utah.edu/~regehr/papers/swarm12.pdf</a></p>\r\n<p class=\"western\" align=\"left\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\" align=\"left\"><em>Wu CH, “Efficient\r\nInitialization and Crash Recovery</em> for. <em>Log</em>-<em>based\r\nFile Systems</em> over Flash Memory” from National Taiwan\r\nUniversity, Dept of Computer Science,<span style=\"font-style: normal\">\r\n2006.<br/>\r\nhttp://</span><cite>www.cis.nctu.edu.tw/~lpchang/papers/SAC_wu_sac06.pdf</cite></p>\r\n<p class=\"western\" align=\"left\" style=\"font-style: normal\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<div id=\"sdfootnote1\">\r\n	<p class=\"sdfootnote-western\"><a class=\"sdfootnotesym\" name=\"sdfootnote1sym\" href=\"#sdfootnote1anc\">1</a>Note\r\n	that flash translation layers (FTLs) are erroneously refered to as\r\n	flash file systems. For example, despite the name, M-Systems TrueFFS\r\n	is not a flash file system but a flash translation layer (FTL).</p>\r\n</div>\r\n<div id=\"sdfootnote2\">\r\n	<p class=\"sdfootnote-western\"><a class=\"sdfootnotesym\" name=\"sdfootnote2sym\" href=\"#sdfootnote2anc\">2</a>This\r\n	document only provides a brief overview of the Yaffs architecture\r\n	and design. The “How Yaffs Works” document provides an in-depth\r\n	explanation of the Yaffs design and architecture.</p>\r\n</div>\r\n<div id=\"sdfootnote3\">\r\n	<p class=\"sdfootnote-western\"><a class=\"sdfootnotesym\" name=\"sdfootnote3sym\" href=\"#sdfootnote3anc\">3</a>Refer\r\n	to the “How Yaffs Works” document to understand the need for\r\n	garbage collection and how Yaffs does garbage collection.</p>\r\n</div>\r\n<div id=\"sdfootnote4\">\r\n	<p class=\"sdfootnote-western\"><a class=\"sdfootnotesym\" name=\"sdfootnote4sym\" href=\"#sdfootnote4anc\">4</a>For\r\n	more information on Yaffs Direct Interface, please read the various\r\n	documents on the subject.</p>\r\n</div>\r\n<div id=\"sdfootnote5\">\r\n	<p class=\"sdfootnote-western\"><a class=\"sdfootnotesym\" name=\"sdfootnote5sym\" href=\"#sdfootnote5anc\">5</a>http://www.coverity.com</p>\r\n</div>','<p>This document describes some of the important design criteria and design features used to achieve a robust design suitable for modern embedded systems which need to store critical data.&nbsp; The test methodologies are also described.</p>','raw_html'),('paper',0,420,605,'und',0,'\r\n\r\n	<p class=\"western\">Many embedded systems need to store critical\r\n	data, making reliable file systems an important part of modern\r\n	embedded system design. That robustness is not achieved through\r\n	chance. Robustness is only achieved through design and extensive\r\n	testing to verify that the file system functions correctly and is\r\n	resistant to power failure.</p>\r\n	<p class=\"western\">This document describes some of the important\r\n	design criteria and design features used to achieve a robust design.</p>\r\n	\r\n<p class=\"western\" style=\"page-break-before: always\"><h1 class=\"western\">1 Background</h1>\r\n<p class=\"western\">Cheaper CPUs and flash have driven up embedded\r\nsystem functionality. These increased functions often require file\r\nsystem storage.</p>\r\n<p class=\"western\">The original flash file storage mechanisms were\r\nthe use of a flash translation layer (FTL) – a driver model which\r\nmakes flash memory appear as a disk drive – in conjunction with a\r\ndisk-oriented file system such as FAT. This storage methodology has\r\nvarious performance and robustness limitations, leading to the\r\ndevelopment of file systems designed specifically for flash memory.\r\nThese are known as flash file systems.</p>\r\n<p class=\"western\">Flash memory has various limitations when compared\r\nwith a disk. For example, flash memory pages cannot be individually\r\nre-written but instead the whole block must be  erased and rewritten\r\nwith the modified page. Typical FTL achieve this with various logical\r\nto physical mapping schemes. Thus emulating disk-like behaviour on\r\nflash memory adds an extra layer of software which slows down write\r\nperformance. Worse still, it adds extra state which is prone to\r\ncorruption due to power failure.</p>\r\n<p class=\"western\">A typical FTL-based solution will use a file\r\nsystem such as FAT. FAT always stores tables in the same disk blocks\r\nand must thus change the same blocks often. Since flash memory blocks\r\ncan endure a limited number of write/erasure cycles, the FTL must\r\nmove the physical location of the block around to prevent  the high\r\ntraffic blocks from wearing out. This requires wear levelling – a\r\nfurther burden.</p>\r\n<p class=\"western\">Some systems try to mitigate against the\r\nperformance penalties by caching a lot of data to reduce writes.\r\nWhile this can go some way towards reducing the apparent write time,\r\nit does make the solution prone to data loss in the event of a power\r\nfailure.</p>\r\n<p class=\"western\">As well as limitations, flash memory also has\r\ncertain advantages when compared to rotating media. There is no spin\r\nup time, making it more responsive. There is no read head so there is\r\nno read penalty if data is fragmented. Flash file systems can be\r\ndesigned to exploit these advantages.</p>\r\n<p class=\"western\">True flash file systems<a class=\"sdfootnoteanc\" name=\"sdfootnote1anc\" href=\"#sdfootnote1sym\"><sup>1</sup></a>,\r\non the other hand, are a single code body designed to take the\r\nfeatures and limitations of flash into consideration. Flash file\r\nsystems can thus be far more “flash friendly”. Well designed\r\nflash file systems will avoid using “flash unfriendly” techniques\r\nsuch as allocation tables and in-place rewriting.</p>\r\n<p class=\"western\">Yaffs is a flash file system, originally designed\r\nspecifically for NAND flash though also used with great success on\r\nNOR flash too. Yaffs development started in 2001 when 32Mbytes of\r\nflash was considered large. Since then, Yaffs has been expanded to\r\nwork properly with different flash types and far larger memory arrays\r\n(many GBytes).</p>\r\n<p class=\"western\">Yaffs was originally deployed in Linux, but was\r\nwritten in an OS neutral way, mainly to facilitate modular\r\ndevelopment and testing. This turned out to be useful when we had\r\nrequests to port Yaffs to other operating systems. Since then, Yaffs\r\nhas been used in many different products in a wide variety of\r\napplications from consumer products such as cell phones and sewing\r\nmachines to aerospace, industrial and medical applications including\r\nprocess control, building management, communications infrastructure\r\nand many others.</p>\r\n<p class=\"western\">Yaffs is not tied to any endian ordering and has\r\nbeen used on a wide variety of architectures including ARM, MIPS,\r\nPowerPC, x86, some DSPs. Yaffs has been deployed using a wide variety\r\nof compilers from many different vendors.</p>\r\n<p class=\"western\">Nor is Yaffs tied to any particular operating\r\nsystem. Yaffs has been used with Linux, eCOS, Windows Embedded\r\nCompact (previously Windows CE), VxWorks and others.</p>\r\n<h1 class=\"western\">2 Flash File System considerations</h1>\r\n<p class=\"western\">There are many criteria that are important when\r\nselecting a flash file system. These are some that out customers have\r\nfound to be most important:</p>\r\n<ul>\r\n	<li/>\r\n<p class=\"western\">Robustness: It really is not worth having a\r\n	file system that loses or corrupts data and prevents the system from\r\n	working properly. Some flash file systems are only robust when\r\n	synced (flushed) after files have been written. That requires extra\r\n	code, slows the system and leaves the file system in a\r\n	non-deterministic state until the sync has been completed. Some file\r\n	systems need to perform disk repair operations (eg. check disk) in\r\n	the event of a power failure. This can add considerable time to the\r\n	start up, preventing the system from being operational.</p>\r\n	<li/>\r\n<p class=\"western\">Performance: In many embedded system\r\n	designs, slow read/write performance can delay tasks and cause\r\n	system degradation or even failure. It is thus important that\r\n	read/write performance be acceptable. Note that many flash file\r\n	systems need to perform extra actions such as garbage collection. In\r\n	some cases these actions can cause the file system to stall for a\r\n	long time. It is thus important that these factors be taken into\r\n	consideration. Performance can sometimes be improved by adding a\r\n	write caching layer. These caching layers make the file system calls\r\n	(write etc) proceed quickly, without actually writing the data to\r\n	flash. This is a two-edged sword as data in the cache will be lost\r\n	on a power failure and syncing the file system will take a long\r\n	time. Thus, most flash file systems offer either speed or robustness\r\n	– not both.</p>\r\n	<li/>\r\n<p class=\"western\">Proven: It is very easy for a file system\r\n	vendor to provide a list of claims saying “100% power safe” or\r\n	similar, but what evidence do they have to back this up? All file\r\n	systems, including flash file systems, are complex bodies of\r\n	software with extremely complex state. They need very significant\r\n	testing to prove that they work correctly.</p>\r\n	<li/>\r\n<p class=\"western\">Portable: Software is a huge investment and\r\n	it is increasingly important to be able to port the software between\r\n	OSs and CPU architectures. Most flash file systems are limited to a\r\n	single operating system which makes it difficult to migrate software\r\n	between different platforms. In Yaffs\' case portability extends to\r\n	being able to seamlessly migrate the core Yaffs code into a test\r\n	framework which enhances testing.</p>\r\n</ul>\r\n<h1 class=\"western\">3 How Yaffs achieves robustness and performance</h1>\r\n<p class=\"western\">Yaffs was designed from the ground up specifically\r\nto work well with NAND flash. The author had already developed\r\nanother flash file system, so was already familiar with the  design\r\nchallenges of flash.</p>\r\n<p class=\"western\">As Yaffs is not just adapting a disk-oriented file\r\nsystem to work with flash it is not surprising that Yaffs is very\r\ndifferent in design to most other file systems. The key difference is\r\nthat Yaffs is a log-structured. file system<a class=\"sdfootnoteanc\" name=\"sdfootnote2anc\" href=\"#sdfootnote2sym\"><sup>2</sup></a>.</p>\r\n<p class=\"western\">In essence, a log structured file system writes\r\nfile system changes as a sequential log.  The log structure is\r\nparticularly suitable for various reasons including:</p>\r\n<ul>\r\n	<li/>\r\n<p class=\"western\">All writes are at the end of the log. When\r\n	a file is modified, there is no need to erase and rewrite a part of\r\n	the flash. Changes are just appended to the log. Thus there is no\r\n	need to erase and copy old data just to change some existing pages\r\n	in a file. This tends to make writes much faster. There is no need\r\n	to do a lot of caching to achieve performance. Data can be written\r\n	to the log immediately meaning that sync time is very low. Data\r\n	robustness is improved dramatically.</p>\r\n	<li/>\r\n<p class=\"western\">There are no allocation tables or similar.\r\n	This reduces the amount of data being written to the flash, and that\r\n	there are no tables to corrupt.</p>\r\n	<li/>\r\n<p class=\"western\">Since all writes are to the end of the log\r\n	there are no “high traffic” blocks. This means Yaffs only needs\r\n	a simpler wear leveling strategy.</p>\r\n	<li/>\r\n<p class=\"western\">In the event of a power failure, the file\r\n	system state is easily re-created from the log. This means there is\r\n	no need to perform disk repair operations to correct for an unclean\r\n	shutdown.</p>\r\n</ul>\r\n<p class=\"western\">So why don\'t we see many log structured file\r\nsystems for disk file systems? The answer to this is that log file\r\nsystems tend to spread the writes around on the media. That is\r\ntypically very problematic for mechanical storage which must\r\nphysically move the read/write head from one location to another\r\nmaking the access time very slow. Of course that does not apply for\r\nflash memory. By designing specifically for flash, Yaffs can ignore\r\nthis issue and write fast.</p>\r\n<p class=\"western\">Many flash file systems need make a compromise\r\nbetween robustness against performance. Thanks to the log structure,\r\nYaffs does not need to. Yaffs can provide high performance without\r\ngiving up on robustness.</p>\r\n<p class=\"western\">Those familiar with log structured file system\r\ndesign will know that some log structured file systems have problems\r\nwith garbage collection<a class=\"sdfootnoteanc\" name=\"sdfootnote3anc\" href=\"#sdfootnote3sym\"><sup>3</sup></a>.\r\nGarbage collection is used to clean up the log and make more free\r\nspace available. Some log structured file system designs did not pay\r\nenough attention to garbage collection and can stall for a\r\nconsiderable time while garbage collection happens. Yaffs was\r\ndesigned differently. The potential impact of garbage collection was\r\nconsidered throughout the Yaffs design process. As a result, Yaffs\r\nhas a very simple garbage collection model that allows a lot of\r\nflexibility in garbage collection scheduling. This prevents the\r\ngarbage collection from making the file system unresponsive.</p>\r\n<p class=\"western\">Most file systems are developed within the\r\ncontext, and framework of, a single operating system. This typically\r\nmakes the code difficult to explore, debug and port. Yaffs on the\r\nother hand was developed from the start inside a portable\r\ndevelopment/testing framework. Yaffs is then ported to various\r\noperating systems through the addition of glue code.</p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\"><img src=\"data:image/png;base64,[encoded data, 38784 characters]\" name=\"Object1\" align=\"left\" width=\"552\" height=\"524\"/>\r\n<br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\">There are many benefits to this approach:</p>\r\n<ul>\r\n	<li/>\r\n<p class=\"western\">A development framework runs in user space\r\n	which provides a richer development environment than inside an OS\r\n	kernel. It is much easier to attach debuggers and perform logging\r\n	and create reproducible testing.</p>\r\n	<li/>\r\n<p class=\"western\">The code is structured to be portable. That\r\n	makes it relatively easy to port to a new OS or RTOS with a high\r\n	level of confidence.</p>\r\n	<li/>\r\n<p class=\"western\">There is a choice of porting interfaces\r\n	allowing more flexibility to determine which porting method will be\r\n	simpler. For example, the Linux wrapper accesses the Yaffs core\r\n	directly while the Windows CE wrapper access the Yaffs Direct\r\n	Interface<a class=\"sdfootnoteanc\" name=\"sdfootnote4anc\" href=\"#sdfootnote4sym\"><sup>4</sup></a>.</p>\r\n	<li/>\r\n<p class=\"western\">Each different environment provides\r\n	different test tools. For example, Linux provides a raft of file\r\n	system test tools that do different kinds of testing to the power\r\n	fail test harness. Since the vast majority of the code is in the\r\n	portable Yaffs core, that code gets the advantage of all test\r\n	methods combined. The many millions of Android phone users that use\r\n	Yaffs-based devices are helping test the core code that is also used\r\n	on a wide variety of different operating systems and a wide range of\r\n	different device types.</p>\r\n	<li/>\r\n<p class=\"western\">Its Open Source status means any interested\r\n	person can take a version from git and test it to make sure that it\r\n	meets their needs.</p>\r\n</ul>\r\n<h1 class=\"western\">4 Testing</h1>\r\n<p class=\"western\">It is all very well to design software to be\r\nrobust, but it needs thorough testing to build confidence in the\r\nsoftware and in the code authors and supplier.</p>\r\n<p class=\"western\">File systems have incredibly complex state so it\r\nis not at all surprising that operating system designers find file\r\nsystems some of the most challenging code to test.</p>\r\n<p class=\"western\">There is no single test methodology that can test\r\nall cases, and exhaustive state testing is impossible. The best we\r\ncan do is to have a suite of test methodologies that combine to\r\nprovide thorough testing.</p>\r\n<p class=\"western\">Approximately 60% of Yaffs development effort is\r\ndirected towards testing and improving the test environment. We are\r\nconstantly researching new methodologies.</p>\r\n<p class=\"western\">The following are descriptions of the most\r\nimportant test strategies used in Yaffs.</p>\r\n<h2 class=\"western\">4.1 Power Fail Stress Testing</h2>\r\n<p class=\"western\">By far the most important consideration in Yaffs\r\ntesting is that it is robust to corruptions caused by power failure.\r\nWe want Yaffs to provide the basis for reliable products in typical\r\nembedded system environments.</p>\r\n<p class=\"western\">The first power fail testing was done by companies\r\nintegrating Yaffs into their products. Some of these built test jigs\r\nwhich would automatically interrupt power while running a real\r\nhardware device. This approach is better than nothing, but has some\r\nlimitations:</p>\r\n<ul>\r\n	<li/>\r\n<p class=\"western\">It is relatively costly to set up. Flash\r\n	has a limited lifetime meaning that test devices wear out with time\r\n	and must be replaced.</p>\r\n	<li/>\r\n<p class=\"western\">It is relatively slow since each cycle\r\n	takes many seconds to boot, run the application for a while and then\r\n	reboot.</p>\r\n	<li/>\r\n<p class=\"western\">Many, and perhaps most, of the power\r\n	interruptions will happen at times when the file system is inactive\r\n	and thus be wasted cycles.</p>\r\n</ul>\r\n<p class=\"western\">In 2008 we developed a simulated power-fail-test\r\nenvironment. This simulates power failures using simulated flash\r\nmemory while running various consistency checks.</p>\r\n<p class=\"western\">The benefits of a software-based test harness are\r\nnumerous:</p>\r\n<ul>\r\n	<li/>\r\n<p class=\"western\">The test harness controls the point at\r\n	which the simulated power failures happen. That means every test\r\n	cycle counts.</p>\r\n	<li/>\r\n<p class=\"western\">No special hardware is required.</p>\r\n	<li/>\r\n<p class=\"western\">Test loops run faster. A quad-core computer\r\n	can simulate ten to twenty power failures per second. That means\r\n	about a million power failure simulations per day.</p>\r\n</ul>\r\n<p class=\"western\">The effectiveness of the new software based\r\ntesting is dramatic.. A few times we have tested some user-suggested\r\nchanges that had passed a week or more of real-world power fail\r\ntesting only to have problems caught by the software simulation in a\r\nmatter of minutes.</p>\r\n<p class=\"western\">We regularly run the power fail simulation test\r\nover a weekend, testing millions of power fail cycles.</p>\r\n<h2 class=\"western\">4.2 Testing the Yaffs Direct Interface API</h2>\r\n<p class=\"western\">Yaffs Direct Interface (YDI) is a POSIX-like\r\nwrapper around the Yaffs core. This provides a set of function calls,\r\nyaffs_open(), yaffs_write() and the like.</p>\r\n<p class=\"western\">Each function can return numerous error codes and\r\nhas to handle numerous different parameters.</p>\r\n<p class=\"western\">Although there were already significant tests for\r\nthe YDI, an extensive test harness was developed in 2010 to\r\ncomprehensively test each of the error paths and generate all of the\r\nrequired errors.</p>\r\n<p class=\"western\">This provides a high level of confidence that the\r\ntest interfaces do what they should and that POSIX-like functionality\r\nprovides relatively clean porting of existing code.</p>\r\n<h2 class=\"western\">4.3 Linux Testing</h2>\r\n<p class=\"western\">The main purpose of the Linux testing is to test\r\nthe Linux wrapper code. It does, however, still exercise the Yaffs\r\ncore code differently to other testing and thus adds to the test\r\nfabric.</p>\r\n<p class=\"western\">The Linux testing does not do power fail testing\r\nbut instead tests other aspects such as clean shutdowns, cache\r\nintegrity and write performance. This gives a useful way to assess\r\nthe effects of modifications.</p>\r\n<p class=\"western\">Linux testing is done on both real hardware and on\r\nsimulated hardware using the Linux mtd nand simulator.</p>\r\n<p class=\"western\">As with the Power Fail Stress Testing described\r\nabove, the simulated testing is done using a scrippted environment\r\nwhich is typically run for a few days at a time.</p>\r\n<h2 class=\"western\">4.4 Fuzz Testing</h2>\r\n<p class=\"western\">Fuzz testing deliberately corrupts the flash image\r\nand ensures that Yaffs still mounts. This is done to ensure that\r\nYaffs does not crash on corrupted data.</p>\r\n<p class=\"western\">Clearly fuzz testing can corrupt the contents of\r\nindividual files (that\'s its job), but the file system integrity\r\nshould not be compromised. \r\n</p>\r\n<h2 class=\"western\">4.5 Software checking</h2>\r\n<p class=\"western\">Although code checking is  not actual testing per\r\nse, it does help to verify code changes.</p>\r\n<p class=\"western\">The Yaffs code has been checked with Coverity<a class=\"sdfootnoteanc\" name=\"sdfootnote5anc\" href=\"#sdfootnote5sym\"><sup>5</sup></a>\r\n– a market leader in code checking.</p>\r\n<p class=\"western\">We are investigating the use of KLEE and other\r\ntools.</p>\r\n<h2 class=\"western\">4.6 Open Source Usage</h2>\r\n<p class=\"western\">Open Source usage of Yaffs opens it up to testing\r\nby the many different projects. Many of these participate in some way\r\nwith the Yaffs mailing list, helping to uncover issues and generally\r\nprovide feedback.</p>\r\n<p class=\"western\">Each different project uses Yaffs in a different\r\nway, meaning that a wider range of operation sequences are tested.</p>\r\n<h2 class=\"western\">4.7 Universities</h2>\r\n<p class=\"western\">Over its lifetime, Yaffs has been used as a\r\nteaching framework for various university course in many different\r\ncounties around the world.</p>\r\n<p class=\"western\">For example, Oregon State and Utah State\r\nUniversities have used Yaffs as a test bench for their post-graduate\r\nsoftware testing courses. They essentially test the test tools by\r\ninjecting errors into the Yaffs code and seeing if these are\r\ndiscovered by the test tools they are testing. Of course this has the\r\nside effect of running these tests over the original Yaffs code too. \r\n</p>\r\n<p class=\"western\">Those interested in test methods are encouraged to\r\nread some of the university papers in the references of this\r\ndocument.</p>\r\n<p class=\"western\">We expect to adopt and extend some of the Oregon\r\nState ideas and use these to extend our in-house test suite.</p>\r\n<h1 class=\"western\">5 Conclusions</h1>\r\n<p class=\"western\">Software development is an iterative process of\r\ndesign and testing. Robust software solutions are only possible with\r\nextensive testing.</p>\r\n<p class=\"western\">Embedded systems increasingly need to store data\r\nin file systems as a critical part of their operation. It is thus\r\nimportant to have a file system that is predictable and robust to\r\npower failure and similar interruptions.</p>\r\n<p class=\"western\">Yaffs has been designed from scratch to be robust\r\nto power failure and that robustness has been verified with a\r\nmulti-pronged test strategy that is continuously being improved.</p>\r\n<h1 class=\"western\" style=\"page-break-before: always\">6References</h1>\r\n<p class=\"western\" align=\"left\">Charles Manning, “How Yaffs\r\nWorks”.<br/>\r\n<a href=\"http://users.actrix.co.nz/manningc/yaffs-docs/HowYaffsWorks.pdf\">http://users.actrix.co.nz/manningc/yaffs-docs/HowYaffsWorks.pdf</a></p>\r\n<p class=\"western\" align=\"left\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\" align=\"left\">A. Groce et al, “Swarm Testing”\r\nfrom Oregon State University, School of EE and Computer Science and\r\nUtah State University, School of Computing,\r\n2011.<br/>\r\n<a href=\"http://www.ct.utah.edu/~regehr/papers/swarm12.pdf\">http://</a><a href=\"http://www.ct.utah.edu/~regehr/papers/swarm12.pdf\">www.ct.utah.edu/~regehr/papers/swarm12.pdf</a></p>\r\n<p class=\"western\" align=\"left\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\" align=\"left\"><em>Wu CH, “Efficient\r\nInitialization and Crash Recovery</em> for. <em>Log</em>-<em>based\r\nFile Systems</em> over Flash Memory” from National Taiwan\r\nUniversity, Dept of Computer Science,<span style=\"font-style: normal\">\r\n2006.<br/>\r\nhttp://</span><cite>www.cis.nctu.edu.tw/~lpchang/papers/SAC_wu_sac06.pdf</cite></p>\r\n<p class=\"western\" align=\"left\" style=\"font-style: normal\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<div id=\"sdfootnote1\">\r\n	<p class=\"sdfootnote-western\"><a class=\"sdfootnotesym\" name=\"sdfootnote1sym\" href=\"#sdfootnote1anc\">1</a>Note\r\n	that flash translation layers (FTLs) are erroneously refered to as\r\n	flash file systems. For example, despite the name, M-Systems TrueFFS\r\n	is not a flash file system but a flash translation layer (FTL).</p>\r\n</div>\r\n<div id=\"sdfootnote2\">\r\n	<p class=\"sdfootnote-western\"><a class=\"sdfootnotesym\" name=\"sdfootnote2sym\" href=\"#sdfootnote2anc\">2</a>This\r\n	document only provides a brief overview of the Yaffs architecture\r\n	and design. The “How Yaffs Works” document provides an in-depth\r\n	explanation of the Yaffs design and architecture.</p>\r\n</div>\r\n<div id=\"sdfootnote3\">\r\n	<p class=\"sdfootnote-western\"><a class=\"sdfootnotesym\" name=\"sdfootnote3sym\" href=\"#sdfootnote3anc\">3</a>Refer\r\n	to the “How Yaffs Works” document to understand the need for\r\n	garbage collection and how Yaffs does garbage collection.</p>\r\n</div>\r\n<div id=\"sdfootnote4\">\r\n	<p class=\"sdfootnote-western\"><a class=\"sdfootnotesym\" name=\"sdfootnote4sym\" href=\"#sdfootnote4anc\">4</a>For\r\n	more information on Yaffs Direct Interface, please read the various\r\n	documents on the subject.</p>\r\n</div>\r\n<div id=\"sdfootnote5\">\r\n	<p class=\"sdfootnote-western\"><a class=\"sdfootnotesym\" name=\"sdfootnote5sym\" href=\"#sdfootnote5anc\">5</a>http://www.coverity.com</p>\r\n</div>\r\n','<p>This document describes some of the important design criteria and design features used to achieve a robust design suitable for modern embedded systems which need to store critical data.&nbsp; The test methodologies are also described.</p>','raw_html'),('what_is_special_about_yaffs',0,426,427,'und',0,'<p>We provide a high level interface with the GPL version of Yaffs, so it\'s easy to use with Linux and other OS\'s that support POSIX.&nbsp; This support includes directories, symbolic and hard links, through standard file system interface calls.</p>\r\n\r\n<p>But when you want to integrate Yaffs directly into your OS or your code, you\'ll most likely want to make use of the Yaffs Direct Interface or other low-level interfaces:</p>\r\n\r\n<ul>\r\n	<li>Application Interface: This is the interface that the application code uses to access the YAFFS file system.</li>\r\n	<li>RTOS Integration Interface: These are the functions that much be provided for YAFFS to access the RTOS system resources.</li>\r\n	<li>NAND Configuration and Access Interface: These are the functions that must be provided for YAFFS to access the NAND flash.</li>\r\n</ul>\r\n\r\n<p>Have a look at the guides in the Documents section, to find out more about <a href=\"/documents\">integrating Yaffs</a>.</p>\r\n','Yaffs has high and low level interfaces, for Posix compliance and more direct use, making it easy to integrate with Linux and other RTOSs.','basic_html'),('what_is_special_about_yaffs',0,427,428,'und',0,'<p>Yaffs is easy to port. It is written in C, with particular attention paid to making it portable.&nbsp;It\'s CPU independent, high/low bit independent (endian neutral)&nbsp;and doesn\'t rely on any particular operating system.&nbsp; Look at the schematic in the <a href=\"/yaffs-overview\">Yaffs Overview</a>&nbsp;to see the relationship of the different elements.</p>\r\n\r\n<p>It\'s already been used under Linux, eCos, VxWorks, Win CE and more.&nbsp;</p>\r\n\r\n<p>Yaffs has been used successfully with many different 32-bit and 64-bit CPUs including MIPS, 68000, many from ARM, ColdFire, PowerPC and x86 variants. Yaffs works with 16-bit CPUs too, but this is less tested and might need some tuning, depending on compiler options.&nbsp;</p>\r\n\r\n<p>We\'ve found it easy to move to different processor architectures because it was designed to do this; as long as your processor is greater than 8-bit, Yaffs should run without needing much work.</p>\r\n\r\n<p>Read&nbsp; <a href=\"http://www.yaffs.net/yaffs-porting-guide\">http://www.yaffs.net/yaffs-porting-guide</a> for more detail.</p>\r\n','Yaffs is OS- and CPU- and Endian-independent. It\'s been designed to be easy to port, and has been ported repeatedly by many users.','basic_html'),('what_is_special_about_yaffs',0,428,429,'und',0,'<p>Yaffs was designed from the ground up for Flash memory. It is best with NAND Flash but can be used with NOR too. It has mechanisms for wear-levelling, and special attention has been paid to the safety of the system even under power-failure. It is works well with MLC Nand, as well as SLC; it is compatible with a wide range of Flash, including Toshiba/Sandisk MLC parts.&nbsp; See also the document &nbsp; Considerations in Using a Flash File System&nbsp; for a discussion of the importance of reliability.</p>\r\n','Yaffs is designed to ensure data safety, whilst offering the advantages of NAND Flash. It works with SLC and MLC NAND Flash and also with NOR Flash. See the document Considerations in Using a Flash File System for a discussion of the importance of reliability.','basic_html'),('what_is_special_about_yaffs',0,433,434,'und',0,'<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>','Yaffs has highly optimised and predictable garbage collection strategies. These give it high performance and make it very deterministic when compared with similar file systems.','full_html'),('what_is_special_about_yaffs',0,434,435,'und',0,'<p>Yaffs has a lower memory footprint than most other log-structured Flash file systems.&nbsp; Because it is log-structured, RAM is required to build up runtime data structures for acceptable performance. As a rule of thumb, Yaffs uses approximately 2 bytes per chunk of NAND flash, where a chunk is typically one page of NAND. For NAND with 512byte pages, a budget of approximately 4kbytes of RAM per 1Mbyte of NAND is usually sensible. And for 2kbyte page devices a budget of approximately 1kbyte per 1Mbyte of NAND usually suffices.</p><p>You can find out details of Yaffs memory use in the document&nbsp; <a href=\"http://www.yaffs.net/documents/how-yaffs-works\">http://www.yaffs.net/documents/how-yaffs-works</a></p>','Yaffs has a smaller memory footprint than most other log-structured Flash file systems.','full_html'),('what_is_special_about_yaffs',0,435,436,'und',0,'<p>Yaffs is adaptable to suit the Flash geometries, caching options, Error Correction strategies and other features that you need.</p><p>Details of the configuration options can be found in the Linux menuconfig compile options tool, and in&nbsp; <a href=\"http://www.yaffs.net/yaffs-tuning-and-configuration\">http://www.yaffs.net/yaffs-tuning-and-configuration</a></p>','Yaffs is highly configurable, making it possible to work with various Flash geometries, Error Correction and caching options according to your needs.','full_html'),('what_is_special_about_yaffs',0,436,437,'und',0,'<p>Yaffs Direct Interface is simple to integrate in a system – only a few interface functions are required. Yaffs also includes a POSIX interface. It has been used with Android, VXWorks, Windows, Linux, bare metal, and more; on ARM (32 and 64), x86 (32 and 64), Atmel, and more. </p><p>You can find details in the Yaffs Direct guide.</p>','Yaffs Direct Interface is simple to integrate in a system &ndash; only a few interface functions are required. Yaffs also includes a POSIX interface. It has been used with Android, VXWorks, Windows, Linux, bare metal, and more; on ARM (32 & 64), x86 (32 & 64), Atmel, and more. ','full_html'),('paper',0,448,464,'und',0,'<h3><em>What Operating System (OS) can you use with Yaffs?</em></h3>\r\n\r\n<p>Yaffs is agnostic about the OS it is used with; it has been used with many different OSs, including Linux, eCos, Windows CE, ThreadX, pSOS and vXworks. It is POSIX-compliant, so commands in an application calling POSIX functions will usually work.</p>\r\n\r\n<p>Windows CE uses the Microsoft file handling model and is not POSIX-like. The difference is handled in the Windows CE wrapper.&nbsp; Contact us for more information.</p>\r\n\r\n<p>Work on closer integration of Yaffs into the Linux kernel started in 2010 and the goal is to have Yaffs merged into the mainline Linux kernel.</p>\r\n\r\n<p>The Yaffs Direct Interface, YDI, is the heart of Yaffs and usually stands between the Application, on one side, and the Flash chips, and any OS, on the other side:-</p>\r\n\r\n<h3><em>What CPU can you use with Yaffs?</em></h3>\r\n\r\n<p>Yaffs has been used with many 32-bit and 64-bit CPUs including MIPS, 68000, ColdFire, PowerPC, x86 variants and many ARM-cored CPUs. It should work with 16-bit CPUs but has not been tested.</p>\r\n\r\n<h3><em>Does Yaffs care Which-Endian the CPU is?</em></h3>\r\n\r\n<p>No, Yaffs works with Big-Endian and Little-Endian CPUs</p>\r\n\r\n<h3><em>How big can the whole file system be, and how big can individual files be?</em></h3>\r\n\r\n<p>Yaffs2, which is now standard, can handle a File System (FS) of many Gigabytes total storage; some people are using it with 6GB satisfactorily.&nbsp;<em>Individual</em>&nbsp;files are currently limited to 2GB. The basic Yaffs architecture can handle larger single files and some changes would be required to support individual files greater than 2G bytes. There is an upper limit of around 32GB with the present 2k bytes granularity of \'chunks\' or page size, and the limit of about 16 million chunks per file.</p>\r\n\r\n<p>A coarser granularity of larger chunks can probably be obtained, with knock-on effects in other parameters like RAM usage.</p>\r\n\r\n<h3><em>How many files can there be?</em></h3>\r\n\r\n<p>There is no hard limit. Available flash and RAM will limit this.</p>\r\n\r\n<h3><em>What about directories etc?</em></h3>\r\n\r\n<p>Yaffs supports many different objects including: directories, regular files, hard links, symbolic links and device nodes.</p>\r\n\r\n<p>Yaffs supports long file names, attributes, extended attributes and Unicode.</p>\r\n\r\n<h3><em>How much RAM does it need?</em></h3>\r\n\r\n<p>This depends particularly on the number of tnodes, which in turn depends on the file size, and is therefore a dynamic variable.</p>\r\n\r\n<p>However, Yaffs compares favourably with other similar systems specialised for Flash, and includes robust error handling.</p>\r\n\r\n<h4><em>How are errors handled?</em></h4>\r\n\r\n<p>Error Correction Code (ECC) is used to correct for single-bit errors.</p>\r\n\r\n<p>ECC may use built-in code or that provided from other sources (flash controllers, ECC libraries etc).</p>\r\n\r\n<p>Yaffs is frequently tested on a \"fuzzer\" test harness. This randomly corrupts bits of the file system image to check that the file system still mounts and loads correctly.</p>\r\n\r\n<h3><em>What about Multi-level cell (MLC) chips?</em></h3>\r\n\r\n<p>Because a bit is represented by a smaller amount of charge in the MLC chip compared to a SLC chip, MLC chips are more prone to corruption than SLC.</p>\r\n\r\n<p>MLC also has various write restrictions, which are obeyed by Yaffs2.</p>\r\n\r\n<p>Yaffs2 has some features such as block refreshing to help alleviate the problems associated with MLC.</p>\r\n\r\n<p>MLC generally requires multi-bit ECC. Hardware ECC is preferred since it is faster and requires less computation than software multi-bit correction..</p>\r\n\r\n<h3><em>How robust is Yaffs ?</em></h3>\r\n\r\n<p>Yaffs is designed specifically to take account of manufacturing faults in, and of accumulated wear in, individual cells, and also to handle power failures during use.</p>\r\n\r\n<p>Yaffs allocates flash blocks in a way that gives statistical or implicit wear levelling; when a block is freed up it is released into a&nbsp;<em>free pool</em>&nbsp;and the next allocation comes from this&nbsp;<em>free pool.&nbsp;</em>This randomness tends to spread the blocks in use, giving some wear levelling, rather than one part of the file always being worked intensively.</p>\r\n\r\n<p>Accelerated lifetime testing has been carried out to seek evidence for excessive wear. For example on one professional PDA-style device used by surveyors in the field we determined that extreme lifetime usage would be:</p>\r\n\r\n<ul>\r\n	<li>20MB per day.</li>\r\n	<li>200 days per year</li>\r\n	<li>10 year lifetime</li>\r\n	<li>Total 40Gbytes lifetime write.</li>\r\n</ul>\r\n\r\n<p>We then ran well over 200Gbytes of writing through a specially designed File System Exerciser, a multi-threaded application that writes, reads, verifies, then deletes, repeatedly. There was no sign of a single bit of corruption at the end of the test.</p>\r\n\r\n<p>Another test applied randomly timed power failures repeatedly while running test code. Millions of cycles have been executed without any errors being observed.</p>\r\n\r\n<p>Yaffs is used (under GPL) in the Android mobile phones sold by Google and others. Extensive use in the field like this helps to ensure its robustness.</p>\r\n\r\n<h3><em>How big is its code?</em></h3>\r\n\r\n<p>That depends on how much of it you need; it is modular in organisation. The innermost or core part is about 11k lines of code, the the Yaffs Direct Interface giving file handle access and a Posix-like interface is around 2k lines.</p>\r\n\r\n<h3>Glossary and useful links.</h3>\r\n\r\n<table>\r\n	<colgroup>\r\n		<col />\r\n		<col />\r\n	</colgroup>\r\n	<tbody>\r\n		<tr>\r\n			<td>\r\n			<p>Big-endian and Little-endian</p>\r\n			</td>\r\n			<td>\r\n			<p>Big-endian is when the most significant data chunk is listed first. Little-endian is when the least significant&nbsp;data chunk&nbsp;is listed first.</p>\r\n\r\n			<p><em>http://en.wikipedia.org/wiki/Endianness</em></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>tnodes</p>\r\n			</td>\r\n			<td>\r\n			<p>Tnodes are yaffs data structures used to build trees that map from a file to the file data chunks stored in flash. A large file will have multiple data chunks scattered throughout the flash and will need a larger tnode tree.</p>\r\n\r\n			<p>See the HowYaffs Works document for more information.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>ECC</p>\r\n			</td>\r\n			<td>\r\n			<p>Error correction codes, See the&nbsp;<em>Yaffs Error mitigation</em>&nbsp;document.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>MLC</p>\r\n			</td>\r\n			<td>\r\n			<p>Multi-level cell, allows more than one bit state to be stored in a memory cell. MLC Flash often allows four state (ie. 2 bits) to be stored in one cell.&nbsp;<em>http://en.wikipedia.org/wiki/Multi-level_cell</em></p>\r\n\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n	</tbody>\r\n</table>\r\n\r\n<p>&nbsp;</p>\r\n','<p>Common questions about Yaffs technical issues.</p>','filtered_html'),('paper',0,448,584,'und',0,'<h3><em>What Operating System (OS) can you use with Yaffs?</em></h3>\r\n\r\n<p>Yaffs is agnostic about the OS it is used with; it has been used with many different OSs, including Linux, eCos, Windows CE, ThreadX, pSOS and vXworks. It is POSIX-compliant, so commands in an application calling POSIX functions will usually work.</p>\r\n\r\n<p>Windows CE uses the Microsoft file handling model and is not POSIX-like. The difference is handled in the Windows CE wrapper.&nbsp; Contact us for more information.</p>\r\n\r\n<p>Work on closer integration of Yaffs into the Linux kernel started in 2010 and the goal is to have Yaffs merged into the mainline Linux kernel.</p>\r\n\r\n<p>The Yaffs Direct Interface, YDI, is the heart of Yaffs and usually stands between the Application, on one side, and the Flash chips, and any OS, on the other side:-</p>\r\n\r\n<h3><em>What CPU can you use with Yaffs?</em></h3>\r\n\r\n<p>Yaffs has been used with many 32-bit and 64-bit CPUs including MIPS, 68000, ColdFire, PowerPC, x86 variants and many ARM-cored CPUs. It should work with 16-bit CPUs but has not been tested.</p>\r\n\r\n<h3><em>Does Yaffs care Which-Endian the CPU is?</em></h3>\r\n\r\n<p>No, Yaffs works with Big-Endian and Little-Endian CPUs</p>\r\n\r\n<h3><em>How big can the whole file system be, and how big can individual files be?</em></h3>\r\n\r\n<p>Yaffs2, which is now standard, can handle a File System (FS) of many Gigabytes total storage; some people are using it with 6GB satisfactorily.&nbsp;<em>Individual</em>&nbsp;files are currently limited to 2GB. The basic Yaffs architecture can handle larger single files and some changes would be required to support individual files greater than 2G bytes. There is an upper limit of around 32GB with the present 2k bytes granularity of \'chunks\' or page size, and the limit of about 16 million chunks per file.</p>\r\n\r\n<p>A coarser granularity of larger chunks can probably be obtained, with knock-on effects in other parameters like RAM usage.</p>\r\n\r\n<h3><em>How many files can there be?</em></h3>\r\n\r\n<p>There is no hard limit. Available flash and RAM will limit this.</p>\r\n\r\n<h3><em>What about directories etc?</em></h3>\r\n\r\n<p>Yaffs supports many different objects including: directories, regular files, hard links, symbolic links and device nodes.</p>\r\n\r\n<p>Yaffs supports long file names, attributes, extended attributes and Unicode.</p>\r\n\r\n<h3><em>How much RAM does it need?</em></h3>\r\n\r\n<p>This depends particularly on the number of tnodes, which in turn depends on the file size, and is therefore a dynamic variable.</p>\r\n\r\n<p>However, Yaffs compares favourably with other similar systems specialised for Flash, and includes robust error handling.</p>\r\n\r\n<h4><em>How are errors handled?</em></h4>\r\n\r\n<p>Error Correction Code (ECC) is used to correct for single-bit errors.</p>\r\n\r\n<p>ECC may use built-in code or that provided from other sources (flash controllers, ECC libraries etc).</p>\r\n\r\n<p>Yaffs is frequently tested on a \"fuzzer\" test harness. This randomly corrupts bits of the file system image to check that the file system still mounts and loads correctly.</p>\r\n\r\n<h3><em>What about Multi-level cell (MLC) chips?</em></h3>\r\n\r\n<p>Because a bit is represented by a smaller amount of charge in the MLC chip compared to a SLC chip, MLC chips are more prone to corruption than SLC.</p>\r\n\r\n<p>MLC also has various write restrictions, which are obeyed by Yaffs2.</p>\r\n\r\n<p>Yaffs2 has some features such as block refreshing to help alleviate the problems associated with MLC.</p>\r\n\r\n<p>MLC generally requires multi-bit ECC. Hardware ECC is preferred since it is faster and requires less computation than software multi-bit correction..</p>\r\n\r\n<h3><em>How robust is Yaffs ?</em></h3>\r\n\r\n<p>Yaffs is designed specifically to take account of manufacturing faults in, and of accumulated wear in, individual cells, and also to handle power failures during use.</p>\r\n\r\n<p>Yaffs allocates flash blocks in a way that gives statistical or implicit wear levelling; when a block is freed up it is released into a&nbsp;<em>free pool</em>&nbsp;and the next allocation comes from this&nbsp;<em>free pool.&nbsp;</em>This randomness tends to spread the blocks in use, giving some wear levelling, rather than one part of the file always being worked intensively.</p>\r\n\r\n<p>Accelerated lifetime testing has been carried out to seek evidence for excessive wear. For example on one professional PDA-style device used by surveyors in the field we determined that extreme lifetime usage would be:</p>\r\n\r\n<ul>\r\n	<li>20MB per day.</li>\r\n	<li>200 days per year</li>\r\n	<li>10 year lifetime</li>\r\n	<li>Total 40Gbytes lifetime write.</li>\r\n</ul>\r\n\r\n<p>We then ran well over 200Gbytes of writing through a specially designed File System Exerciser, a multi-threaded application that writes, reads, verifies, then deletes, repeatedly. There was no sign of a single bit of corruption at the end of the test.</p>\r\n\r\n<p>Another test applied randomly timed power failures repeatedly while running test code. Millions of cycles have been executed without any errors being observed.</p>\r\n\r\n<p>Yaffs is used (under GPL) in the Android mobile phones sold by Google and others. Extensive use in the field like this helps to ensure its robustness.</p>\r\n\r\n<h3><em>How big is its code?</em></h3>\r\n\r\n<p>That depends on how much of it you need; it is modular in organisation. The innermost or core part is about 11k lines of code, the the Yaffs Direct Interface giving file handle access and a Posix-like interface is around 2k lines.</p>\r\n\r\n<h3>Glossary and useful links.</h3>\r\n\r\n<table>\r\n	<colgroup>\r\n		<col />\r\n		<col />\r\n	</colgroup>\r\n	<tbody>\r\n		<tr>\r\n			<td>\r\n			<p>Big-endian and Little-endian</p>\r\n			</td>\r\n			<td>\r\n			<p>Big-endian is when the most significant data chunk is listed first. Little-endian is when the least significant&nbsp;data chunk&nbsp;is listed first.</p>\r\n\r\n			<p><em>http://en.wikipedia.org/wiki/Endianness</em></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>tnodes</p>\r\n			</td>\r\n			<td>\r\n			<p>Tnodes are yaffs data structures used to build trees that map from a file to the file data chunks stored in flash. A large file will have multiple data chunks scattered throughout the flash and will need a larger tnode tree.</p>\r\n\r\n			<p>See the HowYaffs Works document for more information.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>ECC</p>\r\n			</td>\r\n			<td>\r\n			<p>Error correction codes, See the&nbsp;<em>Yaffs Error mitigation</em>&nbsp;document.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>MLC</p>\r\n			</td>\r\n			<td>\r\n			<p>Multi-level cell, allows more than one bit state to be stored in a memory cell. MLC Flash often allows four state (ie. 2 bits) to be stored in one cell.&nbsp;<em>http://en.wikipedia.org/wiki/Multi-level_cell</em></p>\r\n\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n	</tbody>\r\n</table>\r\n\r\n<p>&nbsp;</p>\r\n','<p>Common questions about Yaffs technical issues.</p>','basic_html'),('paper',0,451,467,'und',0,'<p>&nbsp;</p><h2 class=\"western\">1 Yaffs Direct Configuration</h2><p class=\"western\">Yaffs behaviour is dictated by compile time and run-time flags.</p><h3 class=\"western\">1.1 Initialisation Parameters</h3><p class=\"western\">Each yaffs device is configured by a yaffs_DeviceParameterStruct structure which is part of the yaffs_DeviceStruct structure. This contains the following fields:</p><table cellpadding=\"4\" cellspacing=\"0\" width=\"100%\"><colgroup><col width=\"96*\"><col width=\"160*\"></colgroup><tbody><tr valign=\"TOP\"><td style=\"border-top-style: solid; border-top-color: rgb(0, 0, 0); border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0.1cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"38%\"><p class=\"western\">name</p></td><td style=\"border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); padding-top: 0.1cm; padding-right: 0.1cm; padding-bottom: 0.1cm; padding-left: 0.1cm; \" width=\"62%\"><p class=\"western\">An optional name for the device</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"38%\"><p class=\"western\">totalBytesPerChunk</p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"62%\"><p class=\"western\">The number of bytes in the data area of the flash page. If inbandTags is not set then this whole area will be used to store data and the tags will be stored in the spare area. If inbandTags is set then part of this area will be used to store tags and the rest will be used to store data.</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"38%\"><p class=\"western\">spareBytesPerChunk</p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"62%\"><p class=\"western\">The number of available bytes in the spare area of the flash page. This excludes space used by ECC, bad block markers etc.</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"38%\"><p class=\"western\">startBlock</p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"62%\"><p class=\"western\">The first block in the partition to be used. 0 for first block.</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"38%\"><p class=\"western\">endBlock</p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"62%\"><p class=\"western\">The last block in the partition to be used.</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"38%\"><p class=\"western\">&nbsp;</p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"62%\"><p class=\"western\">&nbsp;</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"38%\"><p class=\"western\">nReservedBlocks</p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"62%\"><p class=\"western\">Number of good blocks blocks reserved for garbage collection etc. Needs to be at least 2, but 5 would be a more typical number.</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"38%\"><p class=\"western\">inbandTags</p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"62%\"><p class=\"western\">Yaffs2 only:Flag indicating whether tags should be stored in the data area. If inbandTags is set then the short Op cache must be enabled (ie nShortOpCaches must be non-zero.</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"38%\"><p class=\"western\">useNANDECC</p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"62%\"><p class=\"western\">Yaffs1 only: Flag indicating whether the driver performs ECC. If this is zero then Yaffs will perform ECC.</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"38%\"><p class=\"western\">noTagsECC</p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"62%\"><p class=\"western\">Yaffs2 only: Flag indicating whether the tags have ECC attached to them.</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"38%\"><p class=\"western\">isYaffs2</p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"62%\"><p class=\"western\">Flag indicating if this is using the Yaffs2 mechanism. If this is not set then Yaffs1 mode of operation is provided.</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"38%\"><p class=\"western\">&nbsp;</p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"62%\"><p class=\"western\">&nbsp;</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"38%\"><p class=\"western\">nShortOpCaches</p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"62%\"><p class=\"western\">Number of chunks to store in the short operation cache. Zero disables caching. Typical value is 10 to 20 or so. Caching is required for inband tags.</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"38%\"><p class=\"western\">emptyLostAndFound</p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"62%\"><p class=\"western\">Flag to delete all files in lost and found on mount.</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"38%\"><p class=\"western\">skipCheckpointRead</p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"62%\"><p class=\"western\">Yaffs2 only: Flag to skip reading checkpoint on mount. If set then a re-scan is forced.</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"38%\"><p class=\"western\">skipCheckpointWrite</p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"62%\"><p class=\"western\">Yaffs2 only: Flag to skip writing checkpoint on sync or unmount.</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"38%\"><p class=\"western\">refreshPeriod</p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"62%\"><p class=\"western\">Yaffs2 only: How often Yaffs should do a block refresh. Values less than 10 disable block refreshing. Typical values would be1000.</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"38%\"><p class=\"western\">&nbsp;</p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"62%\"><p class=\"western\">&nbsp;</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"38%\"><p class=\"western\">initialiseNAND</p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"62%\"><p class=\"western\">Pointer to function to initialise flash driver.</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"38%\"><p class=\"western\">deinitialiseNAND</p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"62%\"><p class=\"western\">Pointer to function to de-initialise flash driver</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"38%\"><p class=\"western\">eraseBlockInNAND</p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"62%\"><p class=\"western\">Pointer to function to erase a flash block</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"38%\"><p class=\"western\">&nbsp;</p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"62%\"><p class=\"western\">&nbsp;</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"38%\"><p class=\"western\">writeChunkToNAND</p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"62%\"><p class=\"western\">Yaffs1 only: Pointer to function to write a chunk</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"38%\"><p class=\"western\">readChunkFromNAND</p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"62%\"><p class=\"western\">Yaffs1 only: Pointer to function to read a chunk.</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"38%\"><p class=\"western\">&nbsp;</p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"62%\"><p class=\"western\">&nbsp;</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"38%\"><p class=\"western\">writeChunkWithTagsToNAND</p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"62%\"><p class=\"western\">Yaffs2 only: Pointer to function to write a chunk plus tags</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"38%\"><p class=\"western\">readChunkWithTagsFromNAND</p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"62%\"><p class=\"western\">Yaffs2 only: Pointer to function to read a chunk plus tags</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"38%\"><p class=\"western\">markNANDBlockBad</p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"62%\"><p class=\"western\">Yaffs2 only: Function to mark a block bad</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"38%\"><p class=\"western\">queryNANDBlock</p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"62%\"><p class=\"western\">Yaffs2 only: Function to query a block state</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"38%\"><p class=\"western\">&nbsp;</p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"62%\"><p class=\"western\">&nbsp;</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"38%\"><p class=\"western\">gcControl</p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"62%\"><p class=\"western\">Callback function that returns the garbage collector control flags. This is optional.</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"38%\"><p class=\"western\">removeObjectCallback</p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"62%\"><p class=\"western\">Callback function called when an object is removed. This is set by the wrapper.</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"38%\"><p class=\"western\">markSuperBlockDirty</p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"62%\"><p class=\"western\">Callback function that is called when a clean file system is first modified. This is set by the wrapper.</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"38%\"><p class=\"western\">&nbsp;</p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"62%\"><p class=\"western\">&nbsp;</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"38%\"><p class=\"western\">disableSoftDelete</p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"62%\"><p class=\"western\">Yaffs1 only. Debug only. Disables soft deletion if non-zero.</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"38%\"><p class=\"western\">&nbsp;</p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"62%\"><p class=\"western\">&nbsp;</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"38%\"><p class=\"western\">useHeaderFileSize</p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"62%\"><p class=\"western\">Debug only. Leave as zero</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"38%\"><p class=\"western\">disableLazyLoading</p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"62%\"><p class=\"western\">Debug only. Leave as zero.</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"38%\"><p class=\"western\">wideTnodeDisabled</p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"62%\"><p class=\"western\">Debug only. Leave as zero.</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"38%\"><p class=\"western\">&nbsp;</p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"62%\"><p class=\"western\">&nbsp;</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"38%\"><p class=\"western\">deferDirectoryUpdate</p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"62%\"><p class=\"western\">Used to defer directory updates.</p></td></tr></tbody></table><p class=\"western\">&nbsp;</p><h3 class=\"western\">1.2 Compile-time settings</h3><p class=\"western\">These setting are used to apply compile-time configurations.</p><p class=\"western\">CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED</p><p class=\"western\">Normally Yaffs checks that chunks are erased only on the first chunk write to each block. This flag allows you to force all chunks to be checked. This is slower, but is worth using when doing early debugging.</p><p class=\"western\">CONFIG_YAFFS_CASE_INSENSITIVE</p><p class=\"western\">When selected case insensitive name comparisons are used. Note that this will not magically change Yaffs to be case insensitive in a case sensitive OS. This needs to be set according to the OS policy. Typically this is only used in Windows CE.</p><p class=\"western\">CONFIG_YAFFS_DIRECT</p><p class=\"western\">Used when compiling Yaffs Direct.</p><p class=\"western\">CONFIG_YAFFS_DISABLE_LAZY_LOAD</p><p class=\"western\">Lazy loading is used to defer loading up object details until the objects are accessed. This makes mount time faster. This flag can disable lazy loading. Debug only.</p><p class=\"western\">CONFIG_YAFFS_ECC_WRONG_ORDER</p><p class=\"western\">This flag should only be used with old Linux MTD code which had a bug in the ECC byte ordering.</p><p class=\"western\">CONFIG_YAFFS_NO_YAFFS1</p><p class=\"western\">Used to say that only Yaffs2 operation should be compiled in. Not currently supported.</p><p class=\"western\">CONFIG_YAFFS_SHORT_NAMES_IN_RAM</p><p class=\"western\">Set to configure Yaffs to store short object names in RAM. This is faster, but uses up more memory.</p><p class=\"western\">CONFIG_YAFFS_UNICODE</p><p class=\"western\">Set to configure Yaffs to use Unicode file names (eg. With WinCE).</p><p class=\"western\">CONFIG_YAFFS_USE_OWN_SORT</p><p class=\"western\">By default, Yaffs uses qsort for sorting blocks at mount scanning time. This is faster. Using this flag forces Yaffs to use a slow internal sort instead. Debug only.</p><p class=\"western\">CONFIG_YAFFS_UTIL</p><p class=\"western\">Used when compiling Yaffs for utilities.</p><p class=\"western\">CONFIG_YAFFS_WINCE</p><p class=\"western\">Set when compiling Yaffs for WinCE.</p><p class=\"western\">CONFIG_YAFFS_YAFFS2</p><p class=\"western\">Set when using Yaffs2 mode. At present this must always be set.</p><p class=\"western\">CONFIG_YAFFSFS_PROVIDE_VALUES</p><p class=\"western\">Used when compiling Yaffs Direct only.</p><h3 class=\"western\">2 Tracing mechanism</h3><p class=\"western\">Yaffs has a lot of built in tracing to help debug and integrate. The tracing is controlled by yaffs_traceMask bitmask which allows various sets of tracing to be disabled or enabled at runtime.</p><p class=\"western\">The trace bits are specified in the yaffs_trace.h file.</p><p class=\"western\">The tracing mechanism has also been \'hijacked\' to provide a control mask for extra verification code when the YAFFS_TRACE_VERIFYxxx trace bits are selected.</p><p class=\"western\">The tracing mechanism is readily integrated into the system via printf-like statements. Tracing is all done through macros which allow the strings to be converted into unicode or similar if need be.</p><h2 class=\"western\" style=\"page-break-before: always; \">3 Linux</h2><h3 class=\"western\">3.1 Linux compile-time flags</h3><p class=\"western\">The Linux compile time flags are documented in the Kconfig file and will not be duplicated here.</p><h3 class=\"western\">3.2 Linux: /proc/yaffs trace adjustment</h3><p class=\"western\">Under Linux, the tracing mechanism is hooked up to both the /proc/yaffs and the sys interface. The /proc/yaffs interface is very user friendly.</p><p class=\"code-western\"><code class=\"western\">#cat +os &gt; /proc/yaffs # Enables YAFFS_TRACE_OS<br>#cat -all+gc &gt; /proc/yaffs # Disables everything then enable YAFFS_TRACE_GC<br>#cat 0xf000 &gt; /proc/yaffs # Set trace mask to specified bitmask.</code></p><h3 class=\"western\">3.3 Linux: /sys/ interface</h3><p class=\"western\">The Linux /sys/ interface is used by many Linux OS components to access the state of control variables. Some Yaffs variables are available via /sys/module/yaffs2/parameters/ *. Values can be read and modified using standard shell commands or from application programs.</p><p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\"># ls /sys/module/yaffs2/parameters/ yaffs_auto_checkpoint yaffs_traceMask yaffs_wr_attempts<br># cat /sys/module/yaffs2/parameters/yaffs_auto_checkpoint 1<br># echo \"2\" &gt; /sys/module/yaffs2/parameters/yaffs_auto_checkpoint<br># cat /sys/module/yaffs2/parameters/yaffs_auto_checkpoint 2 </font></code></p><p class=\"western\">Yaffs currently supports the following variables:</p><p class=\"western\">yaffs_auto_checkpoint: Controls when checkpoints should be written.</p><p class=\"western\">yaffs_traceMask: An alternative, and less user friendly,interface to modify tracing.</p><p class=\"western\">yaffs_wr_attempts: The number of attempts that Yaffs will make to write a chunk.</p><p class=\"western\">yaffs_gc_control: Controls the garbage collector.</p><h3 class=\"western\">3.4 Linux: /proc/yaffs state dumping</h3><p class=\"western\">Some of the state of Yaffs mounts can be determined by reading the /proc/yaffs entry.</p><p class=\"code-western\"><code class=\"western\"># cat /proc/yaffs<br>charles@charles-laptop:/opt/y/cvs/yaffs2$ cat /proc/yaffs<br>YAFFS built:Mar 16 2010 11:52:25<br>$Id: yaffs_fs.c,v 1.101 2010-03-15 22:27:15 charles Exp $<br>$Id: yaffs_guts.c,v 1.119 2010-03-12 02:48:34 charles Exp $<br><br>Device 0 \"NAND simulator partition 0\" </code><br><code class=\"western\">startBlock......... 0<br>endBlock........... 511<br>totalBytesPerChunk. 2048<br>useNANDECC......... 1<br>noTagsECC.......... 0<br>isYaffs2........... 1<br>inbandTags......... 0<br>emptyLostAndFound.. 1<br>disableLazyLoad.... 0<br>refreshPeriod...... 10000<br>nShortOpCaches..... 10<br>nReservedBlocks.... 5<br><br>nDataBytesPerChunk. 2048<br>chunkGroupBits..... 0<br>chunkGroupSize..... 1<br>nErasedBlocks...... 152<br>blocksInCheckpoint. 0<br><br>nTnodesCreated..... 2300<br>nFreeTnodes........ 1852<br>nObjectsCreated.... 2300<br>nFreeObjects....... 1842<br>nFreeChunks........ 27843<br><br>nPageWrites........ 65993<br>nPageReads......... 19631<br>nBlockErasures..... 1133<br>nGCCopies.......... 37<br>garbageCollections. 161<br>passiveGCs......... 137<br>nRetriedWrites..... 0<br>nRetireBlocks...... 0<br>eccFixed........... 0<br>eccUnfixed......... 0<br>tagsEccFixed....... 0<br>tagsEccUnfixed..... 0<br>cacheHits.......... 44110<br>nDeletedFiles...... 0<br>nUnlinkedFiles..... 42917<br>refreshCount....... 1<br>nBackgroudDeletions 0</code></p><p class=\"code-western\">&nbsp;</p><h2 class=\"western\">4 Conclusions</h2><p class=\"western\">Yaffs includes many options for changing speed or memory use, with specific flags for the Yaffs Direct Interface as well as Linux. Under Linux many of the control variables can be altered using standard Linux systems.</p>','<p>YAFFS has a wide variety of settings that are used for tuning it to various applications, as well as debugging settings to help with integration. This document helps to explain those settings for Yaffs Direct and Linux, covering compile time flags and settings, initialisation parameters, tracing, and state inspection.&nbsp;The latest PDF of the document is found <a href=\"/sites/yaffs.net/files/YaffsTuning.pd\">HERE</a>.</p>','filtered_html'),('paper',0,451,526,'und',0,'<p>&nbsp;</p>\r\n\r\n<h2>1 Yaffs Direct Configuration</h2>\r\n\r\n<p>Yaffs behaviour is dictated by compile time and run-time flags.</p>\r\n\r\n<h3>1.1 Initialisation Parameters</h3>\r\n\r\n<p>Each yaffs device is configured by a yaffs_DeviceParameterStruct structure which is part of the yaffs_DeviceStruct structure. This contains the following fields:</p>\r\n\r\n<table>\r\n	<colgroup>\r\n		<col />\r\n		<col />\r\n	</colgroup>\r\n	<tbody>\r\n		<tr>\r\n			<td>\r\n			<p>name</p>\r\n			</td>\r\n			<td>\r\n			<p>An optional name for the device</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>totalBytesPerChunk</p>\r\n			</td>\r\n			<td>\r\n			<p>The number of bytes in the data area of the flash page. If inbandTags is not set then this whole area will be used to store data and the tags will be stored in the spare area. If inbandTags is set then part of this area will be used to store tags and the rest will be used to store data.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>spareBytesPerChunk</p>\r\n			</td>\r\n			<td>\r\n			<p>The number of available bytes in the spare area of the flash page. This excludes space used by ECC, bad block markers etc.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>startBlock</p>\r\n			</td>\r\n			<td>\r\n			<p>The first block in the partition to be used. 0 for first block.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>endBlock</p>\r\n			</td>\r\n			<td>\r\n			<p>The last block in the partition to be used.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>nReservedBlocks</p>\r\n			</td>\r\n			<td>\r\n			<p>Number of good blocks blocks reserved for garbage collection etc. Needs to be at least 2, but 5 would be a more typical number.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>inbandTags</p>\r\n			</td>\r\n			<td>\r\n			<p>Yaffs2 only:Flag indicating whether tags should be stored in the data area. If inbandTags is set then the short Op cache must be enabled (ie nShortOpCaches must be non-zero.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>useNANDECC</p>\r\n			</td>\r\n			<td>\r\n			<p>Yaffs1 only: Flag indicating whether the driver performs ECC. If this is zero then Yaffs will perform ECC.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>noTagsECC</p>\r\n			</td>\r\n			<td>\r\n			<p>Yaffs2 only: Flag indicating whether the tags have ECC attached to them.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>isYaffs2</p>\r\n			</td>\r\n			<td>\r\n			<p>Flag indicating if this is using the Yaffs2 mechanism. If this is not set then Yaffs1 mode of operation is provided.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>nShortOpCaches</p>\r\n			</td>\r\n			<td>\r\n			<p>Number of chunks to store in the short operation cache. Zero disables caching. Typical value is 10 to 20 or so. Caching is required for inband tags.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>emptyLostAndFound</p>\r\n			</td>\r\n			<td>\r\n			<p>Flag to delete all files in lost and found on mount.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>skipCheckpointRead</p>\r\n			</td>\r\n			<td>\r\n			<p>Yaffs2 only: Flag to skip reading checkpoint on mount. If set then a re-scan is forced.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>skipCheckpointWrite</p>\r\n			</td>\r\n			<td>\r\n			<p>Yaffs2 only: Flag to skip writing checkpoint on sync or unmount.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>refreshPeriod</p>\r\n			</td>\r\n			<td>\r\n			<p>Yaffs2 only: How often Yaffs should do a block refresh. Values less than 10 disable block refreshing. Typical values would be1000.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>initialiseNAND</p>\r\n			</td>\r\n			<td>\r\n			<p>Pointer to function to initialise flash driver.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>deinitialiseNAND</p>\r\n			</td>\r\n			<td>\r\n			<p>Pointer to function to de-initialise flash driver</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>eraseBlockInNAND</p>\r\n			</td>\r\n			<td>\r\n			<p>Pointer to function to erase a flash block</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>writeChunkToNAND</p>\r\n			</td>\r\n			<td>\r\n			<p>Yaffs1 only: Pointer to function to write a chunk</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>readChunkFromNAND</p>\r\n			</td>\r\n			<td>\r\n			<p>Yaffs1 only: Pointer to function to read a chunk.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>writeChunkWithTagsToNAND</p>\r\n			</td>\r\n			<td>\r\n			<p>Yaffs2 only: Pointer to function to write a chunk plus tags</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>readChunkWithTagsFromNAND</p>\r\n			</td>\r\n			<td>\r\n			<p>Yaffs2 only: Pointer to function to read a chunk plus tags</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>markNANDBlockBad</p>\r\n			</td>\r\n			<td>\r\n			<p>Yaffs2 only: Function to mark a block bad</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>queryNANDBlock</p>\r\n			</td>\r\n			<td>\r\n			<p>Yaffs2 only: Function to query a block state</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>gcControl</p>\r\n			</td>\r\n			<td>\r\n			<p>Callback function that returns the garbage collector control flags. This is optional.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>removeObjectCallback</p>\r\n			</td>\r\n			<td>\r\n			<p>Callback function called when an object is removed. This is set by the wrapper.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>markSuperBlockDirty</p>\r\n			</td>\r\n			<td>\r\n			<p>Callback function that is called when a clean file system is first modified. This is set by the wrapper.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>disableSoftDelete</p>\r\n			</td>\r\n			<td>\r\n			<p>Yaffs1 only. Debug only. Disables soft deletion if non-zero.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>useHeaderFileSize</p>\r\n			</td>\r\n			<td>\r\n			<p>Debug only. Leave as zero</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>disableLazyLoading</p>\r\n			</td>\r\n			<td>\r\n			<p>Debug only. Leave as zero.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>wideTnodeDisabled</p>\r\n			</td>\r\n			<td>\r\n			<p>Debug only. Leave as zero.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>deferDirectoryUpdate</p>\r\n			</td>\r\n			<td>\r\n			<p>Used to defer directory updates.</p>\r\n			</td>\r\n		</tr>\r\n	</tbody>\r\n</table>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<h3>1.2 Compile-time settings</h3>\r\n\r\n<p>These setting are used to apply compile-time configurations.</p>\r\n\r\n<p>CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED</p>\r\n\r\n<p>Normally Yaffs checks that chunks are erased only on the first chunk write to each block. This flag allows you to force all chunks to be checked. This is slower, but is worth using when doing early debugging.</p>\r\n\r\n<p>CONFIG_YAFFS_CASE_INSENSITIVE</p>\r\n\r\n<p>When selected case insensitive name comparisons are used. Note that this will not magically change Yaffs to be case insensitive in a case sensitive OS. This needs to be set according to the OS policy. Typically this is only used in Windows CE.</p>\r\n\r\n<p>CONFIG_YAFFS_DIRECT</p>\r\n\r\n<p>Used when compiling Yaffs Direct.</p>\r\n\r\n<p>CONFIG_YAFFS_DISABLE_LAZY_LOAD</p>\r\n\r\n<p>Lazy loading is used to defer loading up object details until the objects are accessed. This makes mount time faster. This flag can disable lazy loading. Debug only.</p>\r\n\r\n<p>CONFIG_YAFFS_ECC_WRONG_ORDER</p>\r\n\r\n<p>This flag should only be used with old Linux MTD code which had a bug in the ECC byte ordering.</p>\r\n\r\n<p>CONFIG_YAFFS_NO_YAFFS1</p>\r\n\r\n<p>Used to say that only Yaffs2 operation should be compiled in. Not currently supported.</p>\r\n\r\n<p>CONFIG_YAFFS_SHORT_NAMES_IN_RAM</p>\r\n\r\n<p>Set to configure Yaffs to store short object names in RAM. This is faster, but uses up more memory.</p>\r\n\r\n<p>CONFIG_YAFFS_UNICODE</p>\r\n\r\n<p>Set to configure Yaffs to use Unicode file names (eg. With WinCE).</p>\r\n\r\n<p>CONFIG_YAFFS_USE_OWN_SORT</p>\r\n\r\n<p>By default, Yaffs uses qsort for sorting blocks at mount scanning time. This is faster. Using this flag forces Yaffs to use a slow internal sort instead. Debug only.</p>\r\n\r\n<p>CONFIG_YAFFS_UTIL</p>\r\n\r\n<p>Used when compiling Yaffs for utilities.</p>\r\n\r\n<p>CONFIG_YAFFS_WINCE</p>\r\n\r\n<p>Set when compiling Yaffs for WinCE.</p>\r\n\r\n<p>CONFIG_YAFFS_YAFFS2</p>\r\n\r\n<p>Set when using Yaffs2 mode. At present this must always be set.</p>\r\n\r\n<p>CONFIG_YAFFSFS_PROVIDE_VALUES</p>\r\n\r\n<p>Used when compiling Yaffs Direct only.</p>\r\n\r\n<h3>2 Tracing mechanism</h3>\r\n\r\n<p>Yaffs has a lot of built in tracing to help debug and integrate. The tracing is controlled by yaffs_traceMask bitmask which allows various sets of tracing to be disabled or enabled at runtime.</p>\r\n\r\n<p>The trace bits are specified in the yaffs_trace.h file.</p>\r\n\r\n<p>The tracing mechanism has also been \'hijacked\' to provide a control mask for extra verification code when the YAFFS_TRACE_VERIFYxxx trace bits are selected.</p>\r\n\r\n<p>The tracing mechanism is readily integrated into the system via printf-like statements. Tracing is all done through macros which allow the strings to be converted into unicode or similar if need be.</p>\r\n\r\n<h2>3 Linux</h2>\r\n\r\n<h3>3.1 Linux compile-time flags</h3>\r\n\r\n<p>The Linux compile time flags are documented in the Kconfig file and will not be duplicated here.</p>\r\n\r\n<h3>3.2 Linux: /proc/yaffs trace adjustment</h3>\r\n\r\n<p>Under Linux, the tracing mechanism is hooked up to both the /proc/yaffs and the sys interface. The /proc/yaffs interface is very user friendly.</p>\r\n\r\n<p><code>#cat +os &gt; /proc/yaffs # Enables YAFFS_TRACE_OS<br />\r\n#cat -all+gc &gt; /proc/yaffs # Disables everything then enable YAFFS_TRACE_GC<br />\r\n#cat 0xf000 &gt; /proc/yaffs # Set trace mask to specified bitmask.</code></p>\r\n\r\n<h3>3.3 Linux: /sys/ interface</h3>\r\n\r\n<p>The Linux /sys/ interface is used by many Linux OS components to access the state of control variables. Some Yaffs variables are available via /sys/module/yaffs2/parameters/ *. Values can be read and modified using standard shell commands or from application programs.</p>\r\n\r\n<p><code># ls /sys/module/yaffs2/parameters/ yaffs_auto_checkpoint yaffs_traceMask yaffs_wr_attempts<br />\r\n# cat /sys/module/yaffs2/parameters/yaffs_auto_checkpoint 1<br />\r\n# echo \"2\" &gt; /sys/module/yaffs2/parameters/yaffs_auto_checkpoint<br />\r\n# cat /sys/module/yaffs2/parameters/yaffs_auto_checkpoint 2 </code></p>\r\n\r\n<p>Yaffs currently supports the following variables:</p>\r\n\r\n<p>yaffs_auto_checkpoint: Controls when checkpoints should be written.</p>\r\n\r\n<p>yaffs_traceMask: An alternative, and less user friendly,interface to modify tracing.</p>\r\n\r\n<p>yaffs_wr_attempts: The number of attempts that Yaffs will make to write a chunk.</p>\r\n\r\n<p>yaffs_gc_control: Controls the garbage collector.</p>\r\n\r\n<h3>3.4 Linux: /proc/yaffs state dumping</h3>\r\n\r\n<p>Some of the state of Yaffs mounts can be determined by reading the /proc/yaffs entry.</p>\r\n\r\n<p><code># cat /proc/yaffs<br />\r\ncharles@charles-laptop:/opt/y/cvs/yaffs2$ cat /proc/yaffs<br />\r\nYAFFS built:Mar 16 2010 11:52:25<br />\r\n$Id: yaffs_fs.c,v 1.101 2010-03-15 22:27:15 charles Exp $<br />\r\n$Id: yaffs_guts.c,v 1.119 2010-03-12 02:48:34 charles Exp $<br />\r\n<br />\r\nDevice 0 \"NAND simulator partition 0\" </code><br />\r\n<code>startBlock......... 0<br />\r\nendBlock........... 511<br />\r\ntotalBytesPerChunk. 2048<br />\r\nuseNANDECC......... 1<br />\r\nnoTagsECC.......... 0<br />\r\nisYaffs2........... 1<br />\r\ninbandTags......... 0<br />\r\nemptyLostAndFound.. 1<br />\r\ndisableLazyLoad.... 0<br />\r\nrefreshPeriod...... 10000<br />\r\nnShortOpCaches..... 10<br />\r\nnReservedBlocks.... 5<br />\r\n<br />\r\nnDataBytesPerChunk. 2048<br />\r\nchunkGroupBits..... 0<br />\r\nchunkGroupSize..... 1<br />\r\nnErasedBlocks...... 152<br />\r\nblocksInCheckpoint. 0<br />\r\n<br />\r\nnTnodesCreated..... 2300<br />\r\nnFreeTnodes........ 1852<br />\r\nnObjectsCreated.... 2300<br />\r\nnFreeObjects....... 1842<br />\r\nnFreeChunks........ 27843<br />\r\n<br />\r\nnPageWrites........ 65993<br />\r\nnPageReads......... 19631<br />\r\nnBlockErasures..... 1133<br />\r\nnGCCopies.......... 37<br />\r\ngarbageCollections. 161<br />\r\npassiveGCs......... 137<br />\r\nnRetriedWrites..... 0<br />\r\nnRetireBlocks...... 0<br />\r\neccFixed........... 0<br />\r\neccUnfixed......... 0<br />\r\ntagsEccFixed....... 0<br />\r\ntagsEccUnfixed..... 0<br />\r\ncacheHits.......... 44110<br />\r\nnDeletedFiles...... 0<br />\r\nnUnlinkedFiles..... 42917<br />\r\nrefreshCount....... 1<br />\r\nnBackgroudDeletions 0</code></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<h2>4 Conclusions</h2>\r\n\r\n<p>Yaffs includes many options for changing speed or memory use, with specific flags for the Yaffs Direct Interface as well as Linux. Under Linux many of the control variables can be altered using standard Linux systems.</p>\r\n','<p>YAFFS has a wide variety of settings that are used for tuning it to various applications, as well as debugging settings to help with integration. This document helps to explain those settings for Yaffs Direct and Linux, covering compile time flags and settings, initialisation parameters, tracing, and state inspection.&nbsp;The latest PDF of the document is found <a href=\"/sites/yaffs.net/files/YaffsTuning.pd\">HERE</a>.</p>','filtered_html'),('paper',0,451,585,'und',0,'<p>&nbsp;</p>\r\n\r\n<h2>1 Yaffs Direct Configuration</h2>\r\n\r\n<p>Yaffs behaviour is dictated by compile time and run-time flags.</p>\r\n\r\n<h3>1.1 Initialisation Parameters</h3>\r\n\r\n<p>Each yaffs device is configured by a yaffs_DeviceParameterStruct structure which is part of the yaffs_DeviceStruct structure. This contains the following fields:</p>\r\n\r\n<table>\r\n	<colgroup>\r\n		<col />\r\n		<col />\r\n	</colgroup>\r\n	<tbody>\r\n		<tr>\r\n			<td>\r\n			<p>name</p>\r\n			</td>\r\n			<td>\r\n			<p>An optional name for the device</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>totalBytesPerChunk</p>\r\n			</td>\r\n			<td>\r\n			<p>The number of bytes in the data area of the flash page. If inbandTags is not set then this whole area will be used to store data and the tags will be stored in the spare area. If inbandTags is set then part of this area will be used to store tags and the rest will be used to store data.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>spareBytesPerChunk</p>\r\n			</td>\r\n			<td>\r\n			<p>The number of available bytes in the spare area of the flash page. This excludes space used by ECC, bad block markers etc.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>startBlock</p>\r\n			</td>\r\n			<td>\r\n			<p>The first block in the partition to be used. 0 for first block.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>endBlock</p>\r\n			</td>\r\n			<td>\r\n			<p>The last block in the partition to be used.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>nReservedBlocks</p>\r\n			</td>\r\n			<td>\r\n			<p>Number of good blocks blocks reserved for garbage collection etc. Needs to be at least 2, but 5 would be a more typical number.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>inbandTags</p>\r\n			</td>\r\n			<td>\r\n			<p>Yaffs2 only:Flag indicating whether tags should be stored in the data area. If inbandTags is set then the short Op cache must be enabled (ie nShortOpCaches must be non-zero.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>useNANDECC</p>\r\n			</td>\r\n			<td>\r\n			<p>Yaffs1 only: Flag indicating whether the driver performs ECC. If this is zero then Yaffs will perform ECC.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>noTagsECC</p>\r\n			</td>\r\n			<td>\r\n			<p>Yaffs2 only: Flag indicating whether the tags have ECC attached to them.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>isYaffs2</p>\r\n			</td>\r\n			<td>\r\n			<p>Flag indicating if this is using the Yaffs2 mechanism. If this is not set then Yaffs1 mode of operation is provided.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>nShortOpCaches</p>\r\n			</td>\r\n			<td>\r\n			<p>Number of chunks to store in the short operation cache. Zero disables caching. Typical value is 10 to 20 or so. Caching is required for inband tags.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>emptyLostAndFound</p>\r\n			</td>\r\n			<td>\r\n			<p>Flag to delete all files in lost and found on mount.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>skipCheckpointRead</p>\r\n			</td>\r\n			<td>\r\n			<p>Yaffs2 only: Flag to skip reading checkpoint on mount. If set then a re-scan is forced.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>skipCheckpointWrite</p>\r\n			</td>\r\n			<td>\r\n			<p>Yaffs2 only: Flag to skip writing checkpoint on sync or unmount.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>refreshPeriod</p>\r\n			</td>\r\n			<td>\r\n			<p>Yaffs2 only: How often Yaffs should do a block refresh. Values less than 10 disable block refreshing. Typical values would be1000.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>initialiseNAND</p>\r\n			</td>\r\n			<td>\r\n			<p>Pointer to function to initialise flash driver.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>deinitialiseNAND</p>\r\n			</td>\r\n			<td>\r\n			<p>Pointer to function to de-initialise flash driver</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>eraseBlockInNAND</p>\r\n			</td>\r\n			<td>\r\n			<p>Pointer to function to erase a flash block</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>writeChunkToNAND</p>\r\n			</td>\r\n			<td>\r\n			<p>Yaffs1 only: Pointer to function to write a chunk</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>readChunkFromNAND</p>\r\n			</td>\r\n			<td>\r\n			<p>Yaffs1 only: Pointer to function to read a chunk.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>writeChunkWithTagsToNAND</p>\r\n			</td>\r\n			<td>\r\n			<p>Yaffs2 only: Pointer to function to write a chunk plus tags</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>readChunkWithTagsFromNAND</p>\r\n			</td>\r\n			<td>\r\n			<p>Yaffs2 only: Pointer to function to read a chunk plus tags</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>markNANDBlockBad</p>\r\n			</td>\r\n			<td>\r\n			<p>Yaffs2 only: Function to mark a block bad</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>queryNANDBlock</p>\r\n			</td>\r\n			<td>\r\n			<p>Yaffs2 only: Function to query a block state</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>gcControl</p>\r\n			</td>\r\n			<td>\r\n			<p>Callback function that returns the garbage collector control flags. This is optional.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>removeObjectCallback</p>\r\n			</td>\r\n			<td>\r\n			<p>Callback function called when an object is removed. This is set by the wrapper.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>markSuperBlockDirty</p>\r\n			</td>\r\n			<td>\r\n			<p>Callback function that is called when a clean file system is first modified. This is set by the wrapper.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>disableSoftDelete</p>\r\n			</td>\r\n			<td>\r\n			<p>Yaffs1 only. Debug only. Disables soft deletion if non-zero.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>useHeaderFileSize</p>\r\n			</td>\r\n			<td>\r\n			<p>Debug only. Leave as zero</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>disableLazyLoading</p>\r\n			</td>\r\n			<td>\r\n			<p>Debug only. Leave as zero.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>wideTnodeDisabled</p>\r\n			</td>\r\n			<td>\r\n			<p>Debug only. Leave as zero.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>deferDirectoryUpdate</p>\r\n			</td>\r\n			<td>\r\n			<p>Used to defer directory updates.</p>\r\n			</td>\r\n		</tr>\r\n	</tbody>\r\n</table>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<h3>1.2 Compile-time settings</h3>\r\n\r\n<p>These setting are used to apply compile-time configurations.</p>\r\n\r\n<p>CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED</p>\r\n\r\n<p>Normally Yaffs checks that chunks are erased only on the first chunk write to each block. This flag allows you to force all chunks to be checked. This is slower, but is worth using when doing early debugging.</p>\r\n\r\n<p>CONFIG_YAFFS_CASE_INSENSITIVE</p>\r\n\r\n<p>When selected case insensitive name comparisons are used. Note that this will not magically change Yaffs to be case insensitive in a case sensitive OS. This needs to be set according to the OS policy. Typically this is only used in Windows CE.</p>\r\n\r\n<p>CONFIG_YAFFS_DIRECT</p>\r\n\r\n<p>Used when compiling Yaffs Direct.</p>\r\n\r\n<p>CONFIG_YAFFS_DISABLE_LAZY_LOAD</p>\r\n\r\n<p>Lazy loading is used to defer loading up object details until the objects are accessed. This makes mount time faster. This flag can disable lazy loading. Debug only.</p>\r\n\r\n<p>CONFIG_YAFFS_ECC_WRONG_ORDER</p>\r\n\r\n<p>This flag should only be used with old Linux MTD code which had a bug in the ECC byte ordering.</p>\r\n\r\n<p>CONFIG_YAFFS_NO_YAFFS1</p>\r\n\r\n<p>Used to say that only Yaffs2 operation should be compiled in. Not currently supported.</p>\r\n\r\n<p>CONFIG_YAFFS_SHORT_NAMES_IN_RAM</p>\r\n\r\n<p>Set to configure Yaffs to store short object names in RAM. This is faster, but uses up more memory.</p>\r\n\r\n<p>CONFIG_YAFFS_UNICODE</p>\r\n\r\n<p>Set to configure Yaffs to use Unicode file names (eg. With WinCE).</p>\r\n\r\n<p>CONFIG_YAFFS_USE_OWN_SORT</p>\r\n\r\n<p>By default, Yaffs uses qsort for sorting blocks at mount scanning time. This is faster. Using this flag forces Yaffs to use a slow internal sort instead. Debug only.</p>\r\n\r\n<p>CONFIG_YAFFS_UTIL</p>\r\n\r\n<p>Used when compiling Yaffs for utilities.</p>\r\n\r\n<p>CONFIG_YAFFS_WINCE</p>\r\n\r\n<p>Set when compiling Yaffs for WinCE.</p>\r\n\r\n<p>CONFIG_YAFFS_YAFFS2</p>\r\n\r\n<p>Set when using Yaffs2 mode. At present this must always be set.</p>\r\n\r\n<p>CONFIG_YAFFSFS_PROVIDE_VALUES</p>\r\n\r\n<p>Used when compiling Yaffs Direct only.</p>\r\n\r\n<h3>2 Tracing mechanism</h3>\r\n\r\n<p>Yaffs has a lot of built in tracing to help debug and integrate. The tracing is controlled by yaffs_traceMask bitmask which allows various sets of tracing to be disabled or enabled at runtime.</p>\r\n\r\n<p>The trace bits are specified in the yaffs_trace.h file.</p>\r\n\r\n<p>The tracing mechanism has also been \'hijacked\' to provide a control mask for extra verification code when the YAFFS_TRACE_VERIFYxxx trace bits are selected.</p>\r\n\r\n<p>The tracing mechanism is readily integrated into the system via printf-like statements. Tracing is all done through macros which allow the strings to be converted into unicode or similar if need be.</p>\r\n\r\n<h2>3 Linux</h2>\r\n\r\n<h3>3.1 Linux compile-time flags</h3>\r\n\r\n<p>The Linux compile time flags are documented in the Kconfig file and will not be duplicated here.</p>\r\n\r\n<h3>3.2 Linux: /proc/yaffs trace adjustment</h3>\r\n\r\n<p>Under Linux, the tracing mechanism is hooked up to both the /proc/yaffs and the sys interface. The /proc/yaffs interface is very user friendly.</p>\r\n\r\n<p><code>#cat +os &gt; /proc/yaffs # Enables YAFFS_TRACE_OS<br />\r\n#cat -all+gc &gt; /proc/yaffs # Disables everything then enable YAFFS_TRACE_GC<br />\r\n#cat 0xf000 &gt; /proc/yaffs # Set trace mask to specified bitmask.</code></p>\r\n\r\n<h3>3.3 Linux: /sys/ interface</h3>\r\n\r\n<p>The Linux /sys/ interface is used by many Linux OS components to access the state of control variables. Some Yaffs variables are available via /sys/module/yaffs2/parameters/ *. Values can be read and modified using standard shell commands or from application programs.</p>\r\n\r\n<p><code># ls /sys/module/yaffs2/parameters/ yaffs_auto_checkpoint yaffs_traceMask yaffs_wr_attempts<br />\r\n# cat /sys/module/yaffs2/parameters/yaffs_auto_checkpoint 1<br />\r\n# echo \"2\" &gt; /sys/module/yaffs2/parameters/yaffs_auto_checkpoint<br />\r\n# cat /sys/module/yaffs2/parameters/yaffs_auto_checkpoint 2 </code></p>\r\n\r\n<p>Yaffs currently supports the following variables:</p>\r\n\r\n<p>yaffs_auto_checkpoint: Controls when checkpoints should be written.</p>\r\n\r\n<p>yaffs_traceMask: An alternative, and less user friendly,interface to modify tracing.</p>\r\n\r\n<p>yaffs_wr_attempts: The number of attempts that Yaffs will make to write a chunk.</p>\r\n\r\n<p>yaffs_gc_control: Controls the garbage collector.</p>\r\n\r\n<h3>3.4 Linux: /proc/yaffs state dumping</h3>\r\n\r\n<p>Some of the state of Yaffs mounts can be determined by reading the /proc/yaffs entry.</p>\r\n\r\n<p><code># cat /proc/yaffs<br />\r\ncharles@charles-laptop:/opt/y/cvs/yaffs2$ cat /proc/yaffs<br />\r\nYAFFS built:Mar 16 2010 11:52:25<br />\r\n$Id: yaffs_fs.c,v 1.101 2010-03-15 22:27:15 charles Exp $<br />\r\n$Id: yaffs_guts.c,v 1.119 2010-03-12 02:48:34 charles Exp $<br />\r\n<br />\r\nDevice 0 \"NAND simulator partition 0\" </code><br />\r\n<code>startBlock......... 0<br />\r\nendBlock........... 511<br />\r\ntotalBytesPerChunk. 2048<br />\r\nuseNANDECC......... 1<br />\r\nnoTagsECC.......... 0<br />\r\nisYaffs2........... 1<br />\r\ninbandTags......... 0<br />\r\nemptyLostAndFound.. 1<br />\r\ndisableLazyLoad.... 0<br />\r\nrefreshPeriod...... 10000<br />\r\nnShortOpCaches..... 10<br />\r\nnReservedBlocks.... 5<br />\r\n<br />\r\nnDataBytesPerChunk. 2048<br />\r\nchunkGroupBits..... 0<br />\r\nchunkGroupSize..... 1<br />\r\nnErasedBlocks...... 152<br />\r\nblocksInCheckpoint. 0<br />\r\n<br />\r\nnTnodesCreated..... 2300<br />\r\nnFreeTnodes........ 1852<br />\r\nnObjectsCreated.... 2300<br />\r\nnFreeObjects....... 1842<br />\r\nnFreeChunks........ 27843<br />\r\n<br />\r\nnPageWrites........ 65993<br />\r\nnPageReads......... 19631<br />\r\nnBlockErasures..... 1133<br />\r\nnGCCopies.......... 37<br />\r\ngarbageCollections. 161<br />\r\npassiveGCs......... 137<br />\r\nnRetriedWrites..... 0<br />\r\nnRetireBlocks...... 0<br />\r\neccFixed........... 0<br />\r\neccUnfixed......... 0<br />\r\ntagsEccFixed....... 0<br />\r\ntagsEccUnfixed..... 0<br />\r\ncacheHits.......... 44110<br />\r\nnDeletedFiles...... 0<br />\r\nnUnlinkedFiles..... 42917<br />\r\nrefreshCount....... 1<br />\r\nnBackgroudDeletions 0</code></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<h2>4 Conclusions</h2>\r\n\r\n<p>Yaffs includes many options for changing speed or memory use, with specific flags for the Yaffs Direct Interface as well as Linux. Under Linux many of the control variables can be altered using standard Linux systems.</p>\r\n','<p>YAFFS has a wide variety of settings that are used for tuning it to various applications, as well as debugging settings to help with integration. This document helps to explain those settings for Yaffs Direct and Linux, covering compile time flags and settings, initialisation parameters, tracing, and state inspection.&nbsp;The latest PDF of the document is found <a href=\"/sites/yaffs.net/files/YaffsTuning.pd\">HERE</a>.</p>','basic_html'),('paper',0,451,609,'und',0,'<p>&nbsp;</p>\r\n\r\n<h2>1 Yaffs Direct Configuration</h2>\r\n\r\n<p>Yaffs behaviour is dictated by compile time and run-time flags.</p>\r\n\r\n<h3>1.1 Initialisation Parameters</h3>\r\n\r\n<p>Each yaffs device is configured by a yaffs_DeviceParameterStruct structure which is part of the yaffs_DeviceStruct structure. This contains the following fields:</p>\r\n\r\n<table>\r\n	<colgroup>\r\n		<col />\r\n		<col />\r\n	</colgroup>\r\n	<tbody>\r\n		<tr>\r\n			<td>\r\n			<p>name</p>\r\n			</td>\r\n			<td>\r\n			<p>An optional name for the device</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>totalBytesPerChunk</p>\r\n			</td>\r\n			<td>\r\n			<p>The number of bytes in the data area of the flash page. If inbandTags is not set then this whole area will be used to store data and the tags will be stored in the spare area. If inbandTags is set then part of this area will be used to store tags and the rest will be used to store data.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>spareBytesPerChunk</p>\r\n			</td>\r\n			<td>\r\n			<p>The number of available bytes in the spare area of the flash page. This excludes space used by ECC, bad block markers etc.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>startBlock</p>\r\n			</td>\r\n			<td>\r\n			<p>The first block in the partition to be used. 0 for first block.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>endBlock</p>\r\n			</td>\r\n			<td>\r\n			<p>The last block in the partition to be used.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>nReservedBlocks</p>\r\n			</td>\r\n			<td>\r\n			<p>Number of good blocks blocks reserved for garbage collection etc. Needs to be at least 2, but 5 would be a more typical number.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>inbandTags</p>\r\n			</td>\r\n			<td>\r\n			<p>Yaffs2 only:Flag indicating whether tags should be stored in the data area. If inbandTags is set then the short Op cache must be enabled (ie nShortOpCaches must be non-zero.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>useNANDECC</p>\r\n			</td>\r\n			<td>\r\n			<p>Yaffs1 only: Flag indicating whether the driver performs ECC. If this is zero then Yaffs will perform ECC.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>noTagsECC</p>\r\n			</td>\r\n			<td>\r\n			<p>Yaffs2 only: Flag indicating whether the tags have ECC attached to them.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>isYaffs2</p>\r\n			</td>\r\n			<td>\r\n			<p>Flag indicating if this is using the Yaffs2 mechanism. If this is not set then Yaffs1 mode of operation is provided.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>nShortOpCaches</p>\r\n			</td>\r\n			<td>\r\n			<p>Number of chunks to store in the short operation cache. Zero disables caching. Typical value is 10 to 20 or so. Caching is required for inband tags.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>emptyLostAndFound</p>\r\n			</td>\r\n			<td>\r\n			<p>Flag to delete all files in lost and found on mount.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>skipCheckpointRead</p>\r\n			</td>\r\n			<td>\r\n			<p>Yaffs2 only: Flag to skip reading checkpoint on mount. If set then a re-scan is forced.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>skipCheckpointWrite</p>\r\n			</td>\r\n			<td>\r\n			<p>Yaffs2 only: Flag to skip writing checkpoint on sync or unmount.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>refreshPeriod</p>\r\n			</td>\r\n			<td>\r\n			<p>Yaffs2 only: How often Yaffs should do a block refresh. Values less than 10 disable block refreshing. Typical values would be1000.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>initialiseNAND</p>\r\n			</td>\r\n			<td>\r\n			<p>Pointer to function to initialise flash driver.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>deinitialiseNAND</p>\r\n			</td>\r\n			<td>\r\n			<p>Pointer to function to de-initialise flash driver</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>eraseBlockInNAND</p>\r\n			</td>\r\n			<td>\r\n			<p>Pointer to function to erase a flash block</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>writeChunkToNAND</p>\r\n			</td>\r\n			<td>\r\n			<p>Yaffs1 only: Pointer to function to write a chunk</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>readChunkFromNAND</p>\r\n			</td>\r\n			<td>\r\n			<p>Yaffs1 only: Pointer to function to read a chunk.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>writeChunkWithTagsToNAND</p>\r\n			</td>\r\n			<td>\r\n			<p>Yaffs2 only: Pointer to function to write a chunk plus tags</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>readChunkWithTagsFromNAND</p>\r\n			</td>\r\n			<td>\r\n			<p>Yaffs2 only: Pointer to function to read a chunk plus tags</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>markNANDBlockBad</p>\r\n			</td>\r\n			<td>\r\n			<p>Yaffs2 only: Function to mark a block bad</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>queryNANDBlock</p>\r\n			</td>\r\n			<td>\r\n			<p>Yaffs2 only: Function to query a block state</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>gcControl</p>\r\n			</td>\r\n			<td>\r\n			<p>Callback function that returns the garbage collector control flags. This is optional.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>removeObjectCallback</p>\r\n			</td>\r\n			<td>\r\n			<p>Callback function called when an object is removed. This is set by the wrapper.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>markSuperBlockDirty</p>\r\n			</td>\r\n			<td>\r\n			<p>Callback function that is called when a clean file system is first modified. This is set by the wrapper.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>disableSoftDelete</p>\r\n			</td>\r\n			<td>\r\n			<p>Yaffs1 only. Debug only. Disables soft deletion if non-zero.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>useHeaderFileSize</p>\r\n			</td>\r\n			<td>\r\n			<p>Debug only. Leave as zero</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>disableLazyLoading</p>\r\n			</td>\r\n			<td>\r\n			<p>Debug only. Leave as zero.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>wideTnodeDisabled</p>\r\n			</td>\r\n			<td>\r\n			<p>Debug only. Leave as zero.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>deferDirectoryUpdate</p>\r\n			</td>\r\n			<td>\r\n			<p>Used to defer directory updates.</p>\r\n			</td>\r\n		</tr>\r\n	</tbody>\r\n</table>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<h3>1.2 Compile-time settings</h3>\r\n\r\n<p>These setting are used to apply compile-time configurations.</p>\r\n\r\n<p>CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED</p>\r\n\r\n<p>Normally Yaffs checks that chunks are erased only on the first chunk write to each block. This flag allows you to force all chunks to be checked. This is slower, but is worth using when doing early debugging.</p>\r\n\r\n<p>CONFIG_YAFFS_CASE_INSENSITIVE</p>\r\n\r\n<p>When selected case insensitive name comparisons are used. Note that this will not magically change Yaffs to be case insensitive in a case sensitive OS. This needs to be set according to the OS policy. Typically this is only used in Windows CE.</p>\r\n\r\n<p>CONFIG_YAFFS_DIRECT</p>\r\n\r\n<p>Used when compiling Yaffs Direct.</p>\r\n\r\n<p>CONFIG_YAFFS_DISABLE_LAZY_LOAD</p>\r\n\r\n<p>Lazy loading is used to defer loading up object details until the objects are accessed. This makes mount time faster. This flag can disable lazy loading. Debug only.</p>\r\n\r\n<p>CONFIG_YAFFS_ECC_WRONG_ORDER</p>\r\n\r\n<p>This flag should only be used with old Linux MTD code which had a bug in the ECC byte ordering.</p>\r\n\r\n<p>CONFIG_YAFFS_NO_YAFFS1</p>\r\n\r\n<p>Used to say that only Yaffs2 operation should be compiled in. Not currently supported.</p>\r\n\r\n<p>CONFIG_YAFFS_SHORT_NAMES_IN_RAM</p>\r\n\r\n<p>Set to configure Yaffs to store short object names in RAM. This is faster, but uses up more memory.</p>\r\n\r\n<p>CONFIG_YAFFS_UNICODE</p>\r\n\r\n<p>Set to configure Yaffs to use Unicode file names (eg. With WinCE).</p>\r\n\r\n<p>CONFIG_YAFFS_USE_OWN_SORT</p>\r\n\r\n<p>By default, Yaffs uses qsort for sorting blocks at mount scanning time. This is faster. Using this flag forces Yaffs to use a slow internal sort instead. Debug only.</p>\r\n\r\n<p>CONFIG_YAFFS_UTIL</p>\r\n\r\n<p>Used when compiling Yaffs for utilities.</p>\r\n\r\n<p>CONFIG_YAFFS_WINCE</p>\r\n\r\n<p>Set when compiling Yaffs for WinCE.</p>\r\n\r\n<p>CONFIG_YAFFS_YAFFS2</p>\r\n\r\n<p>Set when using Yaffs2 mode. At present this must always be set.</p>\r\n\r\n<p>CONFIG_YAFFSFS_PROVIDE_VALUES</p>\r\n\r\n<p>Used when compiling Yaffs Direct only.</p>\r\n\r\n<h3>2 Tracing mechanism</h3>\r\n\r\n<p>Yaffs has a lot of built in tracing to help debug and integrate. The tracing is controlled by yaffs_traceMask bitmask which allows various sets of tracing to be disabled or enabled at runtime.</p>\r\n\r\n<p>The trace bits are specified in the yaffs_trace.h file.</p>\r\n\r\n<p>The tracing mechanism has also been \'hijacked\' to provide a control mask for extra verification code when the YAFFS_TRACE_VERIFYxxx trace bits are selected.</p>\r\n\r\n<p>The tracing mechanism is readily integrated into the system via printf-like statements. Tracing is all done through macros which allow the strings to be converted into unicode or similar if need be.</p>\r\n\r\n<h2>3 Linux</h2>\r\n\r\n<h3>3.1 Linux compile-time flags</h3>\r\n\r\n<p>The Linux compile time flags are documented in the Kconfig file and will not be duplicated here.</p>\r\n\r\n<h3>3.2 Linux: /proc/yaffs trace adjustment</h3>\r\n\r\n<p>Under Linux, the tracing mechanism is hooked up to both the /proc/yaffs and the sys interface. The /proc/yaffs interface is very user friendly.</p>\r\n\r\n<p><code>#cat +os &gt; /proc/yaffs # Enables YAFFS_TRACE_OS<br />\r\n#cat -all+gc &gt; /proc/yaffs # Disables everything then enable YAFFS_TRACE_GC<br />\r\n#cat 0xf000 &gt; /proc/yaffs # Set trace mask to specified bitmask.</code></p>\r\n\r\n<h3>3.3 Linux: /sys/ interface</h3>\r\n\r\n<p>The Linux /sys/ interface is used by many Linux OS components to access the state of control variables. Some Yaffs variables are available via /sys/module/yaffs2/parameters/ *. Values can be read and modified using standard shell commands or from application programs.</p>\r\n\r\n<p><code># ls /sys/module/yaffs2/parameters/ yaffs_auto_checkpoint yaffs_traceMask yaffs_wr_attempts<br />\r\n# cat /sys/module/yaffs2/parameters/yaffs_auto_checkpoint 1<br />\r\n# echo \"2\" &gt; /sys/module/yaffs2/parameters/yaffs_auto_checkpoint<br />\r\n# cat /sys/module/yaffs2/parameters/yaffs_auto_checkpoint 2 </code></p>\r\n\r\n<p>Yaffs currently supports the following variables:</p>\r\n\r\n<p>yaffs_auto_checkpoint: Controls when checkpoints should be written.</p>\r\n\r\n<p>yaffs_traceMask: An alternative, and less user friendly,interface to modify tracing.</p>\r\n\r\n<p>yaffs_wr_attempts: The number of attempts that Yaffs will make to write a chunk.</p>\r\n\r\n<p>yaffs_gc_control: Controls the garbage collector.</p>\r\n\r\n<h3>3.4 Linux: /proc/yaffs state dumping</h3>\r\n\r\n<p>Some of the state of Yaffs mounts can be determined by reading the /proc/yaffs entry.</p>\r\n\r\n<p><code># cat /proc/yaffs<br />\r\ncharles@charles-laptop:/opt/y/cvs/yaffs2$ cat /proc/yaffs<br />\r\nYAFFS built:Mar 16 2010 11:52:25<br />\r\n$Id: yaffs_fs.c,v 1.101 2010-03-15 22:27:15 charles Exp $<br />\r\n$Id: yaffs_guts.c,v 1.119 2010-03-12 02:48:34 charles Exp $<br />\r\n<br />\r\nDevice 0 \"NAND simulator partition 0\" </code><br />\r\n<code>startBlock......... 0<br />\r\nendBlock........... 511<br />\r\ntotalBytesPerChunk. 2048<br />\r\nuseNANDECC......... 1<br />\r\nnoTagsECC.......... 0<br />\r\nisYaffs2........... 1<br />\r\ninbandTags......... 0<br />\r\nemptyLostAndFound.. 1<br />\r\ndisableLazyLoad.... 0<br />\r\nrefreshPeriod...... 10000<br />\r\nnShortOpCaches..... 10<br />\r\nnReservedBlocks.... 5<br />\r\n<br />\r\nnDataBytesPerChunk. 2048<br />\r\nchunkGroupBits..... 0<br />\r\nchunkGroupSize..... 1<br />\r\nnErasedBlocks...... 152<br />\r\nblocksInCheckpoint. 0<br />\r\n<br />\r\nnTnodesCreated..... 2300<br />\r\nnFreeTnodes........ 1852<br />\r\nnObjectsCreated.... 2300<br />\r\nnFreeObjects....... 1842<br />\r\nnFreeChunks........ 27843<br />\r\n<br />\r\nnPageWrites........ 65993<br />\r\nnPageReads......... 19631<br />\r\nnBlockErasures..... 1133<br />\r\nnGCCopies.......... 37<br />\r\ngarbageCollections. 161<br />\r\npassiveGCs......... 137<br />\r\nnRetriedWrites..... 0<br />\r\nnRetireBlocks...... 0<br />\r\neccFixed........... 0<br />\r\neccUnfixed......... 0<br />\r\ntagsEccFixed....... 0<br />\r\ntagsEccUnfixed..... 0<br />\r\ncacheHits.......... 44110<br />\r\nnDeletedFiles...... 0<br />\r\nnUnlinkedFiles..... 42917<br />\r\nrefreshCount....... 1<br />\r\nnBackgroudDeletions 0</code></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<h2>4 Conclusions</h2>\r\n\r\n<p>Yaffs includes many options for changing speed or memory use, with specific flags for the Yaffs Direct Interface as well as Linux. Under Linux many of the control variables can be altered using standard Linux systems.</p>\r\n','<p>YAFFS has a wide variety of settings that are used for tuning it to various applications, as well as debugging settings to help with integration. This document helps to explain those settings for Yaffs Direct and Linux, covering compile time flags and settings, initialisation parameters, tracing, and state inspection.&nbsp;The latest PDF of the document is found <a href=\"/sites/yaffs.net/files/YaffsTuning.pd\">HERE</a>.</p>','basic_html'),('paper',0,451,628,'und',0,'<p>&nbsp;</p>\r\n\r\n<h2>1 Yaffs Direct Configuration</h2>\r\n\r\n<p>Yaffs behaviour is dictated by compile time and run-time flags.</p>\r\n\r\n<h3>1.1 Initialisation Parameters</h3>\r\n\r\n<p>Each yaffs device is configured by a yaffs_DeviceParameterStruct structure which is part of the yaffs_DeviceStruct structure. This contains the following fields:</p>\r\n\r\n<table>\r\n	<colgroup>\r\n		<col />\r\n		<col />\r\n	</colgroup>\r\n	<tbody>\r\n		<tr>\r\n			<td>\r\n			<p>name</p>\r\n			</td>\r\n			<td>\r\n			<p>An optional name for the device</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>totalBytesPerChunk</p>\r\n			</td>\r\n			<td>\r\n			<p>The number of bytes in the data area of the flash page. If inbandTags is not set then this whole area will be used to store data and the tags will be stored in the spare area. If inbandTags is set then part of this area will be used to store tags and the rest will be used to store data.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>spareBytesPerChunk</p>\r\n			</td>\r\n			<td>\r\n			<p>The number of available bytes in the spare area of the flash page. This excludes space used by ECC, bad block markers etc.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>startBlock</p>\r\n			</td>\r\n			<td>\r\n			<p>The first block in the partition to be used. 0 for first block.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>endBlock</p>\r\n			</td>\r\n			<td>\r\n			<p>The last block in the partition to be used.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>nReservedBlocks</p>\r\n			</td>\r\n			<td>\r\n			<p>Number of good blocks blocks reserved for garbage collection etc. Needs to be at least 2, but 5 would be a more typical number.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>inbandTags</p>\r\n			</td>\r\n			<td>\r\n			<p>Yaffs2 only:Flag indicating whether tags should be stored in the data area. If inbandTags is set then the short Op cache must be enabled (ie nShortOpCaches must be non-zero.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>useNANDECC</p>\r\n			</td>\r\n			<td>\r\n			<p>Yaffs1 only: Flag indicating whether the driver performs ECC. If this is zero then Yaffs will perform ECC.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>noTagsECC</p>\r\n			</td>\r\n			<td>\r\n			<p>Yaffs2 only: Flag indicating whether the tags have ECC attached to them.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>isYaffs2</p>\r\n			</td>\r\n			<td>\r\n			<p>Flag indicating if this is using the Yaffs2 mechanism. If this is not set then Yaffs1 mode of operation is provided.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>nShortOpCaches</p>\r\n			</td>\r\n			<td>\r\n			<p>Number of chunks to store in the short operation cache. Zero disables caching. Typical value is 10 to 20 or so. Caching is required for inband tags.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>emptyLostAndFound</p>\r\n			</td>\r\n			<td>\r\n			<p>Flag to delete all files in lost and found on mount.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>skipCheckpointRead</p>\r\n			</td>\r\n			<td>\r\n			<p>Yaffs2 only: Flag to skip reading checkpoint on mount. If set then a re-scan is forced.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>skipCheckpointWrite</p>\r\n			</td>\r\n			<td>\r\n			<p>Yaffs2 only: Flag to skip writing checkpoint on sync or unmount.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>refreshPeriod</p>\r\n			</td>\r\n			<td>\r\n			<p>Yaffs2 only: How often Yaffs should do a block refresh. Values less than 10 disable block refreshing. Typical values would be1000.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>initialiseNAND</p>\r\n			</td>\r\n			<td>\r\n			<p>Pointer to function to initialise flash driver.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>deinitialiseNAND</p>\r\n			</td>\r\n			<td>\r\n			<p>Pointer to function to de-initialise flash driver</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>eraseBlockInNAND</p>\r\n			</td>\r\n			<td>\r\n			<p>Pointer to function to erase a flash block</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>writeChunkToNAND</p>\r\n			</td>\r\n			<td>\r\n			<p>Yaffs1 only: Pointer to function to write a chunk</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>readChunkFromNAND</p>\r\n			</td>\r\n			<td>\r\n			<p>Yaffs1 only: Pointer to function to read a chunk.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>writeChunkWithTagsToNAND</p>\r\n			</td>\r\n			<td>\r\n			<p>Yaffs2 only: Pointer to function to write a chunk plus tags</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>readChunkWithTagsFromNAND</p>\r\n			</td>\r\n			<td>\r\n			<p>Yaffs2 only: Pointer to function to read a chunk plus tags</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>markNANDBlockBad</p>\r\n			</td>\r\n			<td>\r\n			<p>Yaffs2 only: Function to mark a block bad</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>queryNANDBlock</p>\r\n			</td>\r\n			<td>\r\n			<p>Yaffs2 only: Function to query a block state</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>gcControl</p>\r\n			</td>\r\n			<td>\r\n			<p>Callback function that returns the garbage collector control flags. This is optional.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>removeObjectCallback</p>\r\n			</td>\r\n			<td>\r\n			<p>Callback function called when an object is removed. This is set by the wrapper.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>markSuperBlockDirty</p>\r\n			</td>\r\n			<td>\r\n			<p>Callback function that is called when a clean file system is first modified. This is set by the wrapper.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>disableSoftDelete</p>\r\n			</td>\r\n			<td>\r\n			<p>Yaffs1 only. Debug only. Disables soft deletion if non-zero.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>useHeaderFileSize</p>\r\n			</td>\r\n			<td>\r\n			<p>Debug only. Leave as zero</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>disableLazyLoading</p>\r\n			</td>\r\n			<td>\r\n			<p>Debug only. Leave as zero.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>wideTnodeDisabled</p>\r\n			</td>\r\n			<td>\r\n			<p>Debug only. Leave as zero.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>deferDirectoryUpdate</p>\r\n			</td>\r\n			<td>\r\n			<p>Used to defer directory updates.</p>\r\n			</td>\r\n		</tr>\r\n	</tbody>\r\n</table>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<h3>1.2 Compile-time settings</h3>\r\n\r\n<p>These setting are used to apply compile-time configurations.</p>\r\n\r\n<p>CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED</p>\r\n\r\n<p>Normally Yaffs checks that chunks are erased only on the first chunk write to each block. This flag allows you to force all chunks to be checked. This is slower, but is worth using when doing early debugging.</p>\r\n\r\n<p>CONFIG_YAFFS_CASE_INSENSITIVE</p>\r\n\r\n<p>When selected case insensitive name comparisons are used. Note that this will not magically change Yaffs to be case insensitive in a case sensitive OS. This needs to be set according to the OS policy. Typically this is only used in Windows CE.</p>\r\n\r\n<p>CONFIG_YAFFS_DIRECT</p>\r\n\r\n<p>Used when compiling Yaffs Direct.</p>\r\n\r\n<p>CONFIG_YAFFS_DISABLE_LAZY_LOAD</p>\r\n\r\n<p>Lazy loading is used to defer loading up object details until the objects are accessed. This makes mount time faster. This flag can disable lazy loading. Debug only.</p>\r\n\r\n<p>CONFIG_YAFFS_ECC_WRONG_ORDER</p>\r\n\r\n<p>This flag should only be used with old Linux MTD code which had a bug in the ECC byte ordering.</p>\r\n\r\n<p>CONFIG_YAFFS_NO_YAFFS1</p>\r\n\r\n<p>Used to say that only Yaffs2 operation should be compiled in. Not currently supported.</p>\r\n\r\n<p>CONFIG_YAFFS_SHORT_NAMES_IN_RAM</p>\r\n\r\n<p>Set to configure Yaffs to store short object names in RAM. This is faster, but uses up more memory.</p>\r\n\r\n<p>CONFIG_YAFFS_UNICODE</p>\r\n\r\n<p>Set to configure Yaffs to use Unicode file names (eg. With WinCE).</p>\r\n\r\n<p>CONFIG_YAFFS_USE_OWN_SORT</p>\r\n\r\n<p>By default, Yaffs uses qsort for sorting blocks at mount scanning time. This is faster. Using this flag forces Yaffs to use a slow internal sort instead. Debug only.</p>\r\n\r\n<p>CONFIG_YAFFS_UTIL</p>\r\n\r\n<p>Used when compiling Yaffs for utilities.</p>\r\n\r\n<p>CONFIG_YAFFS_WINCE</p>\r\n\r\n<p>Set when compiling Yaffs for WinCE.</p>\r\n\r\n<p>CONFIG_YAFFS_YAFFS2</p>\r\n\r\n<p>Set when using Yaffs2 mode. At present this must always be set.</p>\r\n\r\n<p>CONFIG_YAFFSFS_PROVIDE_VALUES</p>\r\n\r\n<p>Used when compiling Yaffs Direct only.</p>\r\n\r\n<h3>2 Tracing mechanism</h3>\r\n\r\n<p>Yaffs has a lot of built in tracing to help debug and integrate. The tracing is controlled by yaffs_traceMask bitmask which allows various sets of tracing to be disabled or enabled at runtime.</p>\r\n\r\n<p>The trace bits are specified in the yaffs_trace.h file.</p>\r\n\r\n<p>The tracing mechanism has also been \'hijacked\' to provide a control mask for extra verification code when the YAFFS_TRACE_VERIFYxxx trace bits are selected.</p>\r\n\r\n<p>The tracing mechanism is readily integrated into the system via printf-like statements. Tracing is all done through macros which allow the strings to be converted into unicode or similar if need be.</p>\r\n\r\n<h2>3 Linux</h2>\r\n\r\n<h3>3.1 Linux compile-time flags</h3>\r\n\r\n<p>The Linux compile time flags are documented in the Kconfig file and will not be duplicated here.</p>\r\n\r\n<h3>3.2 Linux: /proc/yaffs trace adjustment</h3>\r\n\r\n<p>Under Linux, the tracing mechanism is hooked up to both the /proc/yaffs and the sys interface. The /proc/yaffs interface is very user friendly.</p>\r\n\r\n<p><code>#cat +os &gt; /proc/yaffs # Enables YAFFS_TRACE_OS<br />\r\n#cat -all+gc &gt; /proc/yaffs # Disables everything then enable YAFFS_TRACE_GC<br />\r\n#cat 0xf000 &gt; /proc/yaffs # Set trace mask to specified bitmask.</code></p>\r\n\r\n<h3>3.3 Linux: /sys/ interface</h3>\r\n\r\n<p>The Linux /sys/ interface is used by many Linux OS components to access the state of control variables. Some Yaffs variables are available via /sys/module/yaffs2/parameters/ *. Values can be read and modified using standard shell commands or from application programs.</p>\r\n\r\n<p><code># ls /sys/module/yaffs2/parameters/ yaffs_auto_checkpoint yaffs_traceMask yaffs_wr_attempts<br />\r\n# cat /sys/module/yaffs2/parameters/yaffs_auto_checkpoint 1<br />\r\n# echo \"2\" &gt; /sys/module/yaffs2/parameters/yaffs_auto_checkpoint<br />\r\n# cat /sys/module/yaffs2/parameters/yaffs_auto_checkpoint 2 </code></p>\r\n\r\n<p>Yaffs currently supports the following variables:</p>\r\n\r\n<p>yaffs_auto_checkpoint: Controls when checkpoints should be written.</p>\r\n\r\n<p>yaffs_traceMask: An alternative, and less user friendly,interface to modify tracing.</p>\r\n\r\n<p>yaffs_wr_attempts: The number of attempts that Yaffs will make to write a chunk.</p>\r\n\r\n<p>yaffs_gc_control: Controls the garbage collector.</p>\r\n\r\n<h3>3.4 Linux: /proc/yaffs state dumping</h3>\r\n\r\n<p>Some of the state of Yaffs mounts can be determined by reading the /proc/yaffs entry.</p>\r\n\r\n<p><code># cat /proc/yaffs<br />\r\ncharles@charles-laptop:/opt/y/cvs/yaffs2$ cat /proc/yaffs<br />\r\nYAFFS built:Mar 16 2010 11:52:25<br />\r\n$Id: yaffs_fs.c,v 1.101 2010-03-15 22:27:15 charles Exp $<br />\r\n$Id: yaffs_guts.c,v 1.119 2010-03-12 02:48:34 charles Exp $<br />\r\n<br />\r\nDevice 0 \"NAND simulator partition 0\" </code><br />\r\n<code>startBlock......... 0<br />\r\nendBlock........... 511<br />\r\ntotalBytesPerChunk. 2048<br />\r\nuseNANDECC......... 1<br />\r\nnoTagsECC.......... 0<br />\r\nisYaffs2........... 1<br />\r\ninbandTags......... 0<br />\r\nemptyLostAndFound.. 1<br />\r\ndisableLazyLoad.... 0<br />\r\nrefreshPeriod...... 10000<br />\r\nnShortOpCaches..... 10<br />\r\nnReservedBlocks.... 5<br />\r\n<br />\r\nnDataBytesPerChunk. 2048<br />\r\nchunkGroupBits..... 0<br />\r\nchunkGroupSize..... 1<br />\r\nnErasedBlocks...... 152<br />\r\nblocksInCheckpoint. 0<br />\r\n<br />\r\nnTnodesCreated..... 2300<br />\r\nnFreeTnodes........ 1852<br />\r\nnObjectsCreated.... 2300<br />\r\nnFreeObjects....... 1842<br />\r\nnFreeChunks........ 27843<br />\r\n<br />\r\nnPageWrites........ 65993<br />\r\nnPageReads......... 19631<br />\r\nnBlockErasures..... 1133<br />\r\nnGCCopies.......... 37<br />\r\ngarbageCollections. 161<br />\r\npassiveGCs......... 137<br />\r\nnRetriedWrites..... 0<br />\r\nnRetireBlocks...... 0<br />\r\neccFixed........... 0<br />\r\neccUnfixed......... 0<br />\r\ntagsEccFixed....... 0<br />\r\ntagsEccUnfixed..... 0<br />\r\ncacheHits.......... 44110<br />\r\nnDeletedFiles...... 0<br />\r\nnUnlinkedFiles..... 42917<br />\r\nrefreshCount....... 1<br />\r\nnBackgroudDeletions 0</code></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<h2>4 Conclusions</h2>\r\n\r\n<p>Yaffs includes many options for changing speed or memory use, with specific flags for the Yaffs Direct Interface as well as Linux. Under Linux many of the control variables can be altered using standard Linux systems.</p>\r\n','<p>This document describes the parameters which can be modified by the developer in the different phases of applying, debugging, and routine use of Yaffs.</p>','basic_html'),('help_video',0,452,468,'und',0,'<p><a href=\"http://free-electrons.com/pub/video/2007/elce/elce-2007-wookey-yaffs.ogg\">This&nbsp;video</a>&nbsp;from 2007 describes Yaffs1 and Yaffs2. The&nbsp;<a href=\"/yaffs-talk-pdf-slides-celf-2007\">slides</a>&nbsp;from the video are available.</p>\r\n','<p><a href=\"http://free-electrons.com/pub/video/2007/elce/elce-2007-wookey-yaffs.ogg\">This video</a> from 2007 describes Yaffs1 and Yaffs2. The <a href=\"/yaffs-talk-pdf-slides-celf-2007\">slides</a> from the video are available.</p><p><img alt=\"\" src=\"/sites/yaffs.net/files/file_attach/small_yaffs-introduction.png\" style=\"width: 90px; height: 90px; \"></p>','basic_html'),('paper',0,453,469,'und',0,'<h2>1 Background</h2><p class=\"western\">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><h2 class=\"western\">2 Licensing</h2><p class=\"western\">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 has alternative licensing arrangements to support such applications.</p><h2 class=\"western\">3 What are Yaffs and Yaffs Direct Interface?</h2><p class=\"western\">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><p class=\"western\">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><p class=\"western\">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 to NAND flash for higher density and performance.</p><p class=\"western\">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><p class=\"western\"><br>Yaffs has been used for many products using various operating systems including Windows CE and various RTOSs, including ThreadX, vXworks, pSOS to name just a few.</p><p class=\"western\">Note that there is a native port to eCOS that does not use YDI. This is supported and distributed by eCocCentric.(http://www.ecoscentric.com/).</p><p class=\"western\">Yaffs2, a more recent release of Yaffs, supports a wider range of NAND flash components including 2k page devices, and produces equivalent or better performance. It include Yaffs1 compatibility code so Yaffs1 images still work and migration is quite simple.</p><p class=\"western\">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><h2 class=\"western\">4 Why use Yaffs?</h2><p class=\"western\">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><p class=\"western\">Some features to consider:</p><ul><li><p class=\"western\">Yaffs has been well proven and has been used to ship in large volumes in several products using many different operating systems, compilers and processors.</p></li><li><p class=\"western\">Yaffs is written in portable C and is endian neutral.</p></li><li><p class=\"western\">Yaffs provides bad<b> </b>block handling and ECC algorithms to handle deficiencies in NAND flash.</p></li><li><p class=\"western\">Yaffs is a log-structured file system which makes it very robust to corruptions caused by power failures etc.</p></li><li><p class=\"western\">Yaffs has highly optimised and predictable garbage collection strategies. This makes it high performance and very deterministic when compared with similar file systems.</p></li><li><p class=\"western\">Yaffs has a lower memory footprint than most other log-structured flash file systems.</p></li><li><p class=\"western\">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></li><li><p class=\"western\">Yaffs is highly configurable to work with various flash geometries, various ECC options, caching options etc.</p></li><li><p class=\"western\">Yaffs Direct Interface is simple to integrate in a system – only a few interface functions are required.</p></li><li><p class=\"western\">Yaffs can be used with a wide range of memory technologies.</p></li></ul><h2 class=\"western\">5 Source Code and Yaffs Resources</h2><p class=\"western\"><font face=\"Liberation Serif, serif\">Please note the licensing terms that apply to using the Yaffs code.</font></p><p class=\"western\"><a href=\"http://www.yaffs.net/\"><font face=\"Liberation Serif, serif\">http://www.yaffs.net</font></a><font face=\"Liberation Serif, serif\"> serves as the hub for all Yaffs information.</font></p><p class=\"western\"><font face=\"Liberation Serif, serif\">This document refers to the Yaffs source code extensively. and is available via the download link on this site.</font></p><p class=\"western\"><font face=\"Liberation Serif, serif\">There are various other documents and a Yaffs mailing list for Yaffs discussions.</font></p><p class=\"western\"><font face=\"Liberation Serif, serif\">Consulting services are also available.</font></p><h2 class=\"western\">6 System Requirements</h2><p class=\"western\">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><ul><li><p class=\"western\">Yaffs is endian-neutral and works fine with little-endian and big-endian processors.</p></li><li><p class=\"western\">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 should work with 16-bit CPUs too, but this is generally untested and might need some tuning, depending on compiler options.</p></li><li><p class=\"western\">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></li></ul><h2 class=\"western\">7 How to integrate Yaffs with an RTOS/Embedded system</h2><p class=\"western\">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 OS. Yaffs provides a set of POSIX-compliant functions for applications to use to talk to it.</p><p class=\"western\">In addition to the Yaffs core file system, the YDI has three parts which are each explained in more detail in further sections:</p><ul><li><p class=\"western\"><b>POSIX Application Interface</b>: This is the interface that the application code uses to access the Yaffs file system. (<font face=\"Times New Roman\"><i>open, close, read, write, </i></font>etc)</p></li><li><p class=\"western\"><b>RTOS Integration Interface</b>: These are the functions that must be provided for Yaffs to access the RTOS system resources. (<font face=\"Times New Roman\"><i>initialise, lock, unlock, get time, set error</i></font>)</p></li><li><p class=\"western\"><b>Flash Configuration and Access Interface</b>: These are the functions that must be provided for Yaffs to access the NAND flash. (<i>initialise, read chunk, write chunk, erase block, </i>etc). These functions might be supplied by a chipset vendor or might need to be written by the integrator.</p></li></ul><p class=\"western\"><img alt=\"Yaffs Direct Interface Layer\" src=\"/sites/yaffs.net/files/images/Yaffs%20Direct%20Interface%20layer.gif\" style=\"width: 340px; height: 455px; \"></p><h3 class=\"western\">7.1 Source Files</h3><p class=\"western\">The following source files contain the core file system:</p><table cellpadding=\"4\" cellspacing=\"0\" width=\"100%\"><colgroup><col width=\"71*\"><col width=\"185*\"></colgroup><tbody><tr valign=\"TOP\"><td style=\"border-top-style: solid; border-top-color: rgb(0, 0, 0); border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0.1cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"28%\"><p class=\"western\">yaffs_allocator.c</p></td><td style=\"border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); padding-top: 0.1cm; padding-right: 0.1cm; padding-bottom: 0.1cm; padding-left: 0.1cm; \" width=\"72%\"><p class=\"western\">Allocates Yaffs object and tnode structures.</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"28%\"><p class=\"western\">yaffs_checkpointrw.c</p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"72%\"><p class=\"western\">Streamer for writing checkpoint data</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"28%\"><p class=\"western\">yaffs_ecc.c</p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"72%\"><p class=\"western\">ECC code</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"28%\"><p class=\"western\">yaffs_guts.c</p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"72%\"><p class=\"western\">The major Yaffs algorithms.</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"28%\"><p class=\"western\">yaffs_nand.c</p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"72%\"><p class=\"western\">Flash interfacing abstraction.</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"28%\"><p class=\"western\">yaffs_packedtags1.c<br>yaffs_packedtags2.c</p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"72%\"><p class=\"western\">Tags packing code</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"28%\"><p class=\"western\">yaffs_qsort.c</p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"72%\"><p class=\"western\">Qsort used during Yaffs2 scanning</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"28%\"><p class=\"western\">yaffs_tagscompat.c</p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"72%\"><p class=\"western\">Tags compatibility code to support Yaffs1 mode.</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"28%\"><p class=\"western\">yaffs_tagsvalidity.c</p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"72%\"><p class=\"western\">Tags validity checking.</p></td></tr></tbody></table><p class=\"western\">The Yaffs direct interface is in yaffsfs.c, with the interface functions and structures defined in yaffsfd.h.</p><p class=\"western\">Example and testing build files:</p><table cellpadding=\"4\" cellspacing=\"0\" width=\"100%\"><colgroup><col width=\"71*\"><col width=\"185*\"></colgroup><tbody><tr valign=\"TOP\"><td style=\"border-top-style: solid; border-top-color: rgb(0, 0, 0); border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0.1cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"28%\"><p class=\"western\">dtest.c</p></td><td style=\"border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); padding-top: 0.1cm; padding-right: 0.1cm; padding-bottom: 0.1cm; padding-left: 0.1cm; \" width=\"72%\"><p class=\"western\">A test harness. Also has sample code that can be used for better understanding of how some function calls work.</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"28%\"><p class=\"western\">yaffscfg2k.c</p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"72%\"><p class=\"western\">A test configuration.</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"28%\"><p class=\"western\">yaffs_fileem.c<br>yaffs_fileem2k.c</p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"72%\"><p class=\"western\">Nand flash simulation using a file as backing store.</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"28%\"><p class=\"western\">yaffs_norif1.c</p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"72%\"><p class=\"western\">Nor flash simulation and interfacing example. This is configured for M18 flash.</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"28%\"><p class=\"western\">yaffs_ramdisk.c<br>yaffs_ramem2k.c</p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"72%\"><p class=\"western\">Simulations using RAM.</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"28%\"><p class=\"western\">ynorsim.c</p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"72%\"><p class=\"western\">Another Nor simulation.</p></td></tr></tbody></table><p class=\"western\">Further testing files are in direct/tests and direct/python.</p><h3 class=\"western\">7.2 Integrating the POSIX Application Interface</h3><p class=\"western\">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><p class=\"western\"><br>&nbsp;</p><p class=\"western\">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><p class=\"western\">These functions can be used directly, with the code written using these names. For example</p><p class=\"code-western\"><code class=\"western\">int main(...)<br>{<br>// initialisation<br>f = yaffs_open(...);<br>yaffs_read(f,...);<br>yaffs_close(f);<br>}</code></p><p class=\"western\">The <font face=\"Times New Roman\">yaffs</font> functions can also be wrapped in some way to allow existing code to use yaffs without modification. For example:</p><p class=\"code-western\"><code class=\"western\">#define open(path, oflag, mode) yaffs_open(path, oflag, mode)<br>..<br><br>int main(...)<br>{<br>// initialisation<br>f = open(...);<br>read(f,...);<br>close(f);<br>}</code><br>&nbsp;</p><p class=\"western\">A more complex approach that can be used if more than one file-system is used is to provide redirection functions. For example:</p><p class=\"code-western\"><code class=\"western\">int open(const char *path,...)<br>{<br>// Determine which file system is being used if(it_is_a_yaffs_path(path))<br>return yaffs_open(...);<br>else<br>{<br>// Do something else<br>}<br>}</code></p><p class=\"western\">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><h3 class=\"western\">7.3 RTOS Integration Interface</h3><p class=\"western\">Before Yaffs can be used, it needs to be integrated with the system and configured so that the correct actions are performed.</p><p class=\"western\">To do this, you need to modify the configuration file. An example configuration file is presented in <font face=\"Bitstream Vera Sans\"><font face=\"Times New Roman\">yaffscfg.c and yaffscfg2k.c.</font></font></p><p class=\"western\">This is a relatively straight forward process and defines the RTOS access functions.</p><p class=\"western\">The RTOS access functions are:</p><ul><li><p class=\"western\"><code class=\"western\">void yaffsfs_SetError(int err)</code>: Called by Yaffs to set the system error.</p></li><li><p class=\"western\"><code class=\"western\">void yaffsfs_Lock(void)</code>: Called by Yaffs to lock Yaffs from multi-threaded access.</p></li><li><p class=\"western\"><code class=\"western\">void yaffsfs_Unlock(void)</code>: Called by Yaffs to unlock Yaffs.</p></li><li><p class=\"western\"><code class=\"western\">__u32 yaffsfs_CurrentTime(void)</code>: Get current time from RTOS.</p></li><li><p class=\"western\"><code class=\"western\">void yaffsfs_LocalInitialisation(void)</code>: Called to initialise RTOS context.</p></li></ul><p class=\"western\">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><p class=\"western\"><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><p class=\"western\">Although not shown here, Yaffs also requires memory allocation/free functions which default to <code class=\"western\">malloc()</code> and <code class=\"western\">free()</code>. These, and some other functions can be tuned in file <font face=\"Bitstream Vera Sans\"><font face=\"Times New Roman\">ydirectenv.h</font></font></p><p class=\"western\">Before the application code uses Yaffs, the <code class=\"western\">yaffs_StartUp()</code> function must be called and the appropriate partitions must be mounted. This is typically done in the system boot code:</p><p class=\"code-western\"><code class=\"western\">...</code></p><p class=\"code-western\"><code class=\"western\">/* System boot code: Start up Yaffs. */<br>yaffs_StartUp();<br>yaffs_mount(\"/boot\");</code></p><p class=\"code-western\"><code class=\"western\">...</code></p><h2 class=\"western\">8 Yaffs NAND Model</h2><p class=\"western\">Before defining the flash integration interface, it is important to understand the model and corresponding nomenclature used throughout Yaffs and its documentation.</p><p class=\"western\">Yaffs uses a fairly abstract model for NAND flash. This allows a lot of flexibility in the way it can be used.</p><p class=\"western\">Yaffs is designed for NAND flash and makes the following assumptions and definitions:</p><ul><li><p class=\"western\">The flash is arranged in <i><b>blocks</b></i>. Each block is the same size and comprises an integer number of chunks. Each block is treated as a single erasable item. A block contains a number of chunks.</p></li><li><p class=\"western\">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></li><li><p class=\"western\">All accesses (reads and writes) are page chunk aligned. Some reads might only read the spare area where the tags are kept.</p></li><li><p class=\"western\">When programming a NAND flash, only the zero bits in the pattern being programmed are relevant, and one bits are \"don\'t care\". For example, if a byte already contains the binary pattern 1010, then programming 1001 will result in the pattern which is the logical AND of these two patterns ie. 1000. This is different to NOR flash which would typically abort the attempt to convert a 0 into a 1.</p></li></ul><p class=\"western\">Yaffs identifies blocks by their block number and chunks by the chunk Id. A chunk Id is calculated as:</p><p class=\"western\"><code class=\"western\">chunkId = block_id * chunks_per_block + chunk_offset_in_block</code></p><p class=\"western\">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><p class=\"western\">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 more effort is required to interface to the NAND.</p><h3 class=\"western\">8.1 NAND Model considerations for Yaffs1</h3><p class=\"western\">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><p class=\"western\">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><p class=\"western\">If the yaffs_Device\'s useNANDECC filed is not set, then yaffs will perform the ECC calculations. If this iset then yaffs will expect the NAND driver todo any required ECC checks. On devices that are not using ECC, for example NOR, set useNANDECC=1 and then don\'t do any ECC anyway.</p><p class=\"western\">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><p class=\"western\">The Yaffs1 model has been used in many NOR-based systems. One particularly instructive example is in yaffs_norif1.c which implements Yaffs1 mode on Intel M18 flash using 1k data pages and simulating a spare area on re-writable areas of flash. This does not use ECC but uses checksumming instead.</p><h3 class=\"western\">8.2 NAND Model for Yaffs2</h3><p class=\"western\">Yaffs2 uses a different tags layout than Yaffs1. Yaffs2 uses a yaffs_ExtendedTags structure.which is packed according to the code in yaffs_packedtags2.c.</p><p class=\"western\">The NAND handler layer must use or populate the fields. The fields have the following meaning:</p><ul><li><p class=\"western\"><code class=\"western\">validMarker0</code> Set to 0xAAAAAAAA</p></li><li><p class=\"western\"><code class=\"western\">chunkUsed</code><font face=\"Courier, monospace\"> </font>If 0 then this chunk is not in use</p></li><li><p class=\"western\"><code class=\"western\">objectId</code> The object this chunk belongs to. If 0 then this is not part of an object (ie. unused).</p></li><li><p class=\"western\"><code class=\"western\">chunkId</code><font face=\"Courier, monospace\"> </font> If 0 then this is a header, else a data chunk at the specified position in the file</p></li><li><p class=\"western\"><code class=\"western\">byteCount</code> Number of data bytes in the chunk. Only valid for data chunks</p></li></ul><p class=\"western\">The following fields only have meaning when we read</p><ul><li><p class=\"western\"><code class=\"western\">eccResult</code> <font face=\"Times new roman\">Result of ECC check when reading</font></p></li></ul><ul><li><p class=\"western\"><code class=\"western\">blockBad</code> If 0 then the block is not bad.</p></li></ul><p class=\"western\">The following fields have meaning for Yaffs1 and should be zero for Yaffs:</p><ul><li><p class=\"western\"><code class=\"western\">chunkDeleted</code> if non-zero, the chunk is marked deleted.</p></li><li><p class=\"western\"><code class=\"western\">serialNumber</code> 2-bit serial number.</p></li></ul><p class=\"western\">The following field has meaning for Yaffs1 and should be zero for Yaffs2:</p><ul><li><p class=\"western\"><code class=\"western\">sequenceNumber</code> The sequence number of this block</p></li></ul><p class=\"western\">Optional extra info if this is an object header (Yaffs2 only). Make zero for Yaffs1.</p><p class=\"western\">If <code class=\"western\">extraHeaderInfoAvailable</code> is set, then all the <code class=\"western\">extraXXX</code> fields must be valid.</p><ul><li><p class=\"western\"><code class=\"western\">extraHeaderInfoAvailable</code> There is extra info available if this is not zero.</p></li><li><p class=\"western\"><code class=\"western\">extraParentObjectId</code> The parent object id.</p></li><li><p class=\"western\"><code class=\"western\">extraIsShrinkHeader</code> Is it a shrink header?</p></li><li><p class=\"western\"><code class=\"western\">extraShadows</code> Does this shadow another object?</p></li><li><p class=\"western\"><code class=\"western\">extraObjectType</code><font face=\"Courier, monospace\"> </font> What object type?</p></li><li><p class=\"western\"><code class=\"western\">extraFileLength</code> Length if it is a file.</p></li><li><p class=\"western\"><code class=\"western\">extraEquivalentObjectId</code> Equivalent object Id if it is a hard link.</p></li></ul><p class=\"western\">And finally:</p><ul><li><p class=\"western\"><code class=\"western\">validMarker1</code> Must be 0x55555555.</p></li></ul><p class=\"western\">There are quite a few fields, some of which are optional. All the <code class=\"western\">extraXXXX</code> fields are a way of stuffing more data into object header tags in a way that speeds up scanning. These are optional and should all be zero if not supported.</p><p class=\"western\">The easiest way to process the <code class=\"western\">yaffs_ExtendedTags</code> is to use the functions presented in yaffs_packedtags2.h to do the packing and unpacking. These are:</p><p class=\"western\"><code class=\"western\">yaffs_PackTags2()</code><font face=\"Times New Roman, serif\"> and </font><code class=\"western\">yaffs_UnpackTags2()</code><font face=\"Liberation Serif, serif\"><font size=\"2\">.</font></font></p><p class=\"western\">These functions create or use a packed tags structure which can be stored in the NAND spare area. An example of how to do this is presented in yaffs_fileem2.c</p><h2 class=\"western\">9 NAND Configuration and Access Interface</h2><p class=\"western\">For an example of how to do the configuration, refer to yaffs_cfg.c and yaffs_cfg2k.c.</p><p class=\"western\">This part of the configuration involves configuring the chips and suitable access functions.</p><p class=\"western\">This is done in <code class=\"western\">yaffs_StartUp().</code></p><p class=\"western\">Before launching into the device configuration, it is important to understand that Yaffs supports two different modes of operation:</p><ul><li><p class=\"western\">Yaffs1: This is the original mode of operation and is only available for 512-byte-per-page devices.</p></li><li><p class=\"western\">Yaffs2: This mode of operation supports larger page sizes.</p></li></ul><p class=\"western\">Most configuration options are the same for both, but they have different NAND access functions.</p><p class=\"western\">You may have a system that uses a mix of Yaffs1 and Yaffs2 partitions.</p><h3 class=\"western\">9.1 Common configuration items (Yaffs1 and Yaffs2)</h3><p class=\"western\">The configuration involves two parts:</p><ul><li><p class=\"western\">Setting up the mount point table.</p></li><li><p class=\"western\">Setting up the devices.</p></li></ul><p class=\"western\">A <i>yaffsfs_DeviceConfiguration</i> is an entry that has two parts: a mount point name and a pointer to a <i>yaffs_Device</i> structure. The mount point name is used to determine where the particular <i>yaffs_Device</i> may be found in the directory structure. There can be any number of mount points and they may be nested. For example:</p><p class=\"code-western\"><code class=\"western\">static yaffsfs_DeviceConfiguration yaffsfs_config[] = {</code></p><p class=\"code-western\"><code class=\"western\">{ \"/\", &amp;ramDev},</code></p><p class=\"code-western\"><code class=\"western\">{ \"/flash/boot\", &amp;bootDev},</code></p><p class=\"code-western\"><code class=\"western\">{ \"/flash/flash\", &amp;flashDev},</code></p><p class=\"code-western\"><code class=\"western\">{ \"/ram2k\", &amp;ram2kDev},</code></p><p class=\"code-western\"><code class=\"western\">{(void *)0,(void *)0} /* Terminate list */</code></p><p class=\"code-western\"><code class=\"western\">};</code></p><p class=\"western\">Each logical storage entity is called a <i>yaffs_Device</i> and is probably best though of as a partition descriptor. Each <i>yaffs_Device</i> can correspond to:</p><ul><li><p class=\"western\">A whole flash device.</p></li><li><p class=\"western\">Part of a flash device.</p></li><li><p class=\"western\">Something other than a flash device (e.g. perhaps a RAM emulation). During testing, this emulation capability is often employed to use a host system hard-disk file or nfs-mounted file as an alternative storage mechanism.</p></li></ul><p class=\"western\">Two or more<var> </var><var><font face=\"Times, serif\">yaffs_Devices</font></var><var> </var>can reside in a single physical flash device by specifying different start and end blocks. For example here is a case where a single device is split into two partitions:</p><p class=\"code-western\"><code class=\"western\">// /boot<br>......<br>bootDev.param.startBlock = 0; // First block.<br>bootDev.param.endBlock = 55; // Last block in 2MB.<br><br>// /disk<br>...<br>diskDev.param.startBlock = 56; // First block after 2MB<br>diskDev.param.endBlock = 1023; // Last block in 16MB</code></p><p class=\"western\">All <i>yaffs_Device</i> structures must be configured according to the Yaffs Tuning document.</p><h3 class=\"western\">9.2 Common Access Functions (Yaffs1 and Yaffs2)</h3><p class=\"western\">Both Yaffs1 and Yaffs2 configurations must provide pointers to the following functions:</p><p class=\"code-western\"><code class=\"western\">int (*eraseBlockInNAND)(struct yaffs_DeviceStruct *dev,int blockInNAND)</code></p><p class=\"western\">Yaffs calls this function to erase a block of flash.</p><p class=\"western\"><font face=\"Courier New, monospace\"><font size=\"2\"><code class=\"western\">int (*initialiseNAND)(struct yaffs_DeviceStruct *dev)</code></font></font></p><p class=\"western\">Yaffs calls this function at start up before other functions get called to access the <i>yaffs_Device</i>. This allows the system integrator a control point to perform any required initialisation (eg. set up chip selects etc.).</p><h3 class=\"western\">9.3 Yaffs1 Access Functions</h3><p class=\"western\">For Yaffs1 partitions, the yaffs_Device configuration also specifies pointers to two further functions that Yaffs calls to access the NAND for this yaffs_Device. For a better understanding of these functions, see the section on the Yaffs NAND Model. These functions are:</p><p class=\"code-western\"><code class=\"western\">int (*writeChunkToNAND)(struct yaffs_DeviceStruct *dev,int chunkInNAND, const __u8 *data, yaffs_Spare *spare)</code></p><p class=\"western\">Yaffs calls this function to write data to NAND. The <font face=\"Courier, monospace\"><font size=\"2\">data</font></font> pointer may be NULL if only the spare area is being written, as happens when the chunk is being deleted or retired. If the data pointer is NULL then do not write the data. The <font face=\"Courier, monospace\"><font size=\"2\">spare</font></font> pointer will never be NULL.</p><p class=\"code-western\"><code class=\"western\">int (*readChunkFromNAND)(struct yaffs_DeviceStruct *dev,int chunkInNAND, __u8 *data, yaffs_Spare *spare)</code></p><p class=\"western\">Yaffs calls this function when reading a chunk from flash. The meanings of the arguments are obvious from the above, but note that the data and spare fields might be NULL, in which case those pointers should not be dereferenced.</p><h3 class=\"western\">9.4 Yaffs2 Access Functions</h3><p class=\"western\">The Yaffs2 mode of operation is far more flexible than the Yaffs1 mode of operation. That allows for far more different types of flash to be used, but slightly increases the complexity of the NAND access functions.</p><p class=\"western\">With the Yaffs1 mode of operation, Yaffs performs bad block detection and marking and can optionally perform ECC. It can do this because it assumes that the NAND spare area is structured in a certain way. The Yaffs2 mode of operation can no longer make those assumptions which means that the system integrator must provide slightly more complex functions. However, the interface is still relatively simple, particularly if existing code is used as a basis.</p><p class=\"code-western\"><code class=\"western\">int (*writeChunkWithTagsToNAND) (struct yaffs_DeviceStruct * dev,</code></p><p class=\"code-western\"><code class=\"western\">int chunkInNAND, const __u8 * data,</code></p><p class=\"code-western\"><code class=\"western\">const yaffs_ExtendedTags * tags)</code></p><p class=\"code-western\"><code class=\"western\">int (*readChunkWithTagsFromNAND) (struct yaffs_DeviceStruct * dev,</code></p><p class=\"code-western\"><code class=\"western\">int chunkInNAND, __u8 * data,</code></p><p class=\"code-western\"><code class=\"western\">yaffs_ExtendedTags * tags)</code></p><p class=\"code-western\"><code class=\"western\">int (*markNANDBlockBad) (struct yaffs_DeviceStruct * dev, int blockNo);</code></p><p class=\"code-western\"><code class=\"western\">int (*queryNANDBlock) (struct yaffs_DeviceStruct * dev, int blockNo,</code></p><p class=\"code-western\"><code class=\"western\">yaffs_BlockState * state, int *sequenceNumber)</code></p><p class=\"western\">The <code class=\"western\">writeChunkWithTagsToNAND()</code> and <code class=\"western\">readChunkWithTagsFromNAND()</code> functions must save or retrieve the data and extended tags. Please refer to the explanation of the Yaffs2 NAND model for a better understanding of how to handle the tags. Please note that under certain circumstances, the <font face=\"Courier, monospace\">data</font> and <font face=\"Courier, monospace\">tags</font> pointers may be NULL and the driver code should ignore transfers from or to pointers that are NULL.</p><p class=\"western\">The NAND access functions must also provide a mechanism for marking and tracking bad blocks. If a bad block is detected and Yaffs decides to mark that block bad, the <code class=\"western\">markNANDBlockBad()</code><font color=\"#000000\"><font face=\"Courier, monospace\"><font size=\"2\"> </font></font></font><font color=\"#000000\"><font face=\"Liberation Serif, serif\">function is called.</font></font></p><p class=\"western\">The <code class=\"western\">queryNANDBlock()</code> function does two things:</p><ul><li><p class=\"western\">It determines the block state</p></li><li><p class=\"western\">If the block is in use it also retrieves the block’s sequence number.</p></li></ul><p class=\"western\">By far the easiest way to understand this all is to refer to the example code provided.</p><h2 class=\"western\">10 Using the POSIX file system interface</h2><p class=\"western\">This section is directed to readers that might not be very familiar with accessing a file system via POSIX and POSIX-like interfaces.</p><h3 class=\"western\">10.1 Difference to Windows POSIX-like interfaces</h3><p class=\"western\">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><ul><li><p class=\"western\">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></li><li><p class=\"western\">Windows names drives with a letter. POSIX has no drive letters. The whole POSIX file system is in a single directory tree.</p></li><li><p class=\"western\">Directories and “folders” are the same thing.</p></li></ul><h3 class=\"western\">10.2 Fundamental concepts</h3><table cellpadding=\"4\" cellspacing=\"0\" width=\"642\"><colgroup><col width=\"126\"><col width=\"499\"></colgroup><tbody><tr valign=\"TOP\"><td style=\"border-top-style: solid; border-top-color: rgb(0, 0, 0); border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0.1cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"126\"><p class=\"western\">File</p></td><td style=\"border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); padding-top: 0.1cm; padding-right: 0.1cm; padding-bottom: 0.1cm; padding-left: 0.1cm; \" width=\"499\"><p class=\"western\">A file is an object that is stored in the file system. yaffs supports the following file types:</p><p class=\"western\">A regular file is a sequence of bytes stored in the file system.</p><p class=\"western\">A directory holds links to other files.</p><p class=\"western\">A symbolic link holds a name to another file.</p><p class=\"western\">A special file holds device ids or similar information.</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"126\"><p class=\"western\">Directory</p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"499\"><p class=\"western\">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></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"126\"><p class=\"western\">Link</p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"499\"><p class=\"western\">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></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"126\"><p class=\"western\">Handle</p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"499\"><p class=\"western\">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></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"126\"><p class=\"western\">File mode</p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"499\"><p class=\"western\">The mode is the set of flags that define the type of file as well as the current permissions associated with the file.</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"126\"><p class=\"western\">Path</p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"499\"><p class=\"western\">This is a string that defines the directories and file name. For example:</p><p class=\"western\">“/data/direct-1/file1”</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"126\"><p class=\"western\">File metadata</p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"499\"><p class=\"western\">This is the information about the file, excluding the file contents. The metadata includes the name, mode, size and other details.</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"126\"><p class=\"western\">Mount,<br>partition,<br>file system</p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"499\"><p class=\"western\">These terms all refer to a single mounted flash area. Each mount is hooked into a common directory structure.<br>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></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"126\"><p class=\"western\">inode number</p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"499\"><p class=\"western\">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></td></tr></tbody></table><h3 class=\"western\">10.3 Error code</h3><p class=\"western\">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><p class=\"western\">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><h3 class=\"western\">10.4 Links – the hard kind (not symbolic links)</h3><p class=\"western\">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><p class=\"western\">The difference between links and files is subtle and can be confusing. Briefly:</p><ul><li><p class=\"western\">a file is the stored object in the file system</p></li><li><p class=\"western\">the link is how it is hooked into the directory structure.</p></li></ul><p class=\"western\">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><p class=\"western\">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><p class=\"western\">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><p class=\"western\">A link can be renamed by using the <code class=\"western\">yaffs_rename()</code> function.</p><p class=\"western\">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><p class=\"western\">Thus:</p><ol><li><p class=\"western\">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></li><li><p class=\"western\">If we now unlink “a”, the file still exists under the link “b”.</p></li><li><p class=\"western\">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></li><li><p class=\"western\">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></li></ol><p class=\"western\">There are some limitations in how links are used:</p><ul><li><p class=\"western\">The existing file you are linking to must exist.</p></li><li><p class=\"western\">The file you are linking to must be in the same mount (partition) as the link you are creating.</p></li><li><p class=\"western\">You cannot create a link to a directory because this would allow the creation of recursive loops.</p></li><li><p class=\"western\">The new link name must not exist.</p></li></ul><h3 class=\"western\">10.5 Symbolic links</h3><p class=\"western\">Now that you understand how hard links work, we\'ll introduce symbolic (or soft) links.</p><p class=\"western\">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><p class=\"western\">You can remove symbolic links with the <code class=\"western\">yaffs_unlink()</code> function, just like hard links.</p><p class=\"western\">There are, however, some important differences. A symbolic link only does its linking function when the path is being evaluated and thus:</p><ul><li><p class=\"western\">The file you are creating an alias to does not have to exist.</p></li><li><p class=\"western\">The file you are creating an alias to does not have to be in the same mount.</p></li><li><p class=\"western\">You can create symbolic links to directories.</p></li><li><p class=\"western\">A symbolic link will not keep a file alive by itself. Only a hard link can do that.</p></li></ul><p class=\"western\">Thus:</p><ol><li><p class=\"western\">If we start with a file called “a” and then call <code class=\"western\">yaffs_symlink(“a”, “b”)</code> we now have one links to the file called “a” and a symbolic link aliasising from “b” to “a”.</p></li><li><p class=\"western\">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></li><li><p class=\"western\">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></li><li><p class=\"western\">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></li></ol><h3 class=\"western\">10.6 Handle-based file handling</h3><p class=\"western\">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><p class=\"western\">A handle is identified by an integer of value 0 or greater.</p><p class=\"western\">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><p class=\"western\">A handle remains valid until the handle is closed by <code class=\"western\">yaffs_close()</code>.</p><p class=\"western\">The <code class=\"western\">yaffs_open()</code> call takes three parameters:</p><ul><li><p class=\"western\">name: Full path name of the file being opened.</p></li><li><p class=\"western\">access flags: Flags being used to open this handle</p></li><li><p class=\"western\">creation mode: Mode flags used when creating a file.</p></li></ul><p class=\"western\">The access flags are one or more of:</p><table cellpadding=\"4\" cellspacing=\"0\" width=\"100%\"><colgroup><col width=\"59*\"><col width=\"197*\"></colgroup><tbody><tr valign=\"TOP\"><td style=\"border-top-style: solid; border-top-color: rgb(0, 0, 0); border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0.1cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"23%\"><p class=\"western\"><font face=\"Courier, monospace\"><font size=\"2\"><code class=\"western\">O_CREAT</code></font></font></p></td><td style=\"border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); padding-top: 0.1cm; padding-right: 0.1cm; padding-bottom: 0.1cm; padding-left: 0.1cm; \" width=\"77%\"><p class=\"western\">Create file if it does not already exist.</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"23%\"><p class=\"western\"><font face=\"Courier, monospace\"><font size=\"2\"><code class=\"western\">O_EXCL</code></font></font></p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"77%\"><p class=\"western\">Only use with O_CREAT. Create file if it does not exist. If the file already exists then fail.</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"23%\"><p class=\"western\"><font face=\"Courier, monospace\"><font size=\"2\"><code class=\"western\">O_TRUNC</code></font></font></p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"77%\"><p class=\"western\">If the file exists, and opening with write access, then truncate the file to zero bytes long.</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"23%\"><p class=\"western\">&nbsp;</p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"77%\"><p class=\"western\">&nbsp;</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"23%\"><p class=\"western\"><font face=\"Courier, monospace\"><font size=\"2\"><code class=\"western\">O_APPEND</code></font></font></p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"77%\"><p class=\"western\">Regardless of the handle position, always write to the end of the file.</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"23%\"><p class=\"western\">&nbsp;</p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"77%\"><p class=\"western\">&nbsp;</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"23%\"><p class=\"western\"><font face=\"Courier, monospace\"><font size=\"2\"><code class=\"western\">O_RDWR</code></font></font></p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"77%\"><p class=\"western\">Open for read/write access.</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"23%\"><p class=\"western\"><font face=\"Courier, monospace\"><font size=\"2\"><code class=\"western\">O_WRONLY</code></font></font></p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"77%\"><p class=\"western\">Open for write access and no read access.</p><p class=\"western\">&nbsp;</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"23%\"><p class=\"western\">&nbsp;</p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"77%\"><p class=\"western\">If neither O_RDWR or O_WRONLY is set then the file will be opened for read-only access.</p></td></tr></tbody></table><p class=\"western\">Where they are not mutually exclusive, these flags are typically combined. For example:</p><p class=\"western\"><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><p class=\"western\"><code class=\"western\">O_CREAT | OEXCL | O_WRONLY</code> : Create a new file, opening it for write only. Fails if file already exists.</p><p class=\"western\">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><table cellpadding=\"4\" cellspacing=\"0\" width=\"100%\"><colgroup><col width=\"59*\"><col width=\"197*\"></colgroup><tbody><tr valign=\"TOP\"><td style=\"border-top-style: solid; border-top-color: rgb(0, 0, 0); border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0.1cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"23%\"><p class=\"western\"><font face=\"Courier New, monospace\"><font size=\"2\"><code class=\"western\">S_IREAD</code></font></font></p></td><td style=\"border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); padding-top: 0.1cm; padding-right: 0.1cm; padding-bottom: 0.1cm; padding-left: 0.1cm; \" width=\"77%\"><p class=\"western\">The file may be opened for read access.</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"23%\"><p class=\"western\"><font face=\"Courier New, monospace\"><font size=\"2\"><code class=\"western\">S_IWRITE</code></font></font></p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"77%\"><p class=\"western\">The file may be opened for write access.</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"23%\"><p class=\"western\"><font face=\"Courier New, monospace\"><font size=\"2\"><code class=\"western\">S_IEXEC</code></font></font></p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"77%\"><p class=\"western\">The file may be opened for execution. This is not enforced by yaffs.</p></td></tr></tbody></table><p class=\"western\">Once you have opened a handle you can then do various operations on the file.</p><table cellpadding=\"4\" cellspacing=\"0\" width=\"100%\"><colgroup><col width=\"114*\"><col width=\"142*\"></colgroup><tbody><tr valign=\"TOP\"><td style=\"border-top-style: solid; border-top-color: rgb(0, 0, 0); border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0.1cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"45%\"><p class=\"western\"><font face=\"Courier New, monospace\"><font size=\"2\"><code class=\"western\">yaffs_close(handle)</code></font></font></p></td><td style=\"border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); padding-top: 0.1cm; padding-right: 0.1cm; padding-bottom: 0.1cm; padding-left: 0.1cm; \" width=\"55%\"><p class=\"western\">Close the handle. It is no longer usable.</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"45%\"><p class=\"western\"><font face=\"Courier New, monospace\"><font size=\"2\"><code class=\"western\">yaffs_fsync(handle)</code></font></font></p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"55%\"><p class=\"western\">Flush out any cached writes to the file, as well as the file meta-data.</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"45%\"><p class=\"western\"><font face=\"Courier New, monospace\"><font size=\"2\"><code class=\"western\">yaffs_datasync(handle)</code></font></font></p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"55%\"><p class=\"western\">Same as yaffs_fsync() but no file metadata.</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"45%\"><p class=\"western\"><font face=\"Courier New, monospace\"><font size=\"2\"><code class=\"western\">yaffs_flush(handle)</code></font></font></p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"55%\"><p class=\"western\">Same as yaffs_fsync()</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"45%\"><p class=\"western\"><font face=\"Courier New, monospace\"><font size=\"2\"><code class=\"western\">yaffs_dup(handle)</code></font></font></p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"55%\"><p class=\"western\">Duplicates a handle.</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"45%\"><p class=\"western\"><font face=\"Courier New, monospace\"><font size=\"2\"><code class=\"western\">yaffs_lseek(handle, offset, whence)</code></font></font></p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"55%\"><p class=\"western\">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></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"45%\"><p class=\"western\"><font face=\"Courier New, monospace\"><font size=\"2\"><code class=\"western\">yaffs_ftruncate(handle, size)</code></font></font></p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"55%\"><p class=\"western\">Change the file size. It can be made bigger or smaller. This does not change the handle read/write position.</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"45%\"><p class=\"western\"><font face=\"Courier New, monospace\"><font size=\"2\"><code class=\"western\">yaffs_fstat(handle, buf)</code></font></font></p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"55%\"><p class=\"western\">Get file status.</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"45%\"><p class=\"western\"><font face=\"Courier New, monospace\"><font size=\"2\"><code class=\"western\">yaffs_fchmod(handle, mode)</code></font></font></p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"55%\"><p class=\"western\">Change the file mose.</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"45%\"><p class=\"western\">&nbsp;</p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"55%\"><p class=\"western\">&nbsp;</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"45%\"><p class=\"western\"><font face=\"Courier New, monospace\"><font size=\"2\"><code class=\"western\">yaffs_read(handle, buffer, nbytes)</code></font></font></p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"55%\"><p class=\"western\">Read data from file at file pointer and update pointer.</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"45%\"><p class=\"western\"><font face=\"Courier New, monospace\"><font size=\"2\"><code class=\"western\">yaffs_pread(handle, buffer, nbytes, position)</code></font></font></p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"55%\"><p class=\"western\">Read data from file at specified position. Does not modify file pointer</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"45%\"><p class=\"western\"><font face=\"Courier New, monospace\"><font size=\"2\"><code class=\"western\">yaffs_write(handle, buffer, nbytes)</code></font></font></p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"55%\"><p class=\"western\">Write data to file at file pointer and update pointer.</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"45%\"><p class=\"western\"><font face=\"Courier New, monospace\"><font size=\"2\"><code class=\"western\">yaffs_pread(handle, buffer, nbytes, position)</code></font></font></p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"55%\"><p class=\"western\">Write data to file at specified position. Does not modify file pointer</p></td></tr></tbody></table><h3 class=\"western\">10.7 Changing file size</h3><p class=\"code-western\"><code class=\"western\">yaffs_truncate(path, newSize)</code></p><p class=\"code-western\"><code class=\"western\">yaffs_ftruncate(handle, newSize)</code></p><p class=\"western\">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><p class=\"western\">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><p class=\"western\">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><h3 class=\"western\">10.8 Getting/setting information about files</h3><p class=\"code-western\"><code class=\"western\">yaffs_chmod(path, mode)</code></p><p class=\"code-western\"><code class=\"western\">yaffs_fchmod(handle, mode)</code></p><p class=\"code-western\">&nbsp;</p><p class=\"code-western\"><code class=\"western\">yaffs_access(path,amode)</code></p><p class=\"code-western\">&nbsp;</p><p class=\"code-western\"><code class=\"western\">yaffs_stat(path, struct yaffs_stat *buf) </code></p><p class=\"code-western\"><code class=\"western\">yaffs_fstat(handle, struct yaffs_stat *buf)</code></p><p class=\"code-western\"><code class=\"western\">yaffs_lstat(path, struct yaffs_stat *buf)</code></p><p class=\"code-western\"><code class=\"western\">yaffs_readlink(path, buf, bufsize)</code></p><p class=\"western\">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><p class=\"western\"><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><p class=\"western\">amode is a bitmask of the following values:</p><table cellpadding=\"4\" cellspacing=\"0\" width=\"100%\"><colgroup><col width=\"43*\"><col width=\"213*\"></colgroup><tbody><tr valign=\"TOP\"><td style=\"border-top-style: solid; border-top-color: rgb(0, 0, 0); border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0.1cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"17%\"><p class=\"western\"><font face=\"Courier New, monospace\"><font size=\"2\"><code class=\"western\">R_OK</code></font></font></p></td><td style=\"border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-left-color: rgb(0, 0, 0); padding-top: 0.1cm; padding-right: 0.1cm; padding-bottom: 0.1cm; padding-left: 0.1cm; \" width=\"83%\"><p class=\"western\">Check read is OK</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"17%\"><p class=\"western\"><font face=\"Courier New, monospace\"><font size=\"2\"><code class=\"western\">W_OK</code></font></font></p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"83%\"><p class=\"western\">Check write is OK</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"17%\"><p class=\"western\"><font face=\"Courier New, monospace\"><font size=\"2\"><code class=\"western\">X_OK</code></font></font></p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"83%\"><p class=\"western\">Check execute is OK.</p></td></tr><tr valign=\"TOP\"><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: none; border-right-width: initial; border-right-color: initial; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm; \" width=\"17%\"><p class=\"western\"><font face=\"Courier New, monospace\"><font size=\"2\"><code class=\"western\">0 (zero)</code></font></font></p></td><td style=\"border-top-style: none; border-top-width: initial; border-top-color: initial; border-bottom-style: solid; border-bottom-color: rgb(0, 0, 0); border-left-style: solid; border-left-color: rgb(0, 0, 0); border-right-style: solid; border-right-color: rgb(0, 0, 0); padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm; \" width=\"83%\"><p class=\"western\">Just checks the file exists</p></td></tr></tbody></table><p class=\"western\">These can be combined.</p><p class=\"western\">For example:</p><p class=\"code-western\"><code class=\"western\">if(yaffs_access(path, R_OK | W_OK) == 0)</code></p><p class=\"code-western\"><code class=\"western\">the file exists and can be read and written</code></p><p class=\"code-western\"><code class=\"western\">if(yaffs_access(path, 0) == 0)</code></p><p class=\"code-western\"><code class=\"western\">the file exists</code></p><p class=\"western\"><br>&nbsp;</p><p class=\"western\">The stat calls retrieve a yaffs_stat structure of data which is defined in yaffsfs.h. There are three versions:</p><p class=\"western\"><code class=\"western\">yaffs_fstat</code>: Takes a handle.</p><p class=\"western\"><code class=\"western\">yaffs_stat</code>: Takes a path name and follows symbolic links.</p><p class=\"western\"><code class=\"western\">yaffs_lstat</code>: Takes a path but does not follow symbolic links.</p><p class=\"western\"><br>&nbsp;</p><p class=\"western\">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><p class=\"western\"><code class=\"western\">yaffs_readlink()</code> will read the read the link value into the buffer provided. For example:</p><p class=\"code-western\"><code class=\"western\">yaffs_symlink(“target”,”/link”); /* create a link called link to target */</code></p><p class=\"code-western\"><code class=\"western\">yaffs_readlink(“/link”,buffer,10); /* now buffer contains “target” */</code></p><h3 class=\"western\">10.9 Changing the directory structure and names</h3><p class=\"code-western\"><code class=\"western\">yaffs_open(path, flags, mode)</code></p><p class=\"code-western\"><code class=\"western\">yaffs_mkdir(path, mode)</code></p><p class=\"code-western\"><code class=\"western\">yaffs_symlink(targetPath, linkPath)</code></p><p class=\"code-western\"><code class=\"western\">yaffs_mknod(pathname, mode, dev)</code></p><p class=\"code-western\">&nbsp;</p><p class=\"code-western\"><code class=\"western\">yaffs_link(existingPath, newath)</code></p><p class=\"code-western\">&nbsp;</p><p class=\"code-western\"><code class=\"western\">yaffs_unlink(path)</code></p><p class=\"code-western\"><code class=\"western\">yaffs_rmdir(path)</code></p><p class=\"code-western\">&nbsp;</p><p class=\"code-western\"><code class=\"western\">yaffs_rename(oldPath, newPath)</code></p><p class=\"western\"><br>&nbsp;</p><p class=\"western\">Files of various types, and their first link, are created via the <code class=\"western\">yaffs_open()</code><code class=\"western\"><font face=\"Liberation Serif, serif\">,</font></code><font face=\"Courier New, monospace\"><font size=\"2\"> </font></font><code class=\"western\">yaffs_mkdir()</code><font face=\"Liberation Serif, serif\"><font size=\"2\">, </font></font><code class=\"western\">yaffs_symlink()</code> and <code class=\"western\">yaffs_mknod()</code><font face=\"Liberation Serif, serif\"> </font>functions.</p><p class=\"western\"><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><p class=\"western\"><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><h3 class=\"western\">10.10 Searching directories</h3><p class=\"code-western\"><code class=\"western\">yaffs_DIR *yaffs_opendir(const YCHAR *dirname) ; </code></p><p class=\"code-western\"><code class=\"western\">struct yaffs_dirent *yaffs_readdir(yaffs_DIR *dirp) ; </code></p><p class=\"code-western\"><code class=\"western\">void yaffs_rewinddir(yaffs_DIR *dirp) ; </code></p><p class=\"code-western\"><code class=\"western\">int yaffs_closedir(yaffs_DIR *dirp) ;</code></p><p class=\"western\">Searching is performed by the following sequence of operations:</p><ul><li><p class=\"western\">Open the directory for reading with <code class=\"western\">yaffs_opendir()</code>.</p></li><li><p class=\"western\">Iterate through the entries in the directory using <code class=\"western\">yaffs_readdir()</code>. Each read will advance the directory read position.</p></li><li><p class=\"western\">You can reset to the start of the directory with <code class=\"western\">yaffs_rewinddir()</code>.</p></li><li><p class=\"western\">Close the directory when finished with <code class=\"western\">yaffs_closedir()</code>.</p></li></ul><h3 class=\"western\">10.11 Mount control</h3><p class=\"code-western\"><code class=\"western\">yaffs_mount(path) ; </code></p><p class=\"code-western\"><code class=\"western\">yaffs_mount2(path, readOnly); </code></p><p class=\"code-western\"><code class=\"western\">yaffs_unmount(path);</code></p><p class=\"code-western\"><code class=\"western\">yaffs_unmount2(path, int force); </code></p><p class=\"code-western\"><code class=\"western\">yaffs_remount(path, force, readOnly);</code></p><p class=\"code-western\"><code class=\"western\">yaffs_sync(path) ;</code></p><p class=\"western\">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><p class=\"western\">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.</p><p class=\"western\"><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><p class=\"western\"><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><h3 class=\"western\">10.12 Other</h3><p class=\"code-western\"><code class=\"western\">yaffs_freespace(path); </code></p><p class=\"code-western\"><code class=\"western\">yaffs_totalspace(path); </code></p><p class=\"code-western\"><code class=\"western\">yaffs_inodecount(path);</code></p><p class=\"western\">These functions provide information on the free and total space (in bytes) for the mount that the path addresses.</p><p class=\"western\"><code class=\"western\">yaffs_inodecount()</code> returns the number of files on the mount that the path addresses.</p><h3 class=\"western\">11 Example: yaffs_readdir() and yaffs_stat()</h3><p class=\"western\">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><p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">void dump_directory(const char *dname) </font></code></p><p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">{ </font></code></p><p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">yaffs_DIR *d; </font></code></p><p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">yaffs_dirent *de; </font></code></p><p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">struct yaffs_stat s; </font></code></p><p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">char str[100]; </font></code></p><p class=\"code-western\">&nbsp;</p><p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">d = yaffs_opendir(dname); </font></code></p><p class=\"code-western\">&nbsp;</p><p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">if(!d) </font></code></p><p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">{ </font></code></p><p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">printf(\"opendir failed\\n\"); </font></code></p><p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">} </font></code></p><p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">else </font></code></p><p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">{ </font></code></p><p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">while((de = yaffs_readdir(d)) != NULL) </font></code></p><p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">{ </font></code></p><p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">sprintf(str,\"%s/%s\",dname,de-&gt;d_name); </font></code></p><p class=\"code-western\">&nbsp;</p><p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">yaffs_lstat(str,&amp;s); </font></code></p><p class=\"code-western\">&nbsp;</p><p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">printf(\"%s inode %d length %d mode %X \",</font></code></p><p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">str,s.st_ino,(int)s.st_size,s.st_mode); </font></code></p><p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">switch(s.st_mode &amp; S_IFMT) </font></code></p><p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">{ </font></code></p><p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">case S_IFREG: printf(\"data file\"); break; </font></code></p><p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">case S_IFDIR: printf(\"directory\"); break; </font></code></p><p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">case S_IFLNK: printf(\"symlink --&gt;\"); </font></code></p><p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">if(yaffs_readlink(str,str,100) &lt; 0) </font></code></p><p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">printf(\"no alias\"); </font></code></p><p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">else </font></code></p><p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">printf(\"\\\"%s\\\"\",str);</font></code></p><p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">break; </font></code></p><p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">default: printf(\"unknown\"); break; </font></code></p><p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">} </font></code></p><p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">printf(\"\\n\"); </font></code></p><p class=\"code-western\">&nbsp;</p><p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">if((s.st_mode &amp; S_IFMT) == S_IFDIR) </font></code></p><p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">dump_directory_tree_worker(str); </font></code></p><p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">} </font></code></p><p class=\"code-western\">&nbsp;</p><p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">yaffs_closedir(d); </font></code></p><p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">} </font></code></p><p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">}&nbsp;</font></code></p><p>&nbsp;</p>','<p>This describes the Yaffs Direct Interface (YDI), which allows Yaffs to be simply integrated with embedded systems, with or without an RTOS.</p><p>&nbsp;</p>','filtered_html');
