ass=\"western\"><font face=\"Liberation Serif, serif\">top_level:\r\n	depth of the Tnode tree</font></p>\r\n	<li/>\r\n<p class=\"western\"><font face=\"Liberation Serif, serif\">top:\r\n	pointer to top of Tnode tree</font></p>\r\n</ul>\r\n<p class=\"western\">The meaning of the file size is quite obvious.\r\nThis is the current length of the file. Note that a file might have\r\nholes in it caused by seeking forward past the extents of the file.</p>\r\n<p class=\"western\">The top and top_level work together to control the\r\nTnode trees. \r\n</p>\r\n<h3 class=\"western\" style=\"page-break-before: always\">12.6.1 Tnode\r\ntree</h3>\r\n<p class=\"western\">Each file has a tnode tree to provide the mapping\r\nfrom file position to actual NAND chunk address. top is a pointer to\r\nthe top of the tnode tree</p>\r\n\r\n<p class=\"western\"><img src=\"data:image/png;base64,[encoded data, 20236 characters]\" name=\"Object1\" align=\"left\" width=\"385\" height=\"378\">\r\n  <br clear=\"left\"/>\r\n</img>\r\n<br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\">The tnode tree is made up of tnodes (tree nodes)\r\narranged in levels, each of which holds either:</p>\r\n<ul>\r\n	<li/>\r\n<p class=\"western\">At levels greater than 0, a tnode has 8\r\n	pointers to other tnodes in the next level down.</p>\r\n	<li/>\r\n<p class=\"western\">At level 0, a tnode has 16 NAND chunk Ids\r\n	which identify the chunk\'s location in RAM.</p>\r\n</ul>\r\n<p class=\"western\">These numbers are powers of 2 which makes for\r\nsimple look-ups by just applying bitmasks. The code that traverses\r\nthis tree is in yaffs_find_tnode_0().</p>\r\n<p class=\"western\">As the file size grows, more tnodes are added and\r\nas the levels fill, more levels are added. If the file is truncated\r\nor resized downwards, then the tree is pruned. If a chunk in a file\r\nis replaced (eg. data is overwritten or copied by garbage collection)\r\nthen the tnode tree must be updated to reflect the change.</p>\r\n<p class=\"western\">Tnodes typically make up the bulk of the Yaffs\'\r\nRAM usage.</p>\r\n<h1 class=\"western\">13 How various mechanisms work</h1>\r\n<p class=\"western\">Having looked at the Yaffs data structures, we now\r\nconsider how some of the mechanisms in Yaffs operates. This is most\r\neasily done by walking through some operations that Yaffs performs.</p>\r\n<h2 class=\"western\">13.1 Block and chunk management</h2>\r\n<h3 class=\"western\">13.1.1 Block states</h3>\r\n<p class=\"western\">Yaffs tracks the state of each block and chunk in\r\nthe partition. This information is first built up during scanning (or\r\nrecovered from a checkpoint). A block may be in one of the following\r\nstates (see definition of  enum yaffs_block_state):</p>\r\n\r\n<table width=\"605\" cellpadding=\"4\" cellspacing=\"0\">\r\n	<col width=\"146\">\r\n	<col width=\"441\">\r\n	<tr valign=\"top\">\r\n		<td width=\"146\" style=\"border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0.1cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\">UNKNOWN</p>\r\n		</td>\r\n		<td width=\"441\" style=\"border: 1px solid #000000; padding: 0.1cm\">\r\n			<p class=\"western\">The block state is not yet known.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"146\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\">NEEDS_SCANNING</p>\r\n		</td>\r\n		<td width=\"441\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\">During pre-scanning it has been determined that\r\n			this block has something on it and needs scanning.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"146\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\">SCANNING</p>\r\n		</td>\r\n		<td width=\"441\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\">This block is currently being scanned.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"146\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\">EMPTY</p>\r\n		</td>\r\n		<td width=\"441\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\">This block has nothing in it (is erased) and\r\n			may be used for allocation. The block can get to this state by\r\n			being erased.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"146\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\">ALLOCATING</p>\r\n		</td>\r\n		<td width=\"441\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\">This is the block currently being used for\r\n			allocation by the chunk allocator.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"146\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\">FULL</p>\r\n		</td>\r\n		<td width=\"441\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\">All the chunks in this block have been\r\n			allocated and at least one chunk contains useful information that\r\n			has not yet been deleted.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"146\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\">DIRTY</p>\r\n		</td>\r\n		<td width=\"441\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\">All the chunks in this block have been\r\n			allocated and all have been deleted. The block might have been in\r\n			the FULL or COLLECTING state before this. This block can now be\r\n			erased and returned to EMPTY state.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"146\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\">CHECKPOINT</p>\r\n		</td>\r\n		<td width=\"441\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\">This block has checkpoint data in it. When the\r\n			checkpoint is invalidated this block will be erased and returned\r\n			to the EMPTY state.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"146\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\">COLLECTING</p>\r\n		</td>\r\n		<td width=\"441\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\">This block is being garbage collected. As soon\r\n			as all live data has been inspected this block becomes DIRTY.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"146\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\">DEAD</p>\r\n		</td>\r\n		<td width=\"441\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\">This block has been retired or was marked bad.\r\n			This is a terminal state.</p>\r\n		</td>\r\n	</tr>\r\n</table>\r\n<p class=\"western\"><img src=\"data:image/png;base64,[encoded data, 42088 characters]\" name=\"Object3\" align=\"left\" width=\"575\" height=\"510\">\r\n  <br clear=\"left\"/>\r\n</img>\r\n<br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\">The regular runtime states are; EMPTY, ALLOCATING,\r\nFULL, COLLECTING and DIRTY.</p>\r\n<p class=\"western\">The checkpoint state is used for checkpoint\r\nblocks.</p>\r\n<p class=\"western\">The DEAD state is the terminal state for blocks\r\nthat were retired because they were either marked bad or an error was\r\ndetected.</p>\r\n<h3 class=\"western\">13.1.2 Block and chunk allocation</h3>\r\n<p class=\"western\">An available chunk must be allocated before it can\r\nbe written. The chunk allocation mechanism is provided by\r\nyaffs_alloc_chunk() and is very simple. Each yaffs_dev has a current\r\nblock that it is allocating from. This is termed the <i><b>allocation\r\nblock </b></i><i><b>(alloc_block)</b></i>. Chunks are allocated\r\nsequentially from the allocation block. As the chunks are allocated,\r\nblock and chunk management information is updated, including the\r\nblock\'s pages_in_use count and the chunk use bitmap.</p>\r\n<p class=\"western\">When the block is fully allocated, another empty\r\nblock is selected to become the allocation block. The blocks are\r\nselected by searching upwards from the previous allocation block.</p>\r\n<p class=\"western\">In older versions of Yaffs, the Yaffs scanning\r\nwould identify the allocation block being used when the file system\r\nwas last shut down and would continue allocation from that point.\r\nThis had the benefit of continuing to use the same block and slightly\r\nreduce garbage creation. However, doing this could potentially cause\r\nproblems due to attempting to write a block that had been in the\r\nmiddle of a write when power was lost. Thus Yaffs now always starts\r\nallocation on a new block after a mount. This slightly increases the\r\namount of garbage (typically by an insignificant amount) but improves\r\nrobustness.</p>\r\n<h3 class=\"western\">13.1.3 A word about wear leveling</h3>\r\n<p class=\"western\">Since flash memory blocks can only endure a\r\nlimited number of writes and erases ( termed the flash endurance), a\r\nflash file system needs to ensure that the same few blocks are not\r\noverwritten continuously causing those blocks to wear out while the\r\nother blocks are hardly used at all.. Instead it is important that\r\nthe file system spreads out the wear.</p>\r\n<p class=\"western\">This is extremely important in a file system such\r\nas FAT which uses a limited set of logical blocks to store the file\r\nallocation table entries which get modified frequently. If FAT is\r\nused with a static logical to physical block mapping then the file\r\nallocation table blocks will wear out far before other blocks causing\r\npremature device failure. Thus, for FAT, it is very important that\r\nthe logical to physical mapping gets stirred up a bit to cause the\r\nfile allocation tables to be written to different physical blocks,\r\nthus leveling out the wear.</p>\r\n<p class=\"western\">Wear leveling is far less of a concern in a log\r\nstructured file system such as Yaffs since we always write to the end\r\nof the log and thus don\'t keep on overwriting the same blocks.</p>\r\n<p class=\"western\">There are basically two ways to achieve wear\r\nleveling:</p>\r\n<ul>\r\n	<li/>\r\n<p class=\"western\"><font face=\"Liberation Serif, serif\">Use a\r\n	specifically written set of functions that actively perform wear\r\n	leveling.</font></p>\r\n	<li/>\r\n<p class=\"western\"><font face=\"Liberation Serif, serif\">Allow\r\n	a degree of wear leveling to happen as a side effect of other\r\n	activity.</font></p>\r\n</ul>\r\n<p class=\"western\">Yaffs takes the second approach.</p>\r\n<p class=\"western\">Firstly, being log structured, Yaffs inherently\r\nspreads out the wear by performing all writes in sequence. That means\r\nthat we don\'t single out a few blocks for a specific purpose and\r\nwrite them more than others.</p>\r\n<p class=\"western\">Secondly, blocks are allocated serially from the\r\nerased blocks in the partition. Thus the process of erasing (after\r\ndeletion of garbage collection) and then allocating blocks does tend\r\nto spread the block use and provides a level of wear leveling.</p>\r\n<p class=\"western\">Thus, even though there is no code to specifically\r\nperform wear leveling it does happen as a side effect of other\r\nactivity.</p>\r\n<p class=\"western\">This strategy performs well and has survived many\r\naccelerated lifetime tests in both simulations and on real NAND-based\r\nproducts.</p>\r\n<h3 class=\"western\">13.1.4 Management of yaffs_tnode and yaffs_obj\r\nstructures</h3>\r\n<p class=\"western\">yaffs_tnodes and yaffs_objs are dynamically\r\ncreated and released as they are needed. \r\n</p>\r\n<p class=\"western\">The allocation and management could be done by\r\njust using the standard memory allocator (malloc, kmalloc etc), but\r\nthis could cause performance problems, particularly in embedded\r\nsystems which tend to have rather simplistic memory allocators. \r\n</p>\r\n<p class=\"western\">The allocation and deletion of many small\r\nstructures can cause memory fragmentation causing out-of-memory and\r\nslowdown problems.</p>\r\n<p class=\"western\">To prevent these problems, Yaffs manages these\r\nobjects internally. Yaffs creates many structures (100 or so) at a\r\ntime and then allocates them singly from a free list. When structures\r\nare released they are placed on the free list for reuse.</p>\r\n<h2 class=\"western\">13.2 Internal cache</h2>\r\n<p class=\"western\">This describes the standard Yaffs internal cache\r\nimplementation. Alternative caches have been devised for other\r\npurposes and at some future point Yaffs might be extended to support\r\npluggable cache policies.</p>\r\n<p class=\"western\">The main purpose of the internal cache is to\r\nreduce NAND access for  badly behaved applications which perform many\r\nsmall reads and writes. Believe it or not, but there are applications\r\nout there that read or write files a few bytes at a time:</p>\r\n<p class=\"code-western\"><code class=\"western\">while(...)<br/>\r\n	write(h,buf,1);</code></p>\r\n<p class=\"western\" style=\"margin-left: 1.25cm\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\">This sort of behavior would be terrible for\r\nperformance and flash memory life if each read or write operation\r\nresulted in a flash access. Yaffs provides an internal cache to\r\nmitigate against this sort of behaviour.</p>\r\n<p class=\"western\">The Yaffs internal cache is called a “Short Op\r\nCache” (short operation cache) and only comes in to play for\r\noperations which are not chunk aligned. The caching mechanism is very\r\nsimple and was primarily written for less sophisticated OSs that lack\r\ntheir own file caching layer. The cache is still beneficial in OSs\r\nlike Linux, which provide a caching layer, because it caches both the\r\nread and write path. Thus, while short reads will be serviced by the\r\nLinux page cache, the short op cache does address non-chunk aligned\r\nwrites.</p>\r\n<p class=\"western\">Page aligned reads/writes bypass the cache unless\r\nthat chunk is already in the cache, except when inband tags are used.\r\nInband tags always require the cache because the cache is used to\r\nbuild up the buffer where the tags are attached to the data chunk\r\nbeing written.</p>\r\n<p class=\"western\">The cache is stored in an array of cache entries.\r\nThe number of cache entries is set in the yaffs_dev parameters\r\nn_caches and the cache is configured during initialisation. n_caches\r\nof zero disables the cache. The cache management algorithms are\r\nsimplistic and probably don\'t scale well to very large numbers. This\r\nmeans that it is probably best to stick with around 5 to 20 cache\r\nentries.</p>\r\n<p class=\"western\">Each cache entry holds:</p>\r\n<ul>\r\n	<li/>\r\n<p class=\"western\">obj_id, chunk id, nbytes (the tag info of\r\n	the chunk being cached)</p>\r\n	<li/>\r\n<p class=\"western\">The actual data bytes</p>\r\n	<li/>\r\n<p class=\"western\">Cache slot status (last used counter,\r\n	dirty,...)</p>\r\n</ul>\r\n<p class=\"western\">Finding an unused cache entry is a simple\r\noperation. We just iterate through the cache entries searching for\r\none that is not assigned. If all cache entries are busy then a cache\r\npush-out is performed to free up a cahce entry.</p>\r\n<p class=\"western\">Whenever a cache entry is accessed (read or\r\nwritten) the last-use counter is is set to an incrementing number.\r\nThis counter value is used to drive the least-recently-used (LRU)\r\nalgorithm.</p>\r\n<p class=\"western\">Cache entries which have been modified and not yet\r\nwritten back to flash are marked with a dirty flag. This is tells us\r\nwhether we need to write out the data during a flush or push-out.</p>\r\n<p class=\"western\">A push-out happens whenever the cache is full and\r\nwe need to push an entry out of the cache to make space to load a new\r\nentry. Yaffs uses the LRU algorithm to select the LRU cache entry,\r\nwrite it out if needed and then assign that for use.</p>\r\n<p class=\"western\">Whenever a file is flushed (file flush or close),\r\nthe file\'s dirty entries are written out. At certain times (eg.\r\nbefore an unmount or at sync()) the entire cache is flushed.</p>\r\n<p class=\"western\">This caching policy is gives a useful performance\r\nimprovement with very simple algorithms (ie good bang-for-bucks).</p>\r\n<p class=\"western\">Apart from its normal caching function, the short\r\nop cache also does much of the heavy lifting for inband tags support\r\nsince all the inband tags accesses are not chunk aligned and must\r\ntypically be re-aligned. The cache  makes this easy.</p>\r\n<h2 class=\"western\">13.3 Scanning</h2>\r\n<p class=\"western\">Scanning is the process whereby file system state\r\nis rebuilt from scratch. This happens on mounting a Yaffs partition\r\nif no checkpoint data is available or if the mounting was told to\r\nignore the checkpoint data.</p>\r\n<p class=\"western\">Scanning involves reading the tags from all the\r\nactive chunks in the system so can take quite a while, but probably\r\nless time than you\'d expect.</p>\r\n<p class=\"western\">The scanning process is different for Yaffs1 vs\r\nYaffs2 because of the differences mentioned before.</p>\r\n<h3 class=\"western\">13.3.1 Yaffs1 scanning</h3>\r\n<p class=\"western\">Yaffs1 scanning is rather straight forward because\r\nYaffs1 uses deletion markers.</p>\r\n<p class=\"western\">All we really need to do is read the tags off all\r\nthe chunks in the partition and determine if the chunk is active.\r\nOrder is not important and blocks could be read in any order. If the\r\ndeletion marker has not been set then it is active and we need to add\r\nthe chunk to the file system state as follows:</p>\r\n<p class=\"western\">If the chunk is a data chunk (chunk_id &gt; 0)\r\nthen the chunk must be added to the relevant file\'s tnode tree. If\r\nthe object does not exist, then we create it in lost+found, although\r\nit has no name and other file details yet.</p>\r\n<p class=\"western\">If the chunk is an object header (chunk_id == 0)\r\nthen the object must be created (or it might already exist in lost +\r\nfound and we need to fix up its details and slot it into the correct\r\npart of the directory tree.</p>\r\n<p class=\"western\">If at any time during scanning we find that we are\r\nreading a second chunk with the same obj_id:chunk_id as a previously\r\nencountered chunk then the 2-bit serial number is used to resolve the\r\ndispute.</p>\r\n<p class=\"western\">Once the scanning is complete we still need to fix\r\nup a few things: \r\n</p>\r\n<p class=\"western\">Hard links must be connected up properly (it is\r\nmore efficient to defer this until after the scanning has completed).</p>\r\n<p class=\"western\">Also, objects which were marked as unlinked must\r\nbe deleted since there are no longer handles open to these objects.</p>\r\n<h3 class=\"western\">13.3.2 Yaffs2 scanning</h3>\r\n<p class=\"western\">Yaffs2 has no deletion markers which makes the\r\nscanning significantly more complex.</p>\r\n<p class=\"western\">The first thing that needs to be done is to\r\npre-scan the blocks to determine the sequence number for the blocks.\r\nThe list of blocks and sequence numbers is then sorted to make a\r\nchronologically ordered list.</p>\r\n<p class=\"western\">Yaffs then scans <i><b>backwards</b></i> through\r\nthese blocks (ie in reverse chronological order). Thus, the first\r\nencountered  obj_id:chunk_id pair is the current one and subsequent\r\nchunks with those tags are out of date.</p>\r\n<p class=\"western\" style=\"margin-left: 1.25cm\">We read the tags for\r\neach chunk in each block. \r\n</p>\r\n<p class=\"western\" style=\"margin-left: 1.25cm\">If it is a data chunk\r\n( ie. chunk_id &gt; 0) then:</p>\r\n<ul>\r\n	<li/>\r\n<p class=\"western\">If a chunk with the same obj_id:chunk_id\r\n	has already been found then this is not the current chunk. Delete\r\n	this one.</p>\r\n	<li/>\r\n<p class=\"western\">Else if the object is marked as deleted, or\r\n	corrupted, then delete it.</p>\r\n	<li/>\r\n<p class=\"western\">Else if the object does not yet exist then\r\n	this chunk was written since the last object header write for this\r\n	object so this chunk must be the last written chunk in the file and\r\n	must have happened just before an unclean shutdown with the file\r\n	still open. We can create the file and use the chunk_id and nbytes\r\n	to set the file extents.</p>\r\n	<li/>\r\n<p class=\"western\">Else if the object does exist and the chunk\r\n	lies beyond the object\'s file scan size (extents) then it is a\r\n	truncated chunk and can be deleted.</p>\r\n	<li/>\r\n<p class=\"western\">Else it is placed into the file\'s tnode\r\n	tree.</p>\r\n</ul>\r\n<p class=\"western\" style=\"margin-left: 1.25cm\">If it is an object\r\nheader (ie. chunk_id == 0) then:</p>\r\n<ul>\r\n	<li/>\r\n<p class=\"western\">If the object is in the deleted directory\r\n	then mark the object as deleted and set the object\'s shrink size to\r\n	zero.</p>\r\n	<li/>\r\n<p class=\"western\">Else if an object header has not yet been\r\n	found for this object, then this is the most current object header\r\n	and holds the most current name etc.  If no data chunks have yet\r\n	been found for this chunk then the size in the object header is also\r\n	the file extents. The file size is used to set the file scan size\r\n	since at the time it was written the file did not extend past that\r\n	point and we can safely ignore further data chunks for that file\r\n	that extend past that point.</p>\r\n	<li/>\r\n<p class=\"western\">Else just use the file size as the scan\r\n	size if it is smaller than the current file scan size.</p>\r\n	<li/>\r\n<p class=\"western\">Else this an obsolete object header. It is\r\n	deleted.</p>\r\n</ul>\r\n<p class=\"western\">A bit more explanation is probably needed to\r\ndescribe the file scan size. The whole purpose of this is to\r\ndetermine data chunks that should be ignored due to the file being\r\ntruncated.</p>\r\n<h2 class=\"western\">13.4 Checkpoint</h2>\r\n<p class=\"western\">Mount scanning takes quite a lot of time and slows\r\nmounting, though perhaps by less than you\'d think. Checkpointing is a\r\nmechanism to speed the mounting by taking a snapshot of the Yaffs\r\nruntime state at unmount or sync() and then reconstituting the\r\nruntime state on re-mounting. The speed up is dramatic.</p>\r\n<p class=\"western\">The actual checkpoint mechanism is quite simple. A\r\n“stream” of data is written to a set of blocks which are marked\r\nas holding checkpoint data and the important runtime state is written\r\nto the stream.</p>\r\n<p class=\"western\">Not all state needs to be saved, only the state\r\nneeded to reconstitute the structure of the runtime data. For\r\nexample, file metadata need not be saved since it is very easy to\r\nload that through lazy-loading.</p>\r\n<p class=\"western\">The checkpoint stores data in the following order:</p>\r\n<ul>\r\n	<li/>\r\n<p class=\"western\"><font face=\"Liberation Serif, serif\">Start\r\n	marker, including checkpoint format id.</font></p>\r\n	<li/>\r\n<p class=\"western\"><font face=\"Liberation Serif, serif\">yaffs_dev\r\n	information</font></p>\r\n	<li/>\r\n<p class=\"western\"><font face=\"Liberation Serif, serif\">Block\r\n	information</font></p>\r\n	<li/>\r\n<p class=\"western\"><font face=\"Liberation Serif, serif\">Chunk\r\n	flags</font></p>\r\n	<li/>\r\n<p class=\"western\"><font face=\"Liberation Serif, serif\">Objects,\r\n	including file structure</font></p>\r\n	<li/>\r\n<p class=\"western\"><font face=\"Liberation Serif, serif\">End\r\n	marker</font></p>\r\n	<li/>\r\n<p class=\"western\"><font face=\"Liberation Serif, serif\">Checksum</font></p>\r\n</ul>\r\n<p class=\"western\">The checkpoint validity is ensured by the\r\nfollowing mechanisms:</p>\r\n<ul>\r\n	<li/>\r\n<p class=\"western\"><font face=\"Liberation Serif, serif\">The\r\n	data is stored using whatever ECC mechanisms are in place.</font></p>\r\n	<li/>\r\n<p class=\"western\"><font face=\"Liberation Serif, serif\">The\r\n	start marker includes a checkpoint version so that an obsolete\r\n	checkpoint will not be read if the checkpoint code changes.</font></p>\r\n	<li/>\r\n<p class=\"western\"><font face=\"Liberation Serif, serif\">Data\r\n	is written to the stream as structured records, each with a type and\r\n	size.</font></p>\r\n	<li/>\r\n<p class=\"western\"><font face=\"Liberation Serif, serif\">The\r\n	end marker must be read when expected.</font></p>\r\n	<li/>\r\n<p class=\"western\"><font face=\"Liberation Serif, serif\">Two\r\n	checksums are maintained across the whole checkpoint data set.</font></p>\r\n</ul>\r\n<p class=\"western\">If any checks fail, the checkpoint is ignored and\r\nthe state is re-scanned.</p>\r\n<p class=\"western\">The astute reader might notice that block state\r\nchanges as we\'re writing checkpoint blocks, so how do we manage to\r\nre-constitute the block states correctly? This is achieved by the\r\nfollowing:</p>\r\n<ul>\r\n	<li/>\r\n<p class=\"western\"><font face=\"Liberation Serif, serif\">As we\r\n	write the checkpoint, the checkpoint block allocation selects EMPTY\r\n	blocks. We don\'t change the state as we\'re writing the checkpoint so\r\n	their state is written to the checkpoint as EMPTY or CHECKPOINT, it\r\n	does not really matter which.</font></p>\r\n	<li/>\r\n<p class=\"western\"><font face=\"Liberation Serif, serif\">After\r\n	reading the checkpoint, we know which blocks have been used to store\r\n	checkpoint data. We update those blocks to reflect the CHECKPOINT\r\n	state.</font></p>\r\n</ul>\r\n<p class=\"western\">A checkpoint is invalidated by any modifications\r\n(writes, erases,...) thus any modification path also checks to see if\r\nthere is a checkpoint and erases it.</p>\r\n<p class=\"western\">The regular Yaffs block allocator and garbage\r\ncollection logic also needs to be aware of the approximate size of\r\nthe checkpoint so that these can ensure enough spare space is\r\nreserved to store a checkpoint. There is a calculation that updates\r\nthe value whenever the number of objects etc changes.</p>\r\n<h2 class=\"western\">13.5 Extended tags and packed tags</h2>\r\n<p class=\"western\">Extended tags is an abstraction of a way to store\r\nmore information in the tags, allowing for faster scan times. Packed\r\nTags is a physical implementation of the storage of extended tags.</p>\r\n<p class=\"western\">When we\'re scanning we really only need to build\r\nup the structure of the file system. In other words, rebuild the\r\ndirectory relationships, tnode trees and such. Much of the detail\r\nsuch as file names, permissions etc can be lazy loaded if and when\r\nneeded.</p>\r\n<p class=\"western\">This required storing extra information, such as\r\nthe parent directory and object type, in the tags of object headers.\r\nBut how do we do this without enlarging the tags size?</p>\r\n<p class=\"western\">Object headers always have a chunk_id of zero and\r\nn_bytes has no meaning because it is not a data chunk. By using a\r\nsingle bit to identify object headers we suddenly open up a whole lot\r\nof space that we can stuff full of useful data. By being clever as to\r\nwhat data we use, we can pack in the important data in most\r\ncircumstances.</p>\r\n<p class=\"western\">Sometimes, for example very large files, the\r\npacking will not work because there are insufficient bits to hold the\r\nfield so we just write regular tags instead. That\'s OK since there\r\ncan only be few such files in the system so the performance reduction\r\nonly impacts very few files and the system level impact is\r\nunnoticeable. A simple, cheap, strategy that gives speed up 99% of\r\nthe time is a very handy one.</p>\r\n<p class=\"western\">Other details are lazy-loaded on demand. This will\r\nhappen when the object is looked up (eg. by a file open or searching\r\nfor the file in the directory).</p>\r\n<h2 class=\"western\">13.6 Block summaries</h2>\r\n<p class=\"western\">Scanning requires that the tags for each chunk are\r\nread so that they can be inspected. Reading the tags from each chunk\r\ncan be time consuming. Thus, block summaries were added in 2011.</p>\r\n<p class=\"western\">Block summaries write all the tags data for chunks\r\nin the block into the last few (typically only one) chunk in a block.\r\nThis allows all the tags for chunks in that block to be read in one\r\nhit. Depending on the system throughput (CPU, RAM and flash speeds),\r\nthis can speed up mount time dramatically.</p>\r\n<p class=\"western\">Note that the block summary does not replace the\r\ntags attached to each chunk. Both are written. Thus, if the whole\r\nblock is not written (and the block summary is thus not written), the\r\nchunk tags can still be read and used.</p>\r\n<p class=\"western\">If a block summary is not available for a block,\r\nthen the old mechanism is still used to scan the tags on each chunk.</p>\r\n<h2 class=\"western\">13.7 Inband tags</h2>\r\n<p class=\"western\">Thus far we have considered chunks where there are\r\nsufficient unallocated bytes in the spare (or out of band) area to\r\nstore the tags. \r\n</p>\r\n<p class=\"western\">But what happens if we don\'t have enough space in\r\nthe spare area to store the tags? Inband tags to the rescue! \r\n</p>\r\n<p class=\"western\">With inband tags we store the tags in the flash\r\ndata area alongside the data. This gives us far more flexibility in\r\nthe types of storage that Yaffs can support.</p>\r\n<p class=\"western\">There are three major penalties with inband tags:</p>\r\n<ul>\r\n	<li/>\r\n<p class=\"western\">Due to the loss of chunk alignment, all\r\n	transactions must pass through the short op cache. This costs an\r\n	extra memcpy().</p>\r\n	<li/>\r\n<p class=\"western\"></p>\r\n	<li/>\r\n<p class=\"western\">Reading tags during scanning etc can\r\n	involve reading the whole page, making this slower. The impact is\r\n	minimised by using checkpointing or block summaries.</p>\r\n</ul>\r\n<p class=\"western\">Thus, it is better, performance wise, to only use\r\ninband tags when regular tags will not work.</p>\r\n<h2 class=\"western\">13.8 Soft deletion</h2>\r\n<p class=\"western\">Soft deletion is a mechanism that was added to\r\nspeed up file deletion in Yaffs1 mode.</p>\r\n<p class=\"western\">Looking back to the description of how files are\r\nstored in Yaffs1, you can see that deleting a file involves writing\r\nthe deletion marker of every data chunk in the file. This can take\r\nquite some time for large files.</p>\r\n<p class=\"western\">The soft deletion mechanism was added to avoid\r\nwriting all those deletion markers. Instead of writing the deletion\r\nmarkers, soft deletion instead tracks the number of chunks in each\r\nblock that belong to deleted files and leaves the clean up to the\r\ngarbage collector.</p>\r\n<p class=\"western\">When the garbage collector looks at a block it can\r\nsee what current chunks (ie chunks not yet deleted) belong to deleted\r\nfiles and does not copy those, thus effectively deleting the chunk.\r\nOnce all the chunks associated with a deleted file have cleaned up by\r\nthe garbage collector the file header object can also be deleted.</p>\r\n<p class=\"western\">Yaffs2 mode does not write deletion markers and\r\nthus does not use soft deletion.</p>\r\n','This document gives a reasonable explanation of most of the core mechanisms that make Yaffs work. As of the time of writing this, the Yaffs2 code base includes approximately 19,000 lines of code making a very detailed discussion impractical. This document should serve as a first port of call for understanding Yaffs. Further detailed questions and discussions are welcomed on the Yaffs discussion list.','raw_html'),('what_is_special_about_yaffs',0,414,415,'und',0,'<p>If you want to use Yaffs on an Open Source project, then go ahead and <a href=\"/downloads\">download</a> the GNU General Public Licence v.2 now. You can get it straight away from the link on the right of the page.</p>\r\n\r\n<p>Yaffs is also available under a Commercial Licence&nbsp;for projects that don\'t want to disclose their source code.&nbsp; This Licence does not have the obligations of GPL, but is perpetual, world-wide, non-exclusive and carries no continuing royalty.</p>\r\n\r\n<p>You can use the Open Source code to investigate and evaluate Yaffs, then before shipping your product to anyone outside of your organisation you buy a licence from Aleph One which does not have the GNU GPL obligation to release your Source Code.&nbsp; Contact&nbsp; sales@aleph1.co.uk&nbsp; for more information or have a look at our <a href=\"/downloads\">licensing information</a>.</p>\r\n','If you want to use Yaffs on an Open Source project, then go ahead and <a href=\"/downloads\">download</a> the GNU General Public Licence, version 2 form now. It is also available under a commercial Licence without the obligations entailed in the GNU GPL version.','basic_html'),('what_is_special_about_yaffs',0,415,416,'und',0,'<p>When shopping for a software component, it\'s always useful to be able to try it out before buying.</p>\r\n\r\n<p>For your proprietary projects, the GPL version of Yaffs lets you do just that - download it, examine the code and test it out. Check out our documentation and videos.</p>\r\n\r\n<p>It\'s perfectly acceptable and safe to use the GNU GPL code inside your company, providing you don\'t ship a binary to anyone beyond it.&nbsp;That\'s when code disclosure and licensing provisions of the GNU GPL kick in.&nbsp;So before you do that, you\'ll want to talk to us about acquiring a paid Licence.</p>\r\n','If you think that Yaffs might be what you need, you can test it without buying a licence.','basic_html'),('what_is_special_about_yaffs',0,416,417,'und',0,'<p>Having started in 2002 Yaffs embodies more than ten years of experience with Flash memory and its specialised needs, coupled with continued growth in the number of people and companies using Yaffs.</p>\r\n\r\n<p>Since its inception numerous features and refinements have been added. The code continues to evolve, growing in value to users whilst retaining backward compatibility. The community of users continues to grow as more and more people and companies opt to use Yaffs, providing a pool of knowledge which is accessible to new users.&nbsp;</p>\r\n\r\n<p>The availability of the GNU General Public Licence version means that there\'s always an exit route for open source projects, and since it\'s open-source, existing commercial projects will at the very least always have the source code and the licence to continue to use it, and likely much more. Plus commercial projects benefit from the open source experience in Yaffs - both with respect to developers and knowledge.&nbsp;</p>\r\n\r\n<p>Yaffs is a safe choice for any project needing a Flash file system: it has well over ten years of history, proven sustainability, a continuously improving codebase, a growing user base, and exit routes, since it&nbsp;will continue to be available regardless of Yaffs.net.</p>\r\n','Yaffs has a long history, coupled with continuing development. There are thousands of developers who have used it, and it\'s deployed in many millions of devices.','basic_html'),('what_is_special_about_yaffs',0,417,418,'und',0,'<p>Yaffs support is available through the Yaffs community - primarily via the mail list - with help coming from our key developers as well as other people who use Yaffs. For those times when you don\'t feel comfortable asking a question in a public forum, perhaps because the project is sensitive, we will normally answer a few questions off-list before we offer you the opportunity of consultancy and direct access to our developers. And of course we are always willing to discuss other forms of support for customers who buy licences.</p>\r\n','Yaffs support is available through the Yaffs community but for those problems that aren\'t suitable for a public forum, we offer consultancy with direct access to our developers.','basic_html'),('what_is_special_about_yaffs',0,418,419,'und',0,'<p>Yaffs provides bad block handling and ECC algorithms to handle deficiencies in NAND flash.</p>\r\n\r\n<p>It is a log-structured file system which makes it very robust to corruptions caused by power failures.</p>\r\n\r\n<p>We spend about 60% of development time on testing Yaffs, and our test harness is available for download so you can check the testing and perform some yourself.</p>\r\n\r\n<p>We\'ve performed hundreds of thousands of tests to make sure that Yaffs is as safe as we can make it, even in the even of a power failure during a firmware update.</p>\r\n\r\n<p>You can find full details of the Yaffs testing regime in our paper <a href=\"http://www.yaffs.net/documents/yaffs-robustness-and-testing\">http://www.yaffs.net/documents/yaffs-robustness-and-testing</a>&nbsp; including all the details on the power-fail stress tests, the Yaffs Direct API tests for commercial RTOSs, Linux testing, and fuzz testing where we deliberately corrupt Yaffs file systems to check that Yaffs can still mount.</p>\r\n','Yaffs is designed for data safety and rigorously tested to ensure it does the best possible to keep users\' data safe. It\'s been crash-tested it hundreds of thousands of times ...','basic_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,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,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'),('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,606,'und',0,'	<p class=\"western\" align=\"justify\">This document describes the Yaffs\r\n	Direct Interface (YDI),  which allows Yaffs to be simply integrated\r\n	with embedded systems, with or without an RTOS.</p>\r\n\r\n<p class=\"western\" style=\"page-break-before: always\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<h1 class=\"western\" style=\"page-break-before: always\">1 Background</h1>\r\n<p class=\"western\">The purpose of this document is to describe the\r\ninterfacing of the Yaffs Direct Interface (YDI) as well as to provide\r\nsufficient information to allow a preliminary evaluation of Yaffs.\r\nThis document tries to focus on the issues important to the system\r\nintegrator without getting too detailed about how Yaffs works. Other\r\ndocuments provide an in-depth discussion of how Yaffs works.</p>\r\n<h1 class=\"western\">2 Licensing</h1>\r\n<p class=\"western\">Yaffs was originally released for Linux under the\r\nGNU Public License (GPL). Various embedded developers soon identified\r\nthat Yaffs would be ideal for their applications, but were not able\r\nto use GPL based code in their systems. Aleph One <span style=\"font-style: normal\"><span style=\"font-weight: normal\">has</span></span>\r\nalternative licensing arrangements to support such applications.</p>\r\n<h1 class=\"western\">3 What are Yaffs and Yaffs Direct Interface?</h1>\r\n<p class=\"western\">Yaffs stands for <i>Yet Another Flash File System</i>.\r\nYaffs was the first file system designed, from the ground up, for\r\nNAND storage.</p>\r\n<p class=\"western\">In 2002 Aleph One set out to identify file system\r\noptions for using NAND Flash as a file system. Various file systems\r\navailable at the time were evaluated and all were found lacking in\r\none way or another. The need for a suitable NAND storage file system\r\nwas identified and Yaffs was designed to fill that need.</p>\r\n<p class=\"western\">Although Yaffs was originally designed for NAND\r\nflash, it has been used successfully with NOR flash systems and even\r\nas a RAM file system. This allows high reliability file systems to be\r\nconstructed using NOR flash, with a future migration path <span style=\"font-weight: normal\">to\r\nNAND</span> flash for higher density and performance.</p>\r\n<p class=\"western\">Yaffs was originally designed for use with the\r\nLinux operating system, but was designed in a very modular way. The\r\noperating-system-specific code was kept separate from the main Yaffs\r\nfile system code. This allows Yaffs to be ported quite cleanly to\r\nother operating systems through operating system personality modules.\r\nOne such personality module is the Yaffs Direct Interface (YDI) which\r\nallows Yaffs to be simply integrated with embedded systems, with or\r\nwithout an RTOS. \r\n</p>\r\n<p class=\"western\">Yaffs has been used for many products using\r\nvarious operating systems including Windows CE and various RTOSs,\r\nincluding <span style=\"font-weight: normal\">ThreadX, vXworks, pSOS to\r\nname just a few.</span></p>\r\n<p class=\"western\">Note that there is a native port of Yaffs to eCOS\r\nthat does not use YDI. This is supported and distributed by\r\neCocCentric.(http://www.ecoscentric.com/).</p>\r\n<p class=\"western\">Yaffs2, a more recent release of Yaffs, supports a\r\nwider range of NAND flash components including 2k page devices and\r\ndevices with multi-level cells (MLC), and produces equivalent or\r\nbetter performance. It include Yaffs1 compatibility code so Yaffs1\r\nimages still work and migration is quite simple. Yaffs1 or Yaffs2\r\nmode of operation are simply selected by a run-time parameter.</p>\r\n<p class=\"western\">As well as providing a NAND file system, YDI also\r\nprovides a RAM emulation layer to allow Yaffs to operate as a RAM\r\nfile system too. While the RAM emulation is perhaps not as efficient\r\nas a dedicated RAM file system, this does allow one well proven file\r\nsystem to use both RAM and flash.</p>\r\n<h1 class=\"western\">4 Why use Yaffs?</h1>\r\n<p class=\"western\">Yaffs is the first, and perhaps only, file system\r\ndesigned specifically for NAND flash. This means that Yaffs has been\r\ndesigned to work around the various limitations and quirks of NAND\r\nflash, as well as exploit the various features of NAND to achieve an\r\neffective file system.</p>\r\n<p class=\"western\">Some features to consider:</p>\r\n<ul>\r\n	<li/>\r\n<p class=\"western\">Yaffs has been well proven and has been\r\n	used to ship in <span style=\"font-weight: normal\">large volumes in\r\n	several products using many different operating systems, compilers\r\n	and processors.</span></p>\r\n	<li/>\r\n<p class=\"western\">Yaffs is written in portable C and is\r\n	endian neutral.</p>\r\n	<li/>\r\n<p class=\"western\">Yaffs provides <span style=\"font-weight: normal\">bad</span><b>\r\n	</b><span style=\"font-weight: normal\">block</span> handling and ECC\r\n	algorithms to handle deficiencies in NAND flash.</p>\r\n	<li/>\r\n<p class=\"western\">Yaffs is a log-structured file system which\r\n	makes it very robust to corruptions caused by power failures etc.</p>\r\n	<li/>\r\n<p class=\"western\">Yaffs has highly optimised and predictable\r\n	garbage collection strategies. This makes it high performance and\r\n	very deterministic when compared with similar file systems.</p>\r\n	<li/>\r\n<p class=\"western\">Yaffs has a lower memory footprint than\r\n	most other log-structured flash file systems.</p>\r\n	<li/>\r\n<p class=\"western\">Yaffs provides a wide range of POSIX-style\r\n	file system support including directories, symbolic and hard links\r\n	etc. through standard file system interface calls.</p>\r\n	<li/>\r\n<p class=\"western\"><span style=\"font-weight: normal\">Yaffs is\r\n	h</span>ighly configurable to work with various flash geometries,\r\n	various ECC options, caching options etc.</p>\r\n	<li/>\r\n<p class=\"western\">Yaffs Direct Interface is simple to\r\n	integrate in a system – only a few interface functions are\r\n	required.</p>\r\n	<li/>\r\n<p class=\"western\">Yaffs can be used with a wide range of\r\n	memory technologies.</p>\r\n</ul>\r\n<h1 class=\"western\">5 Source Code and Yaffs Resources \r\n</h1>\r\n<p class=\"western\"><font face=\"Liberation Serif, serif\">Please note\r\nthe licensing terms that apply to using the Yaffs code.</font></p>\r\n<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\"><span style=\"font-style: normal\"><span style=\"font-weight: normal\">\r\nserves as the hub for all Yaffs information.</span></span></font></p>\r\n<p class=\"western\"><font face=\"Liberation Serif, serif\">This document\r\nrefers to the Yaffs source code extensively.<span style=\"font-style: normal\"><span style=\"font-weight: normal\">\r\nand is available via the download link on this site.</span></span></font></p>\r\n<p class=\"western\"><font face=\"Liberation Serif, serif\">There are\r\nvarious other documents and a Yaffs mailing list for Yaffs\r\ndiscussions.</font></p>\r\n<p class=\"western\"><font face=\"Liberation Serif, serif\">Consulting\r\nservices are also available.</font></p>\r\n<h1 class=\"western\">6 System Requirements</h1>\r\n<p class=\"western\">Determining minimum system requirements is often\r\nquite difficult. The following are presented as a guideline only.\r\nContact Aleph One for more detailed analysis if required.</p>\r\n<ul>\r\n	<li/>\r\n<p class=\"western\">Yaffs is endian-neutral and works fine with\r\n	little-endian and big-endian processors.</p>\r\n	<li/>\r\n<p class=\"western\">Yaffs code has been used successfully with\r\n	many different 32-bit and 64-bit CPUs including MIPS, 68000, ARM,\r\n	ColdFire, PowerPC and x86 variants. Yaffs has even been used with\r\n	various DSP architectures. Yaffs should work with 16-bit CPUs too,\r\n	but this is generally untested and might need some tuning, depending\r\n	on compiler options.</p>\r\n	<li/>\r\n<p class=\"western\">Because Yaffs is log structured, RAM is\r\n	required to build up runtime data structures for acceptable\r\n	performance. As a rule of thumb, budget approximately 2 bytes per\r\n	<i>chunk</i> of NAND flash, where a <i>chunk</i> is typically one\r\n	page of NAND. For NAND with 512byte pages, budget approximately\r\n	4kbytes of RAM per 1Mbyte of NAND. For 2kbyte page devices budget\r\n	approximately 1kbyte per 1Mbyte of NAND.</p>\r\n</ul>\r\n<h1 class=\"western\">7 How to integrate Yaffs with an RTOS/Embedded\r\nsystem</h1>\r\n<p class=\"western\" align=\"justify\">Yaffs Direct Interface (YDI) wraps\r\nYaffs in a way that is simple to integrate. You need to provide a few\r\nfunctions for Yaffs to use to talk to your hardware and RTOS. Yaffs\r\nprovides a set of POSIX-compliant functions for applications to use\r\nto talk to it.</p>\r\n<p class=\"western\">In addition to the Yaffs core file system, the YDI\r\nhas three parts which are each explained in more detail in further\r\nsections:</p>\r\n<ul>\r\n	<li/>\r\n<p class=\"western\"><b>POSIX Application Interface</b>: This is\r\n	the POSIX-like interface that the application code uses to access\r\n	the Yaffs file system. (<font face=\"Times New Roman\"><i>open, close,\r\n	read, write, </i></font>etc) \r\n	</p>\r\n	<li/>\r\n<p class=\"western\"><b>RTOS Integration Interface</b>: These\r\n	are the functions that must be provided for Yaffs to access the RTOS\r\n	system resources. (<font face=\"Times New Roman\"><i>initialise, lock,\r\n	unlock, get time, </i></font><font face=\"Times New Roman\"><i>memory\r\n	allocation,</i></font><font face=\"Times New Roman\"><i> set error,\r\n	</i></font><font face=\"Times New Roman\"><i>etc</i></font>). Note\r\n	that although we use the term RTOS, the same can be done with other\r\n	OSs or even with no RTOS at all in a bare-metal system.</p>\r\n	<li/>\r\n<p class=\"western\"><img src=\"data:image/png;base64,[encoded data, 27864 characters]\" name=\"Object1\" align=\"left\" width=\"485\" height=\"530\"/>\r\n<b>Flash\r\n	Device </b><b>Interface</b>: This interface support is where the\r\n	flash device and appropriate device drivers are installed to provide\r\n	an access path from Yaffs to the flash device(s). Multiple different\r\n	devices and device types can be supported simultaneously.</p>\r\n</ul>\r\n<h2 class=\"western\">7.1 Source Files</h2>\r\n<p class=\"western\">The following source files contain the core file\r\nsystem:</p>\r\n<table width=\"100%\" cellpadding=\"4\" cellspacing=\"0\">\r\n	<col width=\"71*\">\r\n	<col width=\"185*\">\r\n	<tr valign=\"top\">\r\n		<td width=\"28%\" style=\"border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0.1cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\">yaffs_allocator.c</p>\r\n		</td>\r\n		<td width=\"72%\" style=\"border: 1px solid #000000; padding: 0.1cm\">\r\n			<p class=\"western\">Allocates Yaffs object and tnode structures.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"28%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\"><br/>\r\n\r\n			</p>\r\n		</td>\r\n		<td width=\"72%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\"><br/>\r\n\r\n			</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"28%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\">yaffs_bitmap.c</p>\r\n		</td>\r\n		<td width=\"72%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\">Block and chunk bitmap handling code.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"28%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\">yaffs_checkpointrw.c</p>\r\n		</td>\r\n		<td width=\"72%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\">Streamer for writing checkpoint data</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"28%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\">yaffs_ecc.c</p>\r\n		</td>\r\n		<td width=\"72%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\">1-bit Hamming ECC code</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"28%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\"><br/>\r\n\r\n			</p>\r\n		</td>\r\n		<td width=\"72%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\"><br/>\r\n\r\n			</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"28%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\">yaffs_guts.c</p>\r\n		</td>\r\n		<td width=\"72%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\">The major Yaffs algorithms.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"28%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\">yaffs_nameval.c</p>\r\n		</td>\r\n		<td width=\"72%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\">Name/value code for handling extended\r\n			attributes (xattr).</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"28%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\">yaffs_nand.c</p>\r\n		</td>\r\n		<td width=\"72%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\">Flash interfacing abstraction.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"28%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\">yaffs_packedtags1.c<br/>\r\nyaffs_packedtags2.c</p>\r\n		</td>\r\n		<td width=\"72%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\">Tags packing code</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"28%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\">yaffs_summary.c</p>\r\n		</td>\r\n		<td width=\"72%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\">Code for handling block summaries.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"28%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\">yaffs_tagscompat.c</p>\r\n		</td>\r\n		<td width=\"72%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\">Tags compatibility code to support Yaffs1 mode.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"28%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\">yaffs_tagsmarshall.c</p>\r\n		</td>\r\n		<td width=\"72%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\">Tags marshalling code.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"28%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\">yaffs_verify.c</p>\r\n		</td>\r\n		<td width=\"72%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\">Test verification code.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"28%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\">yaffs_yaffs1.c</p>\r\n		</td>\r\n		<td width=\"72%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\">Yaffs1-mode specific code.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"28%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\">yaffs_yaffs2.c</p>\r\n		</td>\r\n		<td width=\"72%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\">Yaffs2-mode specific code.</p>\r\n		</td>\r\n	</tr>\r\n</table>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\">The Yaffs direct interface is in yaffsfs.c, with\r\nthe interface functions and structures defined in yaffsfd.h.</p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<table width=\"100%\" cellpadding=\"4\" cellspacing=\"0\" style=\"page-break-inside: avoid\">\r\n	<col width=\"72*\">\r\n	<col width=\"184*\">\r\n	<tr valign=\"top\">\r\n		<td width=\"28%\" style=\"border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0.1cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\">yaffs_attribs.c</p>\r\n		</td>\r\n		<td width=\"72%\" style=\"border: 1px solid #000000; padding: 0.1cm\">\r\n			<p class=\"western\">Attribute handling.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"28%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\">yaffs_error.c</p>\r\n		</td>\r\n		<td width=\"72%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\">Error reporting code.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"28%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\" align=\"justify\">yaffsfs.c</p>\r\n		</td>\r\n		<td width=\"72%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\" align=\"justify\">Yaffs Direct Interface wrapper\r\n			code.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"28%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\" align=\"justify\">yaffs_hweight.c</p>\r\n		</td>\r\n		<td width=\"72%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\" align=\"justify\">Counts the number of hot bits\r\n			in a byte, word etc.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"28%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\">yaffs_qsort.c</p>\r\n		</td>\r\n		<td width=\"72%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\">Qsort used during Yaffs2 scanning</p>\r\n		</td>\r\n	</tr>\r\n</table>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\">Example flash drivers, simulators and\r\nconfigurations used for testing are are in direct/test-framework\r\ndirectory. These include:</p>\r\n<table width=\"100%\" cellpadding=\"4\" cellspacing=\"0\" style=\"page-break-inside: avoid\">\r\n	<col width=\"72*\">\r\n	<col width=\"184*\">\r\n	<tr valign=\"top\">\r\n		<td width=\"28%\" style=\"border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0.1cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\" align=\"justify\">nanddrv.c</p>\r\n		</td>\r\n		<td width=\"72%\" style=\"border: 1px solid #000000; padding: 0.1cm\">\r\n			<p class=\"western\" align=\"justify\">A NAND driver layer that\r\n			performs the commands to access NAND flash in a rudimentary\r\n			manner. This code should work on many styles of CPU with little\r\n			modification.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"28%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\" align=\"justify\">yaffs_nanddrv.c</p>\r\n		</td>\r\n		<td width=\"72%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\" align=\"justify\">A wrapper around the NAND\r\n			driver which plugs it into Yaffs.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"28%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\" align=\"justify\">nandsim.c</p>\r\n		</td>\r\n		<td width=\"72%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\" align=\"justify\">A NAND simulator layer that\r\n			works with a nandstore_xxx backing store. This simulates a NAND\r\n			chip.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"28%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\" align=\"justify\">nandstore_file.c</p>\r\n		</td>\r\n		<td width=\"72%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\" align=\"justify\">A storage backend for a NAND\r\n			simulator that stores the data to file.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"28%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\" align=\"justify\">nandsim_file.c</p>\r\n		</td>\r\n		<td width=\"72%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\" align=\"justify\">A wrapper around nandsim.c and\r\n			nandstore_file.c which makes a NAND simulator  that saves its data\r\n			in a file.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"28%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\" align=\"justify\">yaffs_nandsim_file.c</p>\r\n		</td>\r\n		<td width=\"72%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\" align=\"justify\">A wrapper which creates a nand\r\n			simulator  instance, hooks up the yaffs NAND driver and then adds\r\n			it to yaffs for use.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"28%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\" align=\"justify\">yaffs_nor_drv.c</p>\r\n		</td>\r\n		<td width=\"72%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<ol>\r\n				<p class=\"western\" align=\"justify\">A driver for CFI-style NOR\r\n				flash.</p>\r\n			</ol>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"28%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\" align=\"justify\">yaffs_m18_drv.c</p>\r\n		</td>\r\n		<td width=\"72%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\" align=\"justify\">A driver for Intel M18-style\r\n			NOR flash.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"28%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\" align=\"justify\">yaffs_osglue.c</p>\r\n		</td>\r\n		<td width=\"72%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\" align=\"justify\">An OS glue layer example used\r\n			in the test harness.</p>\r\n		</td>\r\n	</tr>\r\n</table>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\">Example and testing build files:</p>\r\n<table width=\"100%\" cellpadding=\"4\" cellspacing=\"0\">\r\n	<col width=\"71*\">\r\n	<col width=\"185*\">\r\n	<tr valign=\"top\">\r\n		<td width=\"28%\" style=\"border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0.1cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\">dtest.c</p>\r\n		</td>\r\n		<td width=\"72%\" style=\"border: 1px solid #000000; padding: 0.1cm\">\r\n			<p class=\"western\">A test harness. Also has sample code that can\r\n			be used for better understanding of how some function calls work.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"28%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\">yaffscfg2k.c</p>\r\n		</td>\r\n		<td width=\"72%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\">A test configuration.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"28%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\">yaffs_fileem.c<br/>\r\nyaffs_fileem2k.c</p>\r\n		</td>\r\n		<td width=\"72%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\">Nand flash simulation using a file as backing\r\n			store.</p>\r\n		</td>\r\n	</tr>\r\n</table>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\">Further testing files are in direct/tests and\r\ndirect/python.</p>\r\n<h2 class=\"western\" style=\"page-break-before: always\">7.2 Integrating\r\nthe POSIX Application Interface</h2>\r\n<p class=\"western\">The application interface is defined in yaffsfs.h.\r\nThese provide a POSIX file system interface. For the most part, this\r\ninterface consists of the standard clib function names prefixed with\r\n<code class=\"western\">yaffs_</code>. For example, <code class=\"western\">yaffs_open(),\r\nyaffs_close()</code> etc.</p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\">There is a lot of flexibility in how these\r\nfunctions are used and the system integrator needs to determine the\r\nbest strategy for the system.</p>\r\n<p class=\"western\">These functions can be used directly, with the\r\ncode written using these names. For example</p>\r\n<p class=\"code-western\"><code class=\"western\">int main(...)<br/>\r\n{<br/>\r\n\r\n  // initialisation<br/>\r\n    f = yaffs_open(...);<br/>\r\n   \r\nyaffs_read(f,...);<br/>\r\n    yaffs_close(f);<br/>\r\n}</code></p>\r\n<p class=\"western\">The <font face=\"Times New Roman\">yaffs</font>\r\nfunctions can also be wrapped in some way to allow existing code to\r\nuse yaffs without modification. For example:</p>\r\n<p class=\"western\" align=\"left\" style=\"margin-bottom: 0cm; orphans: 0; widows: 0; page-break-before: auto; page-break-after: avoid\">\r\n<br/>\r\n\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\">#define open(path,\r\noflag, mode)  yaffs_open(path, oflag, mode)<br/>\r\n..<br/>\r\n<br/>\r\nint\r\nmain(...)<br/>\r\n{<br/>\r\n   // initialisation<br/>\r\n    f = open(...);<br/>\r\n\r\n   read(f,...);<br/>\r\n    close(f);<br/>\r\n}</code><br/>\r\n<br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\" align=\"left\" style=\"margin-bottom: 0cm; orphans: 0; widows: 0; page-break-before: auto\">\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\">A more complex approach that can be used if more\r\nthan one file-system is used is to provide redirection functions. For\r\nexample:</p>\r\n<p class=\"western\" align=\"left\" style=\"margin-bottom: 0cm; orphans: 0; widows: 0; page-break-before: auto; page-break-after: avoid\">\r\n<br/>\r\n\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\">int open(const char\r\n*path,...)<br/>\r\n{<br/>\r\n    // Determine which file system is being\r\nused<br/>\r\n    </code><code class=\"western\">i</code><code class=\"western\">f(it_is_a_yaffs_path(path))<br/>\r\n\r\n       return yaffs_open(...);<br/>\r\n    else {<br/>\r\n        // Do\r\nsomething else<br/>\r\n    }<br/>\r\n}</code></p>\r\n<p class=\"western\" align=\"left\" style=\"margin-left: 1.25cm; margin-bottom: 0cm; page-break-inside: avoid; orphans: 0; widows: 0; page-break-before: auto; page-break-after: auto\">\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\">Some RTOS\'s provide a flexible way to integrate\r\nfile systems in which case YDI can typically use these interfaces to\r\naccess yaffs file systems.</p>\r\n\r\n<h1 class=\"western\" style=\"page-break-before: always\">8 RTOS\r\nIntegration Interface</h1>\r\n<p class=\"western\">Before Yaffs can be used, it needs to be\r\nintegrated with the system and configured so that the correct actions\r\nare performed.</p>\r\n<p class=\"western\">To do this, you need to modify the configuration\r\nfile. An example configuration file is presented in <font face=\"Bitstream Vera Sans\"><font face=\"Times New Roman\">yaffscfg.c\r\nand yaffscfg2k.c.</font></font></p>\r\n<p class=\"western\">This is a relatively straight forward process and\r\ndefines the RTOS access functions.</p>\r\n<p class=\"western\">The RTOS access functions are:</p>\r\n<ul>\r\n	<li/>\r\n<p class=\"western\"><code class=\"western\">void\r\n	yaffsfs_SetError(int err)</code>: Called by Yaffs to set the system\r\n	error.</p>\r\n	<li/>\r\n<p class=\"western\"><code class=\"western\">void\r\n	yaffsfs_Lock(void)</code>: Called by Yaffs to lock Yaffs from\r\n	multi-threaded access.</p>\r\n	<li/>\r\n<p class=\"western\"><code class=\"western\">void\r\n	yaffsfs_Unlock(void)</code>: Called by Yaffs to unlock Yaffs.</p>\r\n	<li/>\r\n<p class=\"western\"><code class=\"western\">u32\r\n	yaffsfs_CurrentTime(void)</code>: Get current time from RTOS.</p>\r\n	<li/>\r\n<p class=\"western\"><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>void\r\n	*yaffsfs_malloc(size_t size)</b></font></font>: Called to allocate\r\n	memory.</p>\r\n	<li/>\r\n<p class=\"western\"><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>void\r\n	yaffsfs_free(void *ptr)</b></font></font>: Called to free memory.</p>\r\n	<li/>\r\n<p class=\"western\"><code class=\"western\">void\r\n	yaffsfs_</code><code class=\"western\">OS</code><code class=\"western\">Initialisation(void)</code>:\r\n	Called to initialise RTOS context.</p>\r\n	<li/>\r\n<p class=\"western\"><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>void\r\n	yaffs_bug_fn(const char *file_name, int line_no)</b></font></font>:\r\n	Function to report a bug.</p>\r\n	<li/>\r\n<p class=\"western\"><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>int\r\n	yaffsfs_CheckMemRegion(const void *addr, size_t size, int\r\n	writ</b></font></font><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>e_request</b></font></font>)\r\n	: Function to check if accesses to a memory region is valid. This\r\n	function must return zero if the test passes and negative if it\r\n	fails.</p>\r\n</ul>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\">If Yaffs is being used in a multi-threaded\r\nenvironment, then typically <code class=\"western\">yaffs_LocalInitialisation()</code>\r\nwill initialise a suitable RTOS semaphore and <code class=\"western\">yaffs_Lock()</code>\r\nand <code class=\"western\">yaffs_Unlock()</code> will call the\r\nappropriate functions to lock and release the semaphore.</p>\r\n<p class=\"western\"><code class=\"western\">yaffs_CurrentTime()</code>\r\ncan be any time increment of use to the system. If this is not\r\nrequired, then it is fine to just use a function that is hard-wired\r\nto return zero.</p>\r\n<p class=\"western\">Before the application code uses Yaffs, the\r\n<code class=\"western\">yaffs</code><code class=\"western\">fs</code><code class=\"western\">_</code><code class=\"western\">OSInitialisation</code><code class=\"western\">()</code>\r\nfunction must be called.</p>\r\n<p class=\"western\"><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>yaffsfs_CheckMemRegion()</b></font></font><font face=\"Liberation Serif, serif\"><font size=\"3\" style=\"font-size: 12pt\"><span style=\"font-weight: normal\">\r\nis used to check addresses passed to the various yaffs_xxx functions\r\n(yaffs_open(), yaffs_read() etc)). If the function returns -1, then\r\nthe yaffs_xxx function will return -EFAULT rather than attempt to\r\ndereference the address and crash.</span></font></font></p>\r\n<p class=\"western\" style=\"font-weight: normal\"><font face=\"Liberation Serif, serif\"><font size=\"3\" style=\"font-size: 12pt\">An\r\n implementation might do something like:</font></font></p>\r\n<p class=\"western\" style=\"font-weight: normal\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"code-western\"><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>int\r\nyaffsfs_CheckMemRegion(const void addr, size_t size, <br/>\r\n          \r\n       int write_</b></font></font><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>request</b></font></font><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>)\r\n<br/>\r\n  {<br/>\r\n      u32 uaddr</b></font></font><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>b</b></font></font><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>\r\n= (u32) addr;<br/>\r\n      </b></font></font><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>u32\r\nuaddrt = uaddrb + size -1;<br/>\r\n</b></font></font><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b><br/>\r\n\r\n     if( uaddr</b></font></font><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>b</b></font></font><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>\r\n&gt;= stack_bottom &amp;&amp; uaddr</b></font></font><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>b</b></font></font><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>\r\n&lt;= stack_top &amp;&amp;<br/>\r\n          </b></font></font><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>uaddrt\r\n&gt;= stack_bottom &amp;&amp; uaddrt &lt;= stack_top)<br/>\r\n         \r\nreturn 0; /* </b></font></font><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>r/w\r\n</b></font></font><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>access\r\nis OK */<br/>\r\n</b></font></font><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b><br/>\r\n\r\n     if( uaddr</b></font></font><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>b</b></font></font><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>\r\n&gt;= </b></font></font><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>heap</b></font></font><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>_bottom\r\n&amp;&amp; uaddr</b></font></font><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>b</b></font></font><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>\r\n&lt;= </b></font></font><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>heap</b></font></font><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>_top\r\n&amp;&amp;<br/>\r\n          </b></font></font><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>uaddrt\r\n&gt;= heap_bottom &amp;&amp; uaddrt &lt;= heap_top)<br/>\r\n         \r\nreturn 0; /* </b></font></font><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>r/w</b></font></font><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>\r\naccess is OK /<br/>\r\n</b></font></font><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b><br/>\r\n\r\n     if( !</b></font></font><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>write_request\r\n&amp;&amp;<br/>\r\n          </b></font></font><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>uaddr</b></font></font><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>b</b></font></font><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>\r\n&gt;= </b></font></font><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>rom</b></font></font><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>_bottom\r\n&amp;&amp; uaddr</b></font></font><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>b</b></font></font><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>\r\n&lt;= </b></font></font><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>rom</b></font></font><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>_top\r\n&amp;&amp;<br/>\r\n          </b></font></font><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>uaddrt\r\n&gt;= rom_bottom &amp;&amp; uaddrt &lt;= rom_top)<br/>\r\n         \r\nreturn 0; / </b></font></font><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>read\r\n</b></font></font><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>access\r\nis OK /</b></font></font><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b><br/>\r\n<br/>\r\n\r\n     </b></font></font><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>return\r\n-1; /* Bad access */</b></font></font><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b><br/>\r\n\r\n<br/>\r\n}</b></font></font></p>\r\n<p class=\"code-western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<h1 class=\"western\" style=\"page-break-before: always\">9 Yaffs NAND\r\nModel</h1>\r\n<p class=\"western\">Before defining the flash integration interface,\r\nit is important to understand the model and corresponding\r\nnomenclature used throughout Yaffs and its documentation.</p>\r\n<p class=\"western\">Yaffs uses a fairly abstract model for NAND flash.\r\nThis allows a lot of flexibility in the way it can be used.</p>\r\n<p class=\"western\">Yaffs is designed for NAND flash and makes the\r\nfollowing assumptions and definitions:</p>\r\n<ul>\r\n	<li/>\r\n<p class=\"western\">The flash is arranged in <i><b>blocks</b></i>.\r\n	Each block is the same size and comprises an integer number of\r\n	<span style=\"font-style: normal\"><span style=\"font-weight: normal\">chunks</span></span>.\r\n	Each block is treated as a single erasable item. A block contains a\r\n	number of chunks.</p>\r\n	<li/>\r\n<p class=\"western\">A <i><b>chunk</b></i> equates to the\r\n	allocation units of flash. For Yaffs1, each chunk equates to a\r\n	512-byte or larger NAND page (that is, a 512-byte or larger data\r\n	portion and a 16-byte spare area). For Yaffs2, a chunk will\r\n	typically be larger (eg. on 2k page devices, a chunk will typically\r\n	be a single 2k page: 2kbytes of data and 64 bytes of spare). Yaffs2\r\n	is capable of working with smaller chunk sizes by using inband tags.</p>\r\n	<li/>\r\n<p class=\"western\">All accesses (reads and writes) are page\r\n	chunk aligned. Some reads might only read the spare area where the\r\n	tags are kept.</p>\r\n	<li/>\r\n<p class=\"western\">When programming a NAND flash, only the\r\n	zero bits in the pattern being programmed are relevant, and one bits\r\n	are &quot;don\'t care&quot;. For example, if a byte already contains\r\n	the binary pattern b1010, then programming b1001 will result in the\r\n	pattern which is the logical AND of these two patterns ie. b1000.\r\n	This is different to NOR flash which would typically abort the\r\n	attempt to convert a 0 into a 1.</p>\r\n</ul>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\">Yaffs ide<span style=\"font-weight: normal\">ntifies</span>\r\nblocks by their block number and chunks by the chunk Id. A chunk Id\r\nis calculated as:</p>\r\n<p class=\"western\"><code class=\"western\">chunkId = block_id *\r\nchunks_per_block + chunk_offset_in_block</code></p>\r\n<p class=\"western\">Yaffs treats a blank (0xFF filled) block as being\r\nfree or erased. Thus, the equivalent of formatting for a Yaffs\r\npartition is to erase all the blocks that are not bad.</p>\r\n<p class=\"western\">Yaffs2 has a generalised tags interface to provide\r\nbetter flexibility to cater for a wider range of devices with larger\r\npages and stricter programming limitations. Yaffs2 thus handles more\r\nabstract constructs than Yaffs1 and, in older versions of Yaffs, more\r\neffort was required to interface to the NAND.</p>\r\n<p class=\"western\">In newer versions of Yaffs, the tags management\r\nhas been abstracted out of the driver. This makes the driver\r\ninterface far simpler.</p>\r\n<h2 class=\"western\">9.1 Formatting</h2>\r\n<p class=\"western\">Yaffs treats erased blocks as empty. That makes it\r\nreally easy to “format” a device: just erase it.. Note that this\r\nshould be done while the partition is not mounted.</p>\r\n<p class=\"western\">Unmounting will not normally work when the file\r\nsystem is busy (eg. files are open), Some extra non-standard unmount\r\noptions are provided to enable an unmount to be forced. Note that\r\nusing these will break any current handles and you will no longer be\r\nable to use open files.</p>\r\n<p class=\"western\"><code class=\"western\"><font face=\"Liberation Serif, serif\"><font size=\"3\" style=\"font-size: 12pt\"><span style=\"font-weight: normal\">There\r\nis a </span></font></font></code><code class=\"western\"><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>yaffs_format()\r\n</b></font></font></code><code class=\"western\"><font face=\"Liberation Serif, serif\"><font size=\"3\" style=\"font-size: 12pt\"><span style=\"font-weight: normal\">function\r\nthat will take care of the details.</span></font></font></code></p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<h2 class=\"western\">9.2 NAND Model considerations for Yaffs1</h2>\r\n<p class=\"western\">The historical Yaffs1 tags structure was laid out\r\nin accordance with the SmartMedia specification for use with 512-byte\r\npages. There is now much more flexibility in the way things can be\r\nconfigured.</p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\">Yaffs1 is capable of being used with a variety of\r\nmemory layouts so long as the flash supports the ability to overwrite\r\nthe tags area to set the deletion marker to zero.</p>\r\n<p class=\"western\">If the yaffs_dev\'s use_nand_ecc field is not set,\r\nthen yaffs will perform the ECC calculations. If this is set then\r\nyaffs will expect the NAND driver to do any required ECC checks. On\r\ndevices that are not using ECC, for example NOR, set use_nand_ecc=1\r\nand then don\'t do any ECC anyway.</p>\r\n<p class=\"western\">The Yaffs1 flash model expects an area of 16 spare\r\nbytes, some of which are used for tags. The mapping between the spare\r\nbytes and the usage of the bytes is specified in yaffs_packedtags1.c</p>\r\n<p class=\"western\">The Yaffs1 model has been used in many NOR-based\r\nsystems. One particularly instructive example is in yaffs_nor_drv.c\r\nwhich implements a driver for Yaffs1 mode on CFI-style NOR flash.\r\nThis does not use ECC but uses checksumming instead.</p>\r\n<p class=\"western\">The yaffs_dev structure has a yaffs_driver\r\nstructure which holds the function pointers to the driver. For Yaffs1\r\nmode of operations the following are required:</p>\r\n<table width=\"100%\" cellpadding=\"4\" cellspacing=\"0\" style=\"page-break-inside: avoid\">\r\n	<col width=\"77*\">\r\n	<col width=\"179*\">\r\n	<tr valign=\"top\">\r\n		<td width=\"30%\" style=\"border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0.1cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\" align=\"justify\">drv_write_chunk_fn</p>\r\n		</td>\r\n		<td width=\"70%\" style=\"border: 1px solid #000000; padding: 0.1cm\">\r\n			<p class=\"western\" align=\"justify\">Write a data chunk</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"30%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\" align=\"justify\">drv_read_chunk_fn</p>\r\n		</td>\r\n		<td width=\"70%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\" align=\"justify\">Read a data chunk.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"30%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\" align=\"justify\">drv_erase_fn</p>\r\n		</td>\r\n		<td width=\"70%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\" align=\"justify\">Erase a block</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"30%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\" align=\"justify\">drv_initialise_fn</p>\r\n		</td>\r\n		<td width=\"70%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\" align=\"justify\">Initialisation.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"30%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\" align=\"justify\">drv_deinitialise_fn</p>\r\n		</td>\r\n		<td width=\"70%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\" align=\"justify\">De-initialise</p>\r\n		</td>\r\n	</tr>\r\n</table>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\">These functions are described later.</p>\r\n<h2 class=\"western\">9.3 NAND Model for Yaffs2</h2>\r\n<p class=\"western\">The Yaffs2 interface is far more flexible than\r\nYaffs1, but that means a bit more effort must be done in the driver.\r\nIn particular:</p>\r\n<ul>\r\n	<li/>\r\n<p class=\"western\">There is is no standard spare area/ECC\r\n	layout. The driver must handle all the layout of the spare area and\r\n	ECC handling.</p>\r\n	<li/>\r\n<p class=\"western\">There is not a standard implementation for\r\n	bad block markers. Thus, the driver must provide functions for\r\n	checking and marking bad blocks.</p>\r\n</ul>\r\n<p class=\"western\">The yaffs_driver structure for Yaffs2 mode\r\nrequires the following functions:</p>\r\n<p class=\"western\" align=\"left\" style=\"margin-bottom: 0cm; orphans: 0; widows: 0; page-break-before: auto\">\r\n<br/>\r\n\r\n</p>\r\n<table width=\"100%\" cellpadding=\"4\" cellspacing=\"0\" style=\"page-break-inside: avoid\">\r\n	<col width=\"77*\">\r\n	<col width=\"179*\">\r\n	<tr valign=\"top\">\r\n		<td width=\"30%\" style=\"border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0.1cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\" align=\"justify\">drv_write_chunk_fn</p>\r\n		</td>\r\n		<td width=\"70%\" style=\"border: 1px solid #000000; padding: 0.1cm\">\r\n			<p class=\"western\" align=\"justify\">Write a data chunk</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"30%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\" align=\"justify\">drv_read_chunk_fn</p>\r\n		</td>\r\n		<td width=\"70%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\" align=\"justify\">Read a data chunk.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"30%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\" align=\"justify\">drv_erase_fn</p>\r\n		</td>\r\n		<td width=\"70%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\" align=\"justify\">Erase a block</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"30%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\" align=\"justify\">drv_mark_bad_fn</p>\r\n		</td>\r\n		<td width=\"70%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\" align=\"justify\">Mark a block bad</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"30%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\" align=\"justify\">drv_check_bad_fn</p>\r\n		</td>\r\n		<td width=\"70%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\" align=\"justify\">Check bad block status of a\r\n			block.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"30%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\" align=\"justify\">drv_initialise_fn</p>\r\n		</td>\r\n		<td width=\"70%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\" align=\"justify\">Initialisation.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"30%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\" align=\"justify\">drv_deinitialise_fn</p>\r\n		</td>\r\n		<td width=\"70%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\" align=\"justify\">De-initialise</p>\r\n		</td>\r\n	</tr>\r\n</table>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<h2 class=\"western\">9.4 Overview of flash driver function</h2>\r\n<p class=\"western\">The best way to understand how to write these\r\nfunctions is to look at the example drivers.</p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"code-western\">int (*drv_write_chunk_fn) (struct yaffs_dev\r\n*dev, int nand_chunk, \r\n</p>\r\n<p class=\"code-western\">                            const u8 *data,\r\nint data_len, \r\n</p>\r\n<p class=\"code-western\">                            const u8 *oob,\r\nint oob_len)</p>\r\n<p class=\"western\">This function writes the specified chunk data and\r\noob/spare data to flash.</p>\r\n<p class=\"western\">This function should return YAFFS_OK on success or\r\nYAFFS_FAIL on failure.</p>\r\n<p class=\"western\">If this is a Yaffs2 device, or Yaffs1 with\r\nuse_nand_ecc set, then this function must take care of any ECC that\r\nis required.</p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"code-western\">int (*drv_read_chunk_fn) (struct yaffs_dev\r\n*dev, int nand_chunk, \r\n</p>\r\n<p class=\"code-western\">                           u8 *data, int\r\ndata_len, \r\n</p>\r\n<p class=\"code-western\">                           u8 *oob, int\r\noob_len,</p>\r\n<p class=\"code-western\">                           enum\r\nyaffs_ecc_result *ecc_result)</p>\r\n<p class=\"western\">This function reads the specified chunk data and\r\noob/spare data from flash.</p>\r\n<p class=\"western\">This function should return YAFFS_OK on success or\r\nYAFFS_FAIL on failure.</p>\r\n<p class=\"western\">If this is a Yaffs2 device, or Yaffs1 with\r\nuse_nand_ecc set, then this function must take care of any ECC that\r\nis required and set the ecc_result.</p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"code-western\">int (*drv_erase_fn) (struct yaffs_dev *dev,\r\nint block_no) \r\n</p>\r\n<p class=\"western\">This function erases the specified block.</p>\r\n<p class=\"western\">This function should return YAFFS_OK on success or\r\nYAFFS_FAIL on failure.</p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"code-western\">int (*drv_mark_bad_fn) (struct yaffs_dev\r\n*dev, int block_no); \r\n</p>\r\n<p class=\"code-western\">int (*drv_check_bad_fn) (struct yaffs_dev\r\n*dev, int block_no); \r\n</p>\r\n<p class=\"western\">These functions are only required for Yaffs2 mode.\r\nThey mark a block bad or check if it is bad.</p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"code-western\">int (*drv_initialise_fn) (struct yaffs_dev\r\n*dev); \r\n</p>\r\n<p class=\"code-western\">int (*drv_deinitialise_fn) (struct yaffs_dev\r\n*dev); \r\n</p>\r\n<p class=\"western\">These functions provide hooks for initialising or\r\ndeinitialising the flash driver.</p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<h1 class=\"western\" style=\"page-break-before: always\">10 Configuration\r\nand flash driver installation</h1>\r\n<p class=\"western\">For an example of how to do the configuration,\r\nrefer to yaffs_cfg2k.c and one of the drivers such as\r\nyaffs_nand_drv.c</p>\r\n<p class=\"western\">The old mechanism was static and required a table\r\nof devices that was installed at start up.  This mechanism had\r\nshortcomings – in particular it broke modularity and did not allow\r\ndevices to be added dynamically.</p>\r\n<p class=\"western\">Things are different now. As any time, a yaffs_dev\r\nstructure can be configured and then registered with Yaffs by using\r\nthe yaffs_add_device() function.</p>\r\n<p class=\"western\">A yaffs_dev structure has two parts which must be\r\nconfigured before yaffs_add_device() is called: the paramers\r\n(dev-&gt;param) and the driver (dev-&gt;drv). The driver\r\nconfiguration (plugging in the driver functions) has already been\r\ndescribed above, so we will now look at the yaffs parameters.</p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\">The yaffs_param structure must be set before the\r\nyaffs_dev is added with yaffs_add_device() and should not be modified\r\nafter that.</p>\r\n<p class=\"western\">The params are defined in the Yaffs Tuning\r\nDocument.</p>\r\n<h1 class=\"western\" style=\"page-break-before: always\">11 Using the\r\nPOSIX file system interface</h1>\r\n<p class=\"western\">This section is directed to readers that might not\r\nbe very familiar with accessing a  file system via POSIX and\r\nPOSIX-like interfaces.</p>\r\n<h2 class=\"western\">11.1 Difference to Windows POSIX-like interfaces</h2>\r\n<p class=\"western\">MSDOS and Windows provide a POSIX-lke interface.\r\nIf you are familiar with this then that will help you. There are are\r\nhowever some slight differences, most importantly:</p>\r\n<ul>\r\n	<li/>\r\n<p class=\"western\">Windows has no concept of  links and has a\r\n	1:1 mapping between file names and files.POSIX supports files with\r\n	zero, one or many names. Refer to the sections on linking and\r\n	unlinking files. For instance POSIX allows you to unlink a file (ie\r\n	delete the name for a file) while it is still in use. You can\r\n	continue to read/write the file but it will be deleted as soon as\r\n	the last file handle to the file is closed. Windows, on the other\r\n	hand, does not allow you to unlink a file while it is in use.</p>\r\n	<li/>\r\n<p class=\"western\">Windows names drives with a letter. POSIX\r\n	has no drive letters. The whole POSIX file system is in a single\r\n	directory tree.</p>\r\n	<li/>\r\n<p class=\"western\">Directories and “folders” are the same\r\n	thing.</p>\r\n</ul>\r\n<h2 class=\"western\">11.2 Fundamental concepts</h2>\r\n<table width=\"642\" cellpadding=\"4\" cellspacing=\"0\">\r\n	<col width=\"126\">\r\n	<col width=\"499\">\r\n	<tr valign=\"top\">\r\n		<td width=\"126\" style=\"border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0.1cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\">File</p>\r\n		</td>\r\n		<td width=\"499\" style=\"border: 1px solid #000000; padding: 0.1cm\">\r\n			<p class=\"western\">A file is an object that is stored in the file\r\n			system. yaffs supports the following file types:</p>\r\n			<p class=\"western\">A regular file is a sequence of bytes stored in\r\n			the file system.</p>\r\n			<p class=\"western\">A directory holds links to other files.</p>\r\n			<p class=\"western\">A symbolic link holds a name to another file.</p>\r\n			<p class=\"western\">A special file holds device ids or similar\r\n			information.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"126\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\">Directory</p>\r\n		</td>\r\n		<td width=\"499\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\">This is a structure that holds links and allows\r\n			a file to be found by name. Note that a single file may have many\r\n			links(ie names) and many be found in many places in the directory\r\n			structure.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"126\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\">Link</p>\r\n		</td>\r\n		<td width=\"499\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\">This is a name that allows the file to be\r\n			found. There are two types of link: real links (sometimes called\r\n			hard links) and symbolic (or soft) links. \r\n			</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"126\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\">Handle</p>\r\n		</td>\r\n		<td width=\"499\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\">A file handle provides a context from which a\r\n			file can be accessed and manipulated. A handle has a current file\r\n			position pointer which points to where the file is being read or\r\n			written. Multiple handles can simultaneously access a single file.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"126\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\">File mode</p>\r\n		</td>\r\n		<td width=\"499\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\">The mode is the set of flags that define the\r\n			type of file as well as the current permissions associated with\r\n			the file.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"126\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\">Path</p>\r\n		</td>\r\n		<td width=\"499\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\">This is a string that defines the directories\r\n			and file name. For example:</p>\r\n			<p class=\"western\">“/data/direct-1/file1”</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"126\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\">File metadata</p>\r\n		</td>\r\n		<td width=\"499\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\">This is the information about the file,\r\n			excluding the file contents. The metadata includes the name, mode,\r\n			size and other details.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"126\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\">Mount,<br/>\r\npartition,<br/>\r\nfile system</p>\r\n		</td>\r\n		<td width=\"499\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\">These terms all refer to a single mounted flash\r\n			area. Each mount is hooked into a common directory structure.<br/>\r\nThe\r\n			term file system can sometimes be confusing because it is used\r\n			both for a single mounted partition as well as the the file system\r\n			code. In other words, we might say that both “/boot” is a file\r\n			system and might also say that yaffs is a file system.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"126\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\">inode number</p>\r\n		</td>\r\n		<td width=\"499\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\">The inode number is a unique number that\r\n			identifies the object within the mount. Note that inodes are not\r\n			unique between two or more mounts. There is no way to reach a file\r\n			by inode, only via its links.</p>\r\n		</td>\r\n	</tr>\r\n</table>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<h2 class=\"western\">11.3 Error code</h2>\r\n<p class=\"western\">Most functions result in error codes if the\r\nfunction does not execute successfully. In these cases yaffs calls a\r\nfunction called <code class=\"western\">yaffs_SetError()</code> with\r\nthe error value. This function can be configured to deliver the error\r\ninto the system\'s error mechanism.</p>\r\n<p class=\"western\">In the case of functions that return integers, a\r\nreturned value smaller than 0 indicates an error occurred. Functions\r\nreturning pointers will return NULL if an error occurred.</p>\r\n<h2 class=\"western\">11.4 Links – the hard kind  (not symbolic links)</h2>\r\n<p class=\"western\">At first we\'re just considering real links and not\r\nsymbolic links. Sometimes real links are also called hard links to\r\ndifferentiate them from symbolic links (which are sometimes called\r\nsoft links).</p>\r\n<p class=\"western\">The difference between links and files is subtle\r\nand can be confusing. Briefly:</p>\r\n<ul>\r\n	<li/>\r\n<p class=\"western\">a file is the stored object in the file\r\n	system</p>\r\n	<li/>\r\n<p class=\"western\">the link is how it is hooked into the\r\n	directory structure.</p>\r\n</ul>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\">The first link to a file is created by using the\r\nfile creation calls: <code class=\"western\">yaffs_open()</code>,\r\n<code class=\"western\">yaffs_mknod()</code>, <code class=\"western\">yaffs_symlink()</code>\r\nand <code class=\"western\">yaffs_mkdir()</code>.</p>\r\n<p class=\"western\">A link can be destroyed by using the\r\n<code class=\"western\">yaffs_unlink()</code> function. Directories are\r\ndestroyed using the <code class=\"western\">yaffs_rmdir()</code>\r\nfunction (oh, and the directory must be empty).</p>\r\n<p class=\"western\">Once a file is both unused (there are no handles\r\nopen to it) and there are no links to it it is then deleted.</p>\r\n<p class=\"western\">A link can be renamed by using the <code class=\"western\">yaffs_rename()</code>\r\nfunction.</p>\r\n<p class=\"western\">A file may have many links. These may be created\r\nusing the <code class=\"western\">yaffs_link()</code> function. All the\r\nlinks access the same file and there is no one link that is\r\nconsidered “the real link” and others being “the duplicate\r\nlink”. All links to a file have the same priority. If you look at\r\nthe inode number for “a” and for “b” then they will be the\r\nsame because they are refering to exactly the same file.</p>\r\n<p class=\"western\">Thus:</p>\r\n<ol>\r\n	<li/>\r\n<p class=\"western\">If we start with a file called “a” and\r\n	then call <code class=\"western\">yaffs_link(“a”, “b”)</code>\r\n	we now have two links to the same file. We can\'t tell them apart.</p>\r\n	<li/>\r\n<p class=\"western\">If we now unlink “a”, the file still\r\n	exists under the link “b”.</p>\r\n	<li/>\r\n<p class=\"western\">If we now unlink “b” the file will no\r\n	longer be linked. If there is a handle open to the file then we can\r\n	still access the file through the handle and continue to read or\r\n	modify the file. If there is no link to the file it is deleted.</p>\r\n	<li/>\r\n<p class=\"western\">If an unlinked file was kept alive because\r\n	of a handle being open, the file will not show up in the directory\r\n	structure (because it has no link) and will be deleted as soon as\r\n	the handle is closed (or if the file system is unmounted).</p>\r\n</ol>\r\n<p class=\"western\">There are some limitations in how links are used:</p>\r\n<ul>\r\n	<li/>\r\n<p class=\"western\">The existing file you are linking to must\r\n	exist.</p>\r\n	<li/>\r\n<p class=\"western\">The file you are linking to must be in the\r\n	same mount (partition) as the link you are creating.</p>\r\n	<li/>\r\n<p class=\"western\">You cannot create a link to a directory\r\n	because this would allow the creation of recursive loops.</p>\r\n	<li/>\r\n<p class=\"western\">The new link name must not exist.</p>\r\n</ul>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<h2 class=\"western\">11.5 Symbolic links</h2>\r\n<p class=\"western\">Now that you understand how hard links work, we\'ll\r\nintroduce symbolic (or soft) links.</p>\r\n<p class=\"western\">A symbolic link holds an alias for a different\r\nobject. When you use that symbolic link in a path the alias is used\r\ninstead. To that extent symbolic link and hard links are the same.</p>\r\n<p class=\"western\">You can remove symbolic links with the\r\n<code class=\"western\">yaffs_unlink()</code> function, just like hard\r\nlinks.</p>\r\n<p class=\"western\">There are, however, some important differences. A\r\nsymbolic link only does its linking function when the path is being\r\nevaluated and thus:</p>\r\n<ul>\r\n	<li/>\r\n<p class=\"western\">The file you are creating an alias to does\r\n	not have to exist.</p>\r\n	<li/>\r\n<p class=\"western\">The file you are creating an alias to does\r\n	not have to be in the same mount.</p>\r\n	<li/>\r\n<p class=\"western\">You can create symbolic links to\r\n	directories.</p>\r\n	<li/>\r\n<p class=\"western\">A symbolic link will not keep a file alive\r\n	by itself. Only a hard link can do that.</p>\r\n</ul>\r\n<p class=\"western\">Thus:</p>\r\n<ol>\r\n	<li/>\r\n<p class=\"western\">If we start with a file called “a” and\r\n	then call <code class=\"western\">yaffs_symlink(“a”, “b”)</code>\r\n	we now have one link to the file called “a” and a symbolic link\r\n	aliasising from “b” to “a”.</p>\r\n	<li/>\r\n<p class=\"western\">If we use <code class=\"western\">yaffs_open(“a”)</code>\r\n	or <code class=\"western\">yaffs_open(“b”)</code> they will open\r\n	the same file. The path resolution mechanism substitutes in the\r\n	alias and so will look up “a”. The same applies to almost all\r\n	functions that takes a path, such as <code class=\"western\">yaffs_truncate()</code>,\r\n	<code class=\"western\">yaffs_stat()</code> etc. The only exceptions\r\n	are <code class=\"western\">yaffs_lstat()</code> and <code class=\"western\">yaffs_readlink()</code>\r\n	which will treat the path as pointing to the symbolic link and not\r\n	the file.</p>\r\n	<li/>\r\n<p class=\"western\">You can tell “a” and “b” apart by\r\n	using <code class=\"western\">yaffs_lstat()</code>. <code class=\"western\">yaffs_lstat(“a”)</code>\r\n	will show the information for file “a”. <code class=\"western\">yaffs_lstat(“b”)</code>\r\n	will show the information for the symbolic link itself. Note the\r\n	difference with hard links. With hard links <code class=\"western\">yaffs_lstat(“a”)</code>\r\n	and <code class=\"western\">yaffs_lstat(“b”)</code> would show the\r\n	same results since they are EXACTLY the same thing being referenced.</p>\r\n	<li/>\r\n<p class=\"western\">If we now unlink “a”. then the file is\r\n	no longer linked and will no longer be accessible from “b”. Note\r\n	the difference with hard links.</p>\r\n</ol>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<h2 class=\"western\">11.6 Handle-based file handling</h2>\r\n<p class=\"western\">A handle is file accessor that allows us to access\r\nthe contents of a regular file. The handle identifies the file being\r\naccessed as well as a position pointer tracking where the next read\r\nor write operation will take place.</p>\r\n<p class=\"western\">A handle is identified by an integer of value 0 or\r\ngreater.</p>\r\n<p class=\"western\">A handle is created by using the <code class=\"western\">yaffs_open()</code>\r\ncall and returns the handle value. If the handle could not be created\r\nthen a negative value is returned and the yaffs error code is set.</p>\r\n<p class=\"western\">A handle remains valid until the handle is closed\r\nby <code class=\"western\">yaffs_close()</code>.</p>\r\n<p class=\"western\">The <code class=\"western\">yaffs_open()</code> call\r\ntakes three parameters:</p>\r\n<ul>\r\n	<li/>\r\n<p class=\"western\">name: Full path name of the file being\r\n	opened.</p>\r\n	<li/>\r\n<p class=\"western\">access flags: Flags being used to open this\r\n	handle</p>\r\n	<li/>\r\n<p class=\"western\">creation mode: Mode flags used when\r\n	creating a file.</p>\r\n</ul>\r\n<p class=\"western\">The access flags are one or more of:</p>\r\n<table width=\"100%\" cellpadding=\"4\" cellspacing=\"0\">\r\n	<col width=\"59*\">\r\n	<col width=\"197*\">\r\n	<tr valign=\"top\">\r\n		<td width=\"23%\" style=\"border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0.1cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\"><font face=\"Courier, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><code class=\"western\">O_CREAT</code></font></font></p>\r\n		</td>\r\n		<td width=\"77%\" style=\"border: 1px solid #000000; padding: 0.1cm\">\r\n			<p class=\"western\">Create file if it does not already exist.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"23%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\"><font face=\"Courier, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><code class=\"western\">O_EXCL</code></font></font></p>\r\n		</td>\r\n		<td width=\"77%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\">Only use with O_CREAT. Create file if it does\r\n			not exist. If the file already exists then fail.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"23%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\"><font face=\"Courier, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><code class=\"western\">O_TRUNC</code></font></font></p>\r\n		</td>\r\n		<td width=\"77%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\">If the file exists, and opening with write\r\n			access, then truncate the file to zero bytes long.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"23%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\"><br/>\r\n\r\n			</p>\r\n		</td>\r\n		<td width=\"77%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\"><br/>\r\n\r\n			</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"23%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\"><font face=\"Courier, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><code class=\"western\">O_APPEND</code></font></font></p>\r\n		</td>\r\n		<td width=\"77%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\">Regardless of the handle position, always write\r\n			to the end of the file.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"23%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\"><br/>\r\n\r\n			</p>\r\n		</td>\r\n		<td width=\"77%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\"><br/>\r\n\r\n			</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"23%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\"><font face=\"Courier, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><code class=\"western\">O_RDWR</code></font></font></p>\r\n		</td>\r\n		<td width=\"77%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\">Open for read/write access.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"23%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\"><font face=\"Courier, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><code class=\"western\">O_WRONLY</code></font></font></p>\r\n		</td>\r\n		<td width=\"77%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\">Open for write access and no read access.</p>\r\n			<p class=\"western\"><br/>\r\n\r\n			</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"23%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\"><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>0\r\n			(zero)</b></font></font></p>\r\n		</td>\r\n		<td width=\"77%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\">If neither O_RDWR or O_WRONLY is set then the\r\n			file will be opened for read-only access.</p>\r\n		</td>\r\n	</tr>\r\n</table>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\">Where they are not mutually exclusive, these flags\r\nare typically combined. For example:</p>\r\n<p class=\"western\"><code class=\"western\">O_CREAT | O_TRUNC | O_RDWR</code>\r\n: Create a new file if it does not exist otherwise if the file\r\nalready exists then truncate to zero length. Typically used to\r\noverwrite a file or create if it does not already exist.</p>\r\n<p class=\"western\"><code class=\"western\">O_CREAT | OEXCL | O_WRONLY</code>\r\n: Create a new file, opening it for write only. Fails if file already\r\nexists.</p>\r\n<p class=\"western\">There are three mode flags that can be controlled\r\nor set. These flags may be set by the open that creates the file or\r\nlater by the <code class=\"western\">yaffs_chmod()</code>.</p>\r\n<table width=\"100%\" cellpadding=\"4\" cellspacing=\"0\">\r\n	<col width=\"59*\">\r\n	<col width=\"197*\">\r\n	<tr valign=\"top\">\r\n		<td width=\"23%\" style=\"border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0.1cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\"><font face=\"Courier New, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><code class=\"western\">S_IREAD</code></font></font></p>\r\n		</td>\r\n		<td width=\"77%\" style=\"border: 1px solid #000000; padding: 0.1cm\">\r\n			<p class=\"western\">The file may be opened for read access.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"23%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\"><font face=\"Courier New, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><code class=\"western\">S_IWRITE</code></font></font></p>\r\n		</td>\r\n		<td width=\"77%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\">The file may be opened for write access.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"23%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\"><font face=\"Courier New, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><code class=\"western\">S_IEXEC</code></font></font></p>\r\n		</td>\r\n		<td width=\"77%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\">The file may be opened for execution. This is\r\n			not enforced by yaffs.</p>\r\n		</td>\r\n	</tr>\r\n</table>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\">Once you have opened a handle you can then do\r\nvarious operations on the file.</p>\r\n<table width=\"605\" cellpadding=\"4\" cellspacing=\"0\">\r\n	<col width=\"248\">\r\n	<col width=\"339\">\r\n	<tr valign=\"top\">\r\n		<td width=\"248\" style=\"border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0.1cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\"><font face=\"Courier New, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><code class=\"western\">yaffs_close(handle)</code></font></font></p>\r\n		</td>\r\n		<td width=\"339\" style=\"border: 1px solid #000000; padding: 0.1cm\">\r\n			<p class=\"western\">Close the handle. It is no longer usable.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"248\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\"><font face=\"Courier New, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><code class=\"western\">yaffs_fsync(handle)</code></font></font></p>\r\n		</td>\r\n		<td width=\"339\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\">Flush out any cached writes to the file, as\r\n			well as the file meta-data.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"248\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\"><font face=\"Courier New, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><code class=\"western\">yaffs_datasync(handle)</code></font></font></p>\r\n		</td>\r\n		<td width=\"339\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\">Same as yaffs_fsync() but no file metadata.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"248\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\"><font face=\"Courier New, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><code class=\"western\">yaffs_flush(handle)</code></font></font></p>\r\n		</td>\r\n		<td width=\"339\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\">Same as yaffs_fsync()</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"248\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\"><font face=\"Courier New, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><code class=\"western\">yaffs_dup(handle)</code></font></font></p>\r\n		</td>\r\n		<td width=\"339\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\">Duplicates a handle.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"248\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\"><font face=\"Courier New, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><code class=\"western\">yaffs_lseek(handle,\r\n			offset, whence)</code></font></font></p>\r\n		</td>\r\n		<td width=\"339\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\">Set the handle read/write position. Note that\r\n			this does not modify the file. You can seek past the end of the\r\n			file. This does not modify the file size.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"248\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\"><font face=\"Courier New, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><code class=\"western\">yaffs_ftruncate(handle,\r\n			size)</code></font></font></p>\r\n		</td>\r\n		<td width=\"339\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\">Change the file size. It can be made bigger or\r\n			smaller. This does not change the handle read/write position.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"248\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\"><font face=\"Courier New, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><code class=\"western\">yaffs_fstat(handle,\r\n			buf)</code></font></font></p>\r\n		</td>\r\n		<td width=\"339\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\">Get file status.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"248\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\"><font face=\"Courier New, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><code class=\"western\">yaffs_fchmod(handle,\r\n			mode)</code></font></font></p>\r\n		</td>\r\n		<td width=\"339\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\">Change the file mode.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"248\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\"><br/>\r\n\r\n			</p>\r\n		</td>\r\n		<td width=\"339\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\"><br/>\r\n\r\n			</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"248\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\"><font face=\"Courier New, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><code class=\"western\">yaffs_read(handle,\r\n			buffer, nbytes)</code></font></font></p>\r\n		</td>\r\n		<td width=\"339\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\">Read data from file at file pointer and update\r\n			pointer.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"248\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\"><font face=\"Courier New, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><code class=\"western\">yaffs_pread(handle,\r\n			buffer, nbytes, position)</code></font></font></p>\r\n		</td>\r\n		<td width=\"339\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\">Read data from file at specified position. Does\r\n			not modify file pointer</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"248\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\"><font face=\"Courier New, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><code class=\"western\">yaffs_write(handle,\r\n			buffer, nbytes)</code></font></font></p>\r\n		</td>\r\n		<td width=\"339\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\">Write data to file at file pointer and update\r\n			pointer.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"248\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\"><font face=\"Courier New, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><code class=\"western\">yaffs_pread(handle,\r\n			buffer, nbytes, position)</code></font></font></p>\r\n		</td>\r\n		<td width=\"339\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\">Write data to file at specified position. Does\r\n			not modify file pointer</p>\r\n		</td>\r\n	</tr>\r\n</table>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<h2 class=\"western\">11.7 Changing file size</h2>\r\n<p class=\"code-western\"><code class=\"western\">yaffs_truncate(path,\r\nnewSize)</code></p>\r\n<p class=\"code-western\"><code class=\"western\">yaffs_ftruncate(handle,\r\nnewSize)</code></p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\">These change a file\'s size. Note that truncating\r\ndoes not just mean make the file smaller. The file can also be made\r\nlarger.</p>\r\n<p class=\"western\">Yaffs does not store bytes that it does not need\r\nto. If you use truncate to make a file larger then this will not\r\nnecessarily occupt more flash space.</p>\r\n<p class=\"western\">See also <code class=\"western\">yaffs_lseek()</code>\r\ntoo. Note that <code class=\"western\">yaffs_lseek() </code>only\r\nchanges the position of the write pointer and does not impact on the\r\nfile size unless the file is written.</p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<h2 class=\"western\">11.8 Getting/setting information about files</h2>\r\n<p class=\"code-western\"><code class=\"western\">yaffs_chmod(path, mode)</code></p>\r\n<p class=\"code-western\"><code class=\"western\">yaffs_fchmod(handle,\r\nmode)</code></p>\r\n<p class=\"code-western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\">yaffs_access(path,amode)</code></p>\r\n<p class=\"code-western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\">yaffs_stat(path, struct\r\nyaffs_stat *buf) </code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\">yaffs_fstat(handle,\r\nstruct yaffs_stat *buf)</code></p>\r\n<p class=\"code-western\"><code class=\"western\">yaffs_lstat(path,\r\nstruct yaffs_stat *buf)</code></p>\r\n<p class=\"code-western\"><code class=\"western\">yaffs_readlink(path,\r\nbuf, bufsize)</code></p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\">The chmod calls allow you to set different mode\r\nflags for the file. These can only be used to manipulate the\r\npermissions flags and not change the mode flags relating to the type\r\nof file.</p>\r\n<p class=\"western\"><code class=\"western\">yaffs_access() </code>tests\r\nthat the file can be accessed in the specified mode. This call\r\nreturns zero on success and -1 is returned</p>\r\n<p class=\"western\">amode is a bitmask of the following values:</p>\r\n<table width=\"100%\" cellpadding=\"4\" cellspacing=\"0\">\r\n	<col width=\"43*\">\r\n	<col width=\"213*\">\r\n	<tr valign=\"top\">\r\n		<td width=\"17%\" style=\"border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0.1cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\"><font face=\"Courier New, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><code class=\"western\">R_OK</code></font></font></p>\r\n		</td>\r\n		<td width=\"83%\" style=\"border: 1px solid #000000; padding: 0.1cm\">\r\n			<p class=\"western\">Check read is OK</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"17%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\"><font face=\"Courier New, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><code class=\"western\">W_OK</code></font></font></p>\r\n		</td>\r\n		<td width=\"83%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\">Check write is OK</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"17%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\"><font face=\"Courier New, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><code class=\"western\">X_OK</code></font></font></p>\r\n		</td>\r\n		<td width=\"83%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\">Check execute is OK.</p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"17%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\"><font face=\"Courier New, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><code class=\"western\">0\r\n			(zero)</code></font></font></p>\r\n		</td>\r\n		<td width=\"83%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\">Just checks the file exists</p>\r\n		</td>\r\n	</tr>\r\n</table>\r\n<p class=\"western\">These can be combined.</p>\r\n<p class=\"western\">For example:</p>\r\n<p class=\"code-western\"><code class=\"western\">if(yaffs_access(path,\r\nR_OK | W_OK) == 0)</code></p>\r\n<p class=\"code-western\"><code class=\"western\">	the file exists and\r\ncan be read and written</code></p>\r\n<p class=\"code-western\"><code class=\"western\">if(yaffs_access(path,\r\n0) == 0)</code></p>\r\n<p class=\"code-western\"><code class=\"western\">	the file exists</code></p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\">The stat calls retrieve a yaffs_stat structure of\r\ndata which is defined in yaffsfs.h. There are three versions:</p>\r\n<p class=\"western\"><code class=\"western\">yaffs_fstat</code>: Takes a\r\nhandle.</p>\r\n<p class=\"western\"><code class=\"western\">yaffs_stat</code>: Takes a\r\npath name and follows symbolic links.</p>\r\n<p class=\"western\"><code class=\"western\">yaffs_lstat</code>: Takes a\r\npath but does not follow symbolic links.</p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\">Thus, if path is a symbolic link, <code class=\"western\">yaffs_fstat()\r\n</code>will give information on the file that the link points to\r\nwhile <code class=\"western\">yaffs_lstat()</code> will give\r\ninformation about the link itself.</p>\r\n<p class=\"western\"><code class=\"western\">yaffs_readlink()</code> will\r\nread the read the link value into the buffer provided. For example:</p>\r\n<p class=\"code-western\"><code class=\"western\">	yaffs_symlink(“target”,”/link”);\r\n/* create a link called link to target */</code></p>\r\n<p class=\"code-western\"><code class=\"western\">	yaffs_readlink(“/link”,buffer,10);\r\n /* now buffer contains “target” */</code></p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<h2 class=\"western\">11.9 Changing the directory structure and names</h2>\r\n<p class=\"code-western\"><code class=\"western\">yaffs_open(path, flags,\r\nmode)</code></p>\r\n<p class=\"code-western\"><code class=\"western\">yaffs_mkdir(path, mode)</code></p>\r\n<p class=\"code-western\"><code class=\"western\">yaffs_symlink(targetPath,\r\nlinkPath)</code></p>\r\n<p class=\"code-western\"><code class=\"western\">yaffs_mknod(pathname,\r\nmode, dev)</code></p>\r\n<p class=\"code-western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\">yaffs_link(existingPath,\r\nnewath)</code></p>\r\n<p class=\"code-western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\">yaffs_unlink(path)</code></p>\r\n<p class=\"code-western\"><code class=\"western\">yaffs_rmdir(path)</code></p>\r\n<p class=\"code-western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\">yaffs_rename(oldPath,\r\nnewPath)</code></p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\">Files of various types, and their first link, are\r\ncreated via the <code class=\"western\">yaffs_open()</code><code class=\"western\"><font face=\"Liberation Serif, serif\"><span style=\"font-weight: normal\">,</span></font></code><font face=\"Courier New, monospace\"><font size=\"2\" style=\"font-size: 10pt\">\r\n</font></font><code class=\"western\">yaffs_mkdir()</code><font face=\"Liberation Serif, serif\"><font size=\"2\" style=\"font-size: 10pt\">,\r\n</font></font><code class=\"western\">yaffs_symlink()</code> and\r\n<code class=\"western\">yaffs_mknod()</code><font face=\"Liberation Serif, serif\"><font size=\"3\" style=\"font-size: 12pt\">\r\n</font></font>functions.</p>\r\n<p class=\"western\"><code class=\"western\">yaffs_link()</code> can be\r\nused to create subsequent links to files. Note that you cannot create\r\na link to a directory.</p>\r\n<p class=\"western\"><code class=\"western\">yaffs_rename()</code> allows\r\nyou to rename a link. Note that renaming one link over another link\r\nis an atomic operation. That means that even if the operation is\r\ninterrupted by a power failure, the result will either complete or\r\nnot happen at all. If the target link is for a directory, then the\r\nrename will only work if the target directory is empty.</p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<h2 class=\"western\">11.10 Searching directories</h2>\r\n<p class=\"code-western\"><code class=\"western\">yaffs_DIR\r\n*yaffs_opendir(const YCHAR *dirname) ; </code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\">struct yaffs_dirent\r\n*yaffs_readdir(yaffs_DIR *dirp) ; </code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\">void\r\nyaffs_rewinddir(yaffs_DIR *dirp) ; </code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\">int\r\nyaffs_closedir(yaffs_DIR *dirp) ; </code>\r\n</p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\">Searching is performed by the following sequence\r\nof operations:</p>\r\n<ul>\r\n	<li/>\r\n<p class=\"western\">Open the directory for reading with\r\n	<code class=\"western\">yaffs_opendir()</code>.</p>\r\n	<li/>\r\n<p class=\"western\">Iterate through the entries in the\r\n	directory using <code class=\"western\">yaffs_readdir()</code>. Each\r\n	read will advance the directory read position.</p>\r\n	<li/>\r\n<p class=\"western\">You can reset to the start of the directory\r\n	with <code class=\"western\">yaffs_rewinddir()</code>.</p>\r\n	<li/>\r\n<p class=\"western\">Close the directory when finished with\r\n	<code class=\"western\">yaffs_closedir()</code>.</p>\r\n</ul>\r\n<h2 class=\"western\">11.11 Searching directories (fd interface)</h2>\r\n<p class=\"code-western\"><code class=\"western\">int </code><code class=\"western\">yaffs_open(const\r\nYCHAR *dirname, </code><code class=\"western\">O_RDONLY, 0</code><code class=\"western\">)\r\n; </code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\">struct yaffs_dirent\r\n*yaffs_readdir_</code><code class=\"western\">fd</code><code class=\"western\">(</code><code class=\"western\">int\r\nfd</code><code class=\"western\">) ; </code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\">void\r\nyaffs_rewinddir_</code><code class=\"western\">fd</code><code class=\"western\">(</code><code class=\"western\">int\r\nfd</code><code class=\"western\">) ; </code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\">int yaffs_close(</code><code class=\"western\">int\r\nfd</code><code class=\"western\">) ; </code>\r\n</p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\">This is not a POSIX interface, but provides an\r\nalternate interface for reading directories.</p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\">Searching is performed by the following sequence\r\nof operations:</p>\r\n<ul>\r\n	<li/>\r\n<p class=\"western\">Open the directory for reading with\r\n	<code class=\"western\">yaffs_open( </code><code class=\"western\">name,\r\n	O_RDONLY, 0</code><code class=\"western\">)</code>.</p>\r\n	<li/>\r\n<p class=\"western\">Iterate through the entries in the\r\n	directory using <code class=\"western\">yaffs_readdir_</code><code class=\"western\">fd</code><code class=\"western\">()</code>.\r\n	Each read will advance the directory read position.</p>\r\n	<li/>\r\n<p class=\"western\">You can reset to the start of the directory\r\n	with <code class=\"western\">yaffs_rewinddir_</code><code class=\"western\">fd</code><code class=\"western\">()</code>.</p>\r\n	<li/>\r\n<p class=\"western\">Close the directory when finished with\r\n	<code class=\"western\">yaffs_close()</code>.</p>\r\n</ul>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<h2 class=\"western\">11.12 Mount control and similar</h2>\r\n<p class=\"code-western\"><code class=\"western\">yaffs_mount(path) ; </code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\">yaffs_mount2(path,\r\nreadOnly); </code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\">yaffs_unmount(path);</code></p>\r\n<p class=\"code-western\"><code class=\"western\">yaffs_unmount2(path,\r\nint force); </code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\">yaffs_remount(path,\r\nforce, readOnly);</code></p>\r\n<p class=\"code-western\"><code class=\"western\">yaffs_sync(path) ;</code></p>\r\n<p class=\"code-western\"><code class=\"western\">yaffs_format(const\r\nYCHAR *path, </code>\r\n</p>\r\n<p class=\"western\"><code class=\"western\"> </code><code class=\"western\">		int\r\nunmount_flag, </code>\r\n</p>\r\n<p class=\"western\"><code class=\"western\"> </code><code class=\"western\">		int\r\nforce_unmount_flag, </code>\r\n</p>\r\n<p class=\"western\"><code class=\"western\"> </code><code class=\"western\">		int\r\nremount_flag) </code>\r\n</p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\">A partition must be mounted to be accessed.\r\n<code class=\"western\">yaffs_mount()</code> will mount the partition\r\nfor read/write access. <code class=\"western\">yaffs_mount2()</code>\r\ncan be used to control whether the access is read/write or read only.</p>\r\n<p class=\"western\">A partition can be unmounted to remove it from\r\nuse. <code class=\"western\">yaffs_unmount()</code> will fail if any\r\nfiles are in use whereas <code class=\"western\">yaffs_unmount2()</code>\r\nallows you to force the unmount even if files are open. Note that any\r\nfile handles will then be broken and will no longer access the files.</p>\r\n<p class=\"western\"><code class=\"western\">yaffs_remount()</code> can\r\nbe used to change the access to a currently mounted partition and is\r\nequivalent to making an <code class=\"western\">unmount2()</code> call\r\nfollowed by a <code class=\"western\">mount2()</code> call.</p>\r\n<p class=\"western\"><code class=\"western\">yaffs_sync()</code> does not\r\nchange the mount status but flushes out any pending data on a\r\npartition that is mounted with write access.</p>\r\n<p class=\"western\"><font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>yaffs_format()</b></font></font>\r\nprovides a mechanism to format a device. It has various\r\nparameters.<br/>\r\n	<font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>unmount_flag</b></font></font>:\r\nIf set, yaffs_format() will unmount the device before formatting. If\r\nthis flag is not set and the device is mounted, then the format will\r\nfail with EBUSY.</p>\r\n<p class=\"western\">	<font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>force_unmount</b></font></font>:\r\nIf set, then an unmount is allowed even if the device is busy (eg.\r\nfiles open). If not set, then yaffs_format() will fail (EBUSY) if\r\nfiles are open.</p>\r\n<p class=\"western\">	<font face=\"Liberation Mono, monospace\"><font size=\"2\" style=\"font-size: 10pt\"><b>remount_flag</b></font></font>:\r\n If set, then the device will be remounted after the format if it was\r\nmounted.</p>\r\n<p class=\"western\">The force_unmount and remount_flag options only\r\nhave meaning if unmount_flag is set.</p>\r\n<h2 class=\"western\">11.13 Extended attributes (xattrt)</h2>\r\n<p class=\"western\">Extended attributes provide a mechanism to attach\r\na limited amount of extra data to a file without actually modifying\r\nthe file. Each xattribute is a named pair of name and some data. Each\r\nfile can have as many xattribs as there is space for. In Yaffs, this\r\nis around chunk-size – 512 bytes. So on devices with 2kbyte chunks\r\nyou can store up to 1.5kbytes of xattribute information.</p>\r\n<p class=\"western\">Although there are 12 xattr functions, there are\r\nreally only four basic functions, each with 3 different flavours.</p>\r\n<p class=\"western\">The basic functions are: set an xattr, get an\r\nxattr, remove an xattribute and list the xattribute names.</p>\r\n<p class=\"code-western\">int yaffs_setxattr(const char *path, const\r\nchar *name, \r\n</p>\r\n<p class=\"code-western\">                        const void *data, int\r\nsize, int flags); \r\n</p>\r\n<p class=\"code-western\">int yaffs_lsetxattr(const char *path, const\r\nchar *name, \r\n</p>\r\n<p class=\"code-western\">                        const void *data, int\r\nsize, int flags); \r\n</p>\r\n<p class=\"code-western\">int yaffs_fsetxattr(int fd, const char *name,\r\n</p>\r\n<p class=\"code-western\">                        const void *data, int\r\nsize, int flags); \r\n</p>\r\n<p class=\"western\">These functions are called with name being the\r\nname of the xattr, a pointer to the data and the size of the data,\r\nand flags.</p>\r\n<p class=\"western\">The flags are:</p>\r\n<p class=\"western\">XATTR_CREATE: Create a new xattr, fail with\r\n-EEXIST if the xattrib already exists.</p>\r\n<p class=\"western\">XATTR_REPLACE: Replace an existing xattr, fail\r\nwith -ENOATTR if it does not exist.</p>\r\n<p class=\"western\">zero: Just create with no checks, replace if it\r\nalready exists.</p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\">Setting can fail with -ENOSPC if there is not\r\nenough space to store the xattrib.</p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"code-western\">int yaffs_getxattr(const char *path, const\r\nchar *name, \r\n</p>\r\n<p class=\"code-western\">                        void *data, int\r\nsize); \r\n</p>\r\n<p class=\"code-western\">int yaffs_lgetxattr(const char *path, const\r\nchar *name, \r\n</p>\r\n<p class=\"code-western\">                        void *data, int\r\nsize); \r\n</p>\r\n<p class=\"code-western\">int yaffs_fgetxattr(int fd, const char *name,\r\n</p>\r\n<p class=\"code-western\">                        void *data, int\r\nsize); \r\n</p>\r\n<p class=\"western\">These get (fetch) an xattrib.</p>\r\n<p class=\"western\">If the call succeeds, the length of the retrieved\r\nxattrib is returned. This call can fail with -ENOATTR if the\r\nrequested xattr does not exist or -ERANGE if the buffer was too\r\nsmall.</p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"code-western\">int yaffs_removexattr(const char *path, const\r\nchar *name); \r\n</p>\r\n<p class=\"code-western\">int yaffs_lremovexattr(const char *path,\r\nconst char *name); \r\n</p>\r\n<p class=\"code-western\">int yaffs_fremovexattr(int fd, const char\r\n*name); \r\n</p>\r\n<p class=\"western\">These functions delete an existing xattr. If the\r\nxattr does not exist then -ENOATTR is returned.</p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"code-western\">int yaffs_listxattr(const char *path, char\r\n*list, int size); \r\n</p>\r\n<p class=\"code-western\">int yaffs_llistxattr(const char *path, char\r\n*list, int size); \r\n</p>\r\n<p class=\"code-western\">int yaffs_flistxattr(int fd, char *list, int\r\nsize); \r\n</p>\r\n<p class=\"western\">These functions fetch a list of the xattrib names\r\ninto the list buffer. The names are NUL terminated. eg.\r\n“attrib0\\0attrib1\\0...”.</p>\r\n<p class=\"western\">The function returns the length of the list,\r\notherwise if the list buffer is too short it returns -ERANGE.</p>\r\n<p class=\"western\">Note: If you call these functions with a list\r\nbuffer size of zero, this acts as a query of the required buffer\r\nsize. No data is actually transferred into the list.</p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\">For example we might choose to add some xattribs\r\nto a media file:</p>\r\n<p class=\"code-western\">//Set description</p>\r\n<p class=\"code-western\">yaffs_fsetxattr(fd, “user-comment”, “I\r\nhate this song!”,18);</p>\r\n<p class=\"code-western\">yaffs_fsetxattr(fd, “price-in-cents”,\r\n&amp;cost, sizeof(cost));</p>\r\n<p class=\"code-western\">// Get the comment</p>\r\n<p class=\"code-western\">yaffs_fgetxattr(fd, “user_comment”,\r\nbuffer, sizeof(buffer);</p>\r\n<p class=\"code-western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"code-western\">//List the attributes in a NUL delimited list</p>\r\n<p class=\"code-western\">yaffs_flistxattr(fd, list_buf,\r\nsizeof(list_buf));</p>\r\n<p class=\"code-western\">// Now list_buf has\r\nuser-comment\\0price-in-cents\\0</p>\r\n<p class=\"code-western\">yaffs_fremovexattr(fd, ”user-comment”);</p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<h2 class=\"western\">11.14 Other</h2>\r\n<p class=\"code-western\"><code class=\"western\">yaffs_freespace(path); </code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\">yaffs_totalspace(path);\r\n</code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\">yaffs_inodecount(path);\r\n</code>\r\n</p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\">These functions provide information on the free\r\nand total space (in bytes) for the mount that the path addresses.</p>\r\n<p class=\"western\"><code class=\"western\">yaffs_inodecount()</code>\r\nreturns the number of files on the mount that the path addresses.</p>\r\n\r\n<h1 class=\"western\" style=\"page-break-before: always\">12 Example:\r\nyaffs_readdir() and yaffs_stat()</h1>\r\n<p class=\"western\">This code snippet illustrates using\r\n<code class=\"western\">yaffs_readdir()</code> and associated functions\r\nto iterate through a directory. It also shows how to use\r\n<code class=\"western\">yaffs_lstat() </code>to get information on a\r\nfile and interpret it.</p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">void\r\ndump_directory(const char *dname) </font></code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">{\r\n</font></code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">	yaffs_DIR\r\n*d; </font></code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">	yaffs_dirent\r\n*de; </font></code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">	struct\r\nyaffs_stat s; </font></code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">	char\r\nstr[100]; </font></code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">			\r\n</font></code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">	d\r\n= yaffs_opendir(dname); </font></code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">	\r\n</font></code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">	if(!d)\r\n{ </font></code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">		printf(&quot;opendir\r\nfailed\\n&quot;); </font></code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">	}\r\nelse { </font></code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">		while((de\r\n= yaffs_readdir(d)) != NULL) { </font></code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">			sprintf(str,&quot;%s/%s&quot;,dname,de-&gt;d_name);\r\n</font></code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">			\r\n</font></code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">			yaffs_lstat(str,&amp;s);\r\n</font></code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">			\r\n</font></code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">			printf(&quot;%s\r\ninode %d length %d mode %X &quot;,</font></code></p>\r\n<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);\r\n</font></code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">			switch(s.st_mode\r\n&amp; S_IFMT) { </font></code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">				case\r\nS_IFREG: printf(&quot;data file&quot;); break; </font></code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">				case\r\nS_IFDIR: printf(&quot;directory&quot;); break; </font></code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">				case\r\nS_IFLNK: printf(&quot;symlink --&gt;&quot;); </font></code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">					if(yaffs_readlink(str,str,100)\r\n&lt; 0) </font></code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">						printf(&quot;no\r\nalias&quot;); </font></code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">					else\r\n</font></code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">						printf(&quot;\\&quot;%s\\&quot;&quot;,str);</font></code></p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">					break;\r\n</font></code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">				default:\r\nprintf(&quot;unknown&quot;); break; </font></code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">			}</font></code></p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">			printf(&quot;\\n&quot;);\r\n</font></code>\r\n</p>\r\n<p class=\"code-western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">			if((s.st_mode\r\n&amp; S_IFMT) == S_IFDIR)</font></code></p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">				dump_directory_tree_worker(str);\r\n</font></code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">		}\r\n</font></code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">		\r\n</font></code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">		yaffs_closedir(d);\r\n</font></code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">	}\r\n</font></code>\r\n</p>\r\n<p class=\"code-western\"><code class=\"western\"><font size=\"2\" style=\"font-size: 10pt\">}\r\n</font></code>\r\n</p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n','<p>This describes the Yaffs Direct Interface (YDI), which allows Yaffs to be simply integrated with embedded systems, with or without an RTOS.</p><p>&nbsp;</p>','raw_html'),('article',0,454,607,'und',0,'<p>&nbsp;</p>\r\n\r\n<h2>1 Background</h2>\r\n\r\n<p>This document is intended to provide a outline to the various tests that are incorporated into Yaffs Direct. Most of these tests were written as debug tools to test error response by various Yaffs functions. These and others can be used to check if Yaffs is working properly.</p>\r\n\r\n<h2>2 Running the tests</h2>\r\n\r\n<p>All of the test directories should have a Makefile. Run it to compile the test. The Readme.txt file should tell you how to run the tests.</p>\r\n\r\n<h2>3 Tests</h2>\r\n\r\n<ul>\r\n	<li>\r\n	<p>is_yaffs_working_tests folder contains a the tests related to simply seeing if yaffs is working. There is only one test at the moment, test_1_yaffs_mount.c, which tests if yaffs will mount, create a file and be able to read the file after remounting.</p>\r\n	</li>\r\n	<li>\r\n	<p>stress_tester folder contains yaffs_tester.c which stress tests yaffs by opening and closing files at random. This test will run forever (or until it crashes).</p>\r\n	</li>\r\n	<li>\r\n	<p>handle_tests folder contains the test handle_tests.c which just creates files and duplicates the file handle.</p>\r\n	</li>\r\n	<li>\r\n	<p>The yaffs_and_linux_mirror_tests folder runs a yaffs operation and then compares the response the same command run under linux. This test is used to check that yaffs responds in expected manner with respect to linux.</p>\r\n	</li>\r\n	<li>\r\n	<p>quick_tests folder contains the quick_test which tests almost all of yaffs functions\' error handling and error codes.</p>\r\n	</li>\r\n	<li>\r\n	<p>The threading folder contains the test_threading.c which tests the thread locking ability of yaffs.</p>\r\n	</li>\r\n</ul>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>The folder linux_tests contains the linux_test.c test which tests yaffs running under linux using the nandsim generator. &nbsp;</p>\r\n','<p>This provides a outline to the various tests that are incorporated into Yaffs Direct. Most of these tests were written as debug tools to test error response by various Yaffs functions. These and others can be used to check if Yaffs is working properly.</p>','full_html'),('paper',0,455,608,'und',0,'<p>&nbsp;</p>\r\n\r\n<h2>1 Purpose</h2>\r\n\r\n<p>The purpose of this document is to give an understanding of NAND failure modes and the measures that Yaffs takes to mitigate against these.</p>\r\n\r\n<p>This document is intended to be easy reading, but some very light-weight physics is required to understand the way NAND works.</p>\r\n\r\n<h2>2 The NAND Cell</h2>\r\n\r\n<p>This section explains the internal construction of a NAND device which helps to explain the way that it fails. Each NAND cell consists of a floating gate field effect transistor, described below.</p>\r\n\r\n<h3>2.1 Floating Gate Field Effect Transistor</h3>\r\n\r\n<p>A FET is the fundamental switching element used in almost all digital electronics. A FET is a a semiconductor element that conducts when a charge is applied to the gate.</p>\r\n\r\n<p><img alt=\"\" src=\"/sites/yaffs.net/files/images/fets.gif\" /></p>\r\n\r\n<p>A FET is a type of semiconductor device with a semiconducting region between the the source and drain connections, an insulating oxide and a gate region. The oxide prevents current from flowing from the gate to the oxide, but applying a voltage to the gate injects charge into the gate, creating an electric field which influences the conductive properties of the semiconductor region.</p>\r\n\r\n<p>In a regular FET, a conductive channel is formed between the source and drain when a suitable control voltage is applied to the gate. The current passed by the channel is dependent on the voltage (ie. the strength of the gate field). For now we will ignore analogue levels and just consider binary levels where the gate is either conducting or not. This effectively makes a switch that is controlled by the control gate.</p>\r\n\r\n<p>The floating gate FET is just like a regular FET except that it has an extra floating gate. This floating gate is able to trap charge between the two insulating layers. The trapped charge modifies the local electric field and thus modifies the effect of the control gate. If the floating gate has extra electrons (negative charge) then the control gate must be raised to a higher voltage to make the FET conduct.</p>\r\n\r\n<p>So a regular FET is conductive (on) when the control gate is high and is non-conductive (off) when the control gate is low. A floating gate FET, however, is only non-conductive (off) when the floating gate is charged and the gate is low. This gives us an output that is dependent on the floating gate and a way to read it (the gate).</p>\r\n\r\n<table>\r\n	<colgroup>\r\n		<col />\r\n		<col />\r\n		<col />\r\n	</colgroup>\r\n	<tbody>\r\n		<tr>\r\n			<td>\r\n			<p><strong>Floating gate charge</strong></p>\r\n			</td>\r\n			<td>\r\n			<p><strong>Control gate</strong></p>\r\n			</td>\r\n			<td>\r\n			<p><strong>Source/drain channel</strong></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Neutral(unprogrammed)</p>\r\n			</td>\r\n			<td>\r\n			<p>High</p>\r\n			</td>\r\n			<td>\r\n			<p>On (1)</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Neutral(unprogrammed)</p>\r\n			</td>\r\n			<td>\r\n			<p>Low</p>\r\n			</td>\r\n			<td>\r\n			<p>On (1)</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Charged(programmed)</p>\r\n			</td>\r\n			<td>\r\n			<p>High</p>\r\n			</td>\r\n			<td>\r\n			<p>On (1)</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Charged(programmed)</p>\r\n			</td>\r\n			<td>\r\n			<p>Low</p>\r\n			</td>\r\n			<td>\r\n			<p>Off (0)</p>\r\n			</td>\r\n		</tr>\r\n	</tbody>\r\n</table>\r\n\r\n<p><br />\r\n&nbsp;</p>\r\n\r\n<p>The tunneling oxide is insulating at low voltages but allows quantum tunneling (Fowler-Nordheim tunneling) at higher voltages. This FN-tunneling provides a mechanism to inject or remove charge from the floating gate by applying high voltages to the control gate or the body.</p>\r\n\r\n<p><img alt=\"\" src=\"/sites/yaffs.net/files/images/fn-tunnelling.gif\" /></p>\r\n\r\n<p>By applying a high positive voltage to the control gate, electrons are drawn into the floating gate, resulting in a programmed gate. Erasing is accomplished by the reverse operation which draws electrons out of the gate.</p>\r\n\r\n<p>So a floating gate FET is effectively a readable, programmable switch. In other words: memory!</p>\r\n\r\n<h3>2.2 NAND array layout</h3>\r\n\r\n<p>NAND flash gets its name from the way that the cells are arranged. NAND cells are arranged in chains called <em><strong>strings</strong></em>, typically 1 string per bit-position in the page n(for SLC). The length of the chain is the same as the number of pages per block. This arrangement uses far less silicon area than the NOR flash arrangement which reduces NAND cost and increases density. It does however also introduce some operational and reliability problems.</p>\r\n\r\n<p><img alt=\"\" src=\"/sites/yaffs.net/files/images/nand-page-select.gif\" /></p>\r\n\r\n<p>NAND is read by biasing the unselected pages with a high bias voltage and the selected pages with the low bias voltage. This means that the unselected cells are always on and the selected cells will be on or off according to the state of the floating gate.</p>\r\n\r\n<p>This means we have a matrix where:</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p>All unselected cells are on.</p>\r\n	</li>\r\n	<li>\r\n	<p>Selected unprogrammed cells are on</p>\r\n	</li>\r\n	<li>\r\n	<p>Selected programmed cells are off.</p>\r\n	</li>\r\n</ul>\r\n\r\n<p>Since only one cell in a string is selected at a time, the whole string is on if the selected cell is unprogrammed and is off if the selected cell is programmed. Thus, even though the cells in a string are all in series we can still access them individually.</p>\r\n\r\n<p>Well, that\'s how it would work in a perfect world anyway!</p>\r\n\r\n<p>The string and block arrangement means that it takes quite a while ( typically a few µsec) for the voltage of the string to stabilize after the selection has been made. This stabilization time is the cause of the “access time” delay when accessing NAND flash.</p>\r\n\r\n<h3>3 Fault Modes</h3>\r\n\r\n<p>Sit back for a moment and consider everything that must come together for the NAND flash to work and all the ways things can go wrong:</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p>Of course there can be fabrication faults where defects cause short circuits and open circuits within the chip. These types of fault apply to all chips type, not just flash.</p>\r\n	</li>\r\n	<li>\r\n	<p>Each cell has two oxide layers trapping the floating gate charge, one of which is semi-permeable to support tunneling. If either of these layers is too thick, the gate will be unresponsive. If they are too thin then the gate will tunnel too easily or will leak. If there are impurities in the oxide then the layers may become resistive and “leak”, thus causing the charge to change and possibly causing the state to change.</p>\r\n	</li>\r\n	<li>\r\n	<p>The floating gate state can change by either gaining or losing charge. If charge is lost, then a programmed cell may become unprogrammed (a 0 changes to a 1). If charge is gained, then an unprogrammed cell can become programmed.</p>\r\n	</li>\r\n	<li>\r\n	<p>In very extreme cases, a programmed cell can gain further negative charge and become over-programmed. This means that even if the high read bias voltage is applied to the control gate the FET does not become conductive. In this state, a cell will read as programmed (0) even if it is not selected. This means that the whole string will always read zero irrespective of which page is selected. This fault mode will persist until the cell is erased.</p>\r\n	</li>\r\n	<li>\r\n	<p>These devices are made very cheaply. Flash parts with tens of billions of NAND cells cost only a few dollars. There is little money to spend on individual part testing.</p>\r\n	</li>\r\n</ul>\r\n\r\n<p>Extending the previous state/selection table with the over-programmed fault state, we now have:</p>\r\n\r\n<table>\r\n	<colgroup>\r\n		<col />\r\n		<col />\r\n		<col />\r\n	</colgroup>\r\n	<tbody>\r\n		<tr>\r\n			<td>\r\n			<p><strong>Floating gate charge</strong></p>\r\n			</td>\r\n			<td>\r\n			<p><strong>Control gate</strong></p>\r\n			</td>\r\n			<td>\r\n			<p><strong>Source/drain channel</strong></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Neutral(unprogrammed)</p>\r\n			</td>\r\n			<td>\r\n			<p>High</p>\r\n			</td>\r\n			<td>\r\n			<p>On (1)</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Neutral(unprogrammed)</p>\r\n			</td>\r\n			<td>\r\n			<p>Low</p>\r\n			</td>\r\n			<td>\r\n			<p>On (1)</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Charged(programmed)</p>\r\n			</td>\r\n			<td>\r\n			<p>High</p>\r\n			</td>\r\n			<td>\r\n			<p>On (1)</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Charged(programmed)</p>\r\n			</td>\r\n			<td>\r\n			<p>Low</p>\r\n			</td>\r\n			<td>\r\n			<p>Off(0)</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Over-charged(over-programmed)</p>\r\n			</td>\r\n			<td>\r\n			<p>High</p>\r\n			</td>\r\n			<td>\r\n			<p>Off(0)</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Over-charged(over-programmed)</p>\r\n			</td>\r\n			<td>\r\n			<p>Low</p>\r\n			</td>\r\n			<td>\r\n			<p>Off(0)</p>\r\n			</td>\r\n		</tr>\r\n	</tbody>\r\n</table>\r\n\r\n<h2>4 Fault Mechanisms</h2>\r\n\r\n<p>This section explains some of the common NAND flash failure modes.</p>\r\n\r\n<h3>4.1 General chip fault</h3>\r\n\r\n<p>A NAND is a chip built with normal fabrication techniques and is thus prone to fail just like any other chip. Some of these faults can be isolated by marking faulty blocks. In some cases (eg. Damaged inter-block logic) the whole chip is discarded.</p>\r\n\r\n<p>Yaffs does not use the bad blocks, so they have no negative impact on the performance of the file system 9apart from a small reduction in the amount of storage available).</p>\r\n\r\n<h3>4.2 Oxide degradation</h3>\r\n\r\n<p>Every programming/erasure cycle causes some degradation of the oxide layers. Over many cycles this has a tendency to degrade the properties of the oxide layer. Excessive degradation can cause the cell to fail to erase or program, but more commonly just makes the other fault modes more prevalent.</p>\r\n\r\n<p>The primary mechanism of oxide degradation is that charge becomes permanently trapped within the oxide layer in a way that it is not cleared by programming and erasure. The resulting field disrupts both the FET\'s conductive channel and the effectiveness of the F-N tunneling.</p>\r\n\r\n<p>As a result of this field disruption, two things happen:</p>\r\n\r\n<ul>\r\n	<li>\r\n	<p>The FN tunneling is disrupted which means that the programming and erasure take longer to complete. Eventually programming and erasure might fail (see Program/erase failure below).</p>\r\n	</li>\r\n	<li>\r\n	<p>The programming and erasure is far more marginal meaning that less leakage is required to corrupt a bit value (see Charge leakage below).</p>\r\n	</li>\r\n</ul>\r\n\r\n<p>This degradation is permanent and incremental and is not cleared by erasure. This degradation is the cause of the endurance term in the NAND specification. Typical NAND flash endurance is 10,000 (MLC) to 100,000(SLC) program/erasure cycles.</p>\r\n\r\n<p>Endurance issues are largely minimized by wear leveling and write-path caching.</p>\r\n\r\n<p>Blocks that become too unreliable are retired from use.</p>\r\n\r\n<h3>4.3 Program/erase failure</h3>\r\n\r\n<p>Programming and erase operations are controlled by a built-in state machine that applies the programming/erasure voltages for a while then check whether the operation has succeeded. This is typically performed by an iterative algorithm that will time out if too many cycles are required.</p>\r\n\r\n<p>A failure is signaled in the chip status register when the built-in programming/erasure mechanisms fail to accomplish the programming or erasure within the maximum program/erasure time.</p>\r\n\r\n<p>It is important to realize that a programming failure is only checked on bits being set to a zero. If one bits are inadvertently set to zero then these are not raised as programming errors but are considered to be program disturb errors.</p>\r\n\r\n<p>Program/erase errors are generally the result of excessive oxide degradation.</p>\r\n\r\n<p>Yaffs handles programming/erasure errors as unrecoverable “hard errors”. If these are encountered then useful data is copied off the block and the whole block is permanently retired by marking the block as a bad block.</p>\r\n\r\n<p>These are the only failures that the NAND devices will actually identify. All other failures need to be detected in software.</p>\r\n\r\n<h3>4.4 Charge leakage</h3>\r\n\r\n<p>The oxide isolating the floating gate is not a perfect insulator and charge can escape very slowly, particularly at temperature extremes and when the oxide had been degraded by extensive use. High radiation environments can also make this worse.</p>\r\n\r\n<p>An effective way to handle charge leakage is to use ECC to detect and correct errors. Blocks with errors are rewritten on a fresh block allowing the data to be recreated before unrecoverable errors occur.</p>\r\n\r\n<h3>4.5 Program disturb</h3>\r\n\r\n<p>Program disturb happens when a bit is unintentionally programmed (1 to 0) during a programming operation. The affected bit can be in the same page or elsewhere in the block.</p>\r\n\r\n<p>Program disturb is caused by bias conditions in the flash block during programming. Even though full programming voltage is only applied to the cells being programmed, the other cells are also subject to lesser voltages and minor tunneling can occur. This effect is far less than regular programming but is more than read disturb. However, since a page is only programmed once before the block is erased, there is no multiplier effect as there is in read disturb.</p>\r\n\r\n<p>This condition is made worse by random programming in the block and by applying multiple partial writes to the pages.</p>\r\n\r\n<p>Yaffs1 only writes pages in a block in sequential order and writes pages only once, except for writing deletion markers.</p>\r\n\r\n<p>Yaffs2 does not write deletion markers and thus only programs pages sequentially and only once.</p>\r\n\r\n<p>Thus, Yaffs2 is far less likely to cause write disturb. Yaffs1 should only be used with devices that are tolerant of partial page programming.</p>\r\n\r\n<p>Program disturb within the same page can be corrected by verifying the page after programming.</p>\r\n\r\n<p>ECC provides a mechanism to correct infrequent program disturb errors.</p>\r\n\r\n<h3>4.6 Read disturb</h3>\r\n\r\n<p>Whenever a page is read, the other pages in the block are biased at a read-inhibit voltage to turn them on. While this voltage is not as high as the programming voltage, some very slight F-N tunneling can occur. With sufficient leakage the cell state may change, or the cell may become over-programmed. This effect is known as read disturb.</p>\r\n\r\n<p>Read disturb only impacts the pages in the block that are <em><strong>not</strong></em><strong> </strong>being read. This makes it difficult to detect in some systems. For example, consider a block where only the first page is read repeatedly. Other pages in the block may be incurring read disturb but these are happening without the effect being noticed by software. By the time the pages are eventually read, the read disturb may have caused more bit errors than the ECC is able to fix.</p>\r\n\r\n<p>Thankfully the problem is seldom that bad. Read disturb is very gradual. Under worst case conditions read disturb effects are expected to happen only after approximately 1 million page reads on the block for SLC flash or 100,000 page reads on the block for most MLC flash (or in other words, 10 times the endurance number).</p>\r\n\r\n<p>Be warned though that as process sizes shrink, read disturb is getting more problematic. Some flash parts are prone to read disturb after 20,000 page reads.</p>\r\n\r\n<p>The read disturb effect for a single read is far less than the write disturb effect for a single write. However, each page is only written once per block erase cycle but may be read many times. Therefore the cumulated effect of many read disturbs can cause problems.</p>\r\n\r\n<p>Read disturb effects are cleared by erasing the block.</p>\r\n\r\n<p>Various mechanisms are being implemented to correct read disturb in Yaffs, though these have not yet been implemented.</p>\r\n\r\n<p>The first mechanism is to count the number of page reads on each block. When a certain threshold is reached (say 50,000 reads for an MLC part), the block is rewritten and the count is zeroed.</p>\r\n\r\n<p>The second mechanism is to periodically read pages in the block. eg. Every 256 times a block has a page read we read an additional page to check for read disturb. If read disturb has happened then copy onto a fresh page.</p>\r\n\r\n<p>In addition, ECC does provide some benefit, but is insufficient on its own.</p>\r\n\r\n<h2>5 Decoding NAND reliability statistics</h2>\r\n\r\n<p>Many variables contribute to NAND reliability. These variables are inter-related in complex ways which mean that is is very difficult to try to isolate the variables from each other to fully characterize them. The major variables are:</p>\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>Temperature</p>\r\n			</td>\r\n			<td>\r\n			<p>Temperature impacts the performance of the materials and thus impacts the movement of charge within the NAND cells.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Storage time</p>\r\n			</td>\r\n			<td>\r\n			<p>This is related to the cell leakage. The leakage integrates over time so the longer the cells are stored, the more it changes.</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p>Manufacturing variance</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>Operating voltage</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>Erasure/programming cycles</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>Read cycles</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n		</tr>\r\n	</tbody>\r\n</table>\r\n\r\n<h2>6 MLC vs SLC</h2>\r\n\r\n<p>Both multi-level cell (MLC) and single-level cell (SLC) NAND cells work by trapping charge in the floating gate. By trapping different amounts of charge in the gate it is possible to modify the conductance of the string. MLC store two bits in once cell by using three threshold voltages to distinguish different cell charge levels<a href=\"#sdfootnote1sym\">1</a>.</p>\r\n\r\n<p><img alt=\"\" src=\"/sites/yaffs.net/files/images/nand-mlc-vs-slc-cell-voltages.gif\" /></p>\r\n\r\n<p>In the case of SLC, the cells are erased by the erasure state machine until the cell voltage is below V erase. Programming is accomplished by programming until the voltage exceeds Vprog. On reading, the voltage is compared with Vread.</p>\r\n\r\n<p>MLC programming is accomplished in the same way, except that there are multiple Vprogs and Vreads. This means that there is far less margin for error and cell disturbance is far more likely to cause state changes.</p>\r\n\r\n<p>For this reason, MLC is less reliable, has lower endurance numbers and lower read-disturb numbers. MLC thus requires far better ECC strategies to ensure reliable storage.</p>\r\n\r\n<p>But MLC is cheaper!</p>\r\n\r\n<h2>7 Summary</h2>\r\n\r\n<p>In summary, NAND flash has many failure modes but these can be corrected in software to provide a reliable storage solution. Any flash storage mechanisms that do not provide sufficient coverage of different fault modes should be considered suspect.</p>\r\n\r\n<table>\r\n	<colgroup>\r\n		<col />\r\n		<col />\r\n		<col />\r\n		<col />\r\n		<col />\r\n		<col />\r\n		<col />\r\n	</colgroup>\r\n	<tbody>\r\n		<tr>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p><strong>Chip Fault</strong></p>\r\n			</td>\r\n			<td>\r\n			<p><strong>Degradation</strong></p>\r\n			</td>\r\n			<td>\r\n			<p><strong>P/E failure</strong></p>\r\n			</td>\r\n			<td>\r\n			<p><strong>Leakage</strong></p>\r\n			</td>\r\n			<td>\r\n			<p><strong>Write Disturb</strong></p>\r\n			</td>\r\n			<td>\r\n			<p><strong>Read Disturb</strong></p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><strong>NAND self check</strong></p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\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><strong>Block retirement</strong></p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\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><strong>Wear levelling</strong></p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\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><strong>Write Verification</strong></p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</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><strong>Read counting/ re-write</strong></p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>Future</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><strong>Infrequent read checking</strong></p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>Future</p>\r\n			</td>\r\n			<td>\r\n			<p>Future</p>\r\n			</td>\r\n			<td>\r\n			<p>Future</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><strong>ECC</strong></p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n		</tr>\r\n		<tr>\r\n			<td>\r\n			<p><strong>Occasional rewrite of oldest data</strong></p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n			<td>\r\n			<p>&nbsp;</p>\r\n			</td>\r\n			<td>\r\n			<p>Yes</p>\r\n			</td>\r\n		</tr>\r\n	</tbody>\r\n</table>\r\n\r\n<p>Thus all fault mechanisms are covered by at least two corrective mechanisms (read disturb correcting features are planned).</p>\r\n\r\n<p><a href=\"#sdfootnote1anc\">1</a>Some MLC parts store more than 2 bits per cell, Storing n bits requires 2n levels.</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>&nbsp;</p>\r\n','NAND flash is one of very few types of electronic device which are knowingly shipped with errors and are expected to generate further errors without causing system failure.\r\n\r\nThis document describes the most important failure modes and how they may be addressed in software.','full_html'),('image',0,456,474,'und',0,'<p>This diagram shows the relationships between the Yaffs filesystem, the <a href=\"/documents/yaffs-direct-interface\">Yaffs Direct Interface</a>, Posix, the operating system and the flash hardware.</p>\r\n\r\n<p>&nbsp;</p>\r\n','<p>This diagram shows the relationships between the Yaffs filesystem, the Yaffs Direct Interface, Posix, the operating system and the flash hardware.</p>','basic_html'),('yaffs_user_logo',0,457,475,'und',0,'<p>Google Android and all the phone manufacturers who use it, use Yaffs as the default filesystem in some versions of Android.</p>\r\n\r\n<p>The Android Robot logo is reproduced from work created and&nbsp;<a href=\"http://code.google.com/policies.html\">shared by the Android Open Source Project</a>&nbsp;and used according to terms described in the&nbsp;<a href=\"http://creativecommons.org/licenses/by/2.5/\">Creative Commons 2.5 Attribution License</a>.</p>\r\n','Google Android and all the phone manufacturers who use it, use Yaffs as the default filesystem in some versions of Android.','basic_html'),('help_video',0,458,476,'und',0,'<p>&nbsp;</p>\r\n\r\n<p>This video covers the preparation needed to include Linux in Yaffs - describing the kernel build-tools needed, how to get the kernel source code and Yaffs source code. It\'s about 175Mb and 6m30 long.</p>\r\n\r\n<p><em>Here\'s the script for the video:</em></p>\r\n\r\n<p>Hello, today I\'m going to show you the tools you need to compile Yaffs into the Linux kernel. If you\'ve compiled Linux before, then this tutorial is not appropriate for you, and you should skip to the next one.</p>\r\n\r\n<p>Yaffs is the most widely used file system which is specialised for Flash memory. It\'s used in millions of devices, both under Linux and other operatings systems. It\'s available under the GNU Public Licence – the GPL – and commercial terms. You can find out more about Yaffs at yaffs.net.</p>\r\n\r\n<p>This demo is being run on Intel x86 because the end result is available for you to experiment with under Vagrant and Virtualbox, but with some slight changes we could target another architecture – for instance ARM. If you\'ve never used Vagrant, it provides a way to get a virtual system up and running in a few minutes. You can download the Vagrant box from the Yaffs web site.</p>\r\n\r\n<p><em>Login</em></p>\r\n\r\n<p>We\'re starting off with a stock Ubunutu Precise 12.04 386 server. We\'re using 386 because it\'s the lowest common demoninator, so the virtualbox will run on any system capable of running Virtualbox, but this works just as well for 64 bit architecture.</p>\r\n\r\n<p>Here we are at the command-line of a brand-new installation. The server has been configured for the minimum – it only has ssh, and a couple of othre things required for Vagrant. Of course there\'s no requirement for any of this for Yaffs.</p>\r\n\r\n<p>We need git version control to download Yaffs and the kernel source</p>\r\n\r\n<p><strong>sudo apt-get install git</strong></p>\r\n\r\n<p>We need these tools to build the kernel</p>\r\n\r\n<p><strong>sudo apt-get install crash kexec-tools makedumpfile kernel-wedge</strong></p>\r\n\r\n<p><strong>sudo apt-get install ncurses-dev libncurses5-dev</strong></p>\r\n\r\n<p><strong>sudo apt-get install build-essential fakeroot</strong></p>\r\n\r\n<p>And we need this to automate the job of creating a debian kernel package</p>\r\n\r\n<p><strong>sudo apt-get install kernel-package</strong></p>\r\n\r\n<p>Okay, we have all the tools I\'ll be needing, so I\'m going to go ahead and make a working directory.</p>\r\n\r\n<p><strong>mkdir kernel</strong></p>\r\n\r\n<p><strong>cd kernel</strong></p>\r\n\r\n<p>Of course we\'re going to need Yaffs, so I\'ll go ahead and download that</p>\r\n\r\n<p><strong>git clone git://www.aleph1.co.uk/yaffs2</strong></p>\r\n\r\n<p>That puts it into the Yaffs directory.</p>\r\n\r\n<p><strong>ls</strong></p>\r\n\r\n<p>This copy of Yaffs is licensed under the GNU Public Licence – the GPL, so I must make changes available under the GPL too. We also license Yaffs under commercial terms, removing the need to make your code available to others. Check our website for details.</p>\r\n\r\n<p>Now I need a copy of the kernel source code. I could have used one directly from kernel.org, but because this demo is running on ubuntu, I\'m going to grab the ubuntu kernel. This has the benefit of including the debian build rules.</p>\r\n\r\n<p><strong>git clone git://kernel.ubuntu.com/ubuntu/ubuntu-precise.git source</strong></p>\r\n\r\n<p><strong>cd source</strong></p>\r\n\r\n<p>Here it is</p>\r\n\r\n<p><strong>ls</strong></p>\r\n\r\n<p>And that\'s everything necessary to build the kernel with Yaffs. In the next video we\'ll show you how to configure and compile the kernel with Yaffs. More information about Yaffs is available at www.yaffs.net. Thanks for watching.</p>\r\n','<p>This video covers the preparation needed to include Linux in Yaffs - describing the kernel build-tools needed, how to get the kernel source code and Yaffs source code. It&#39;s about 175Mb and 6m30 long.</p>','basic_html'),('help_video',0,459,477,'und',0,'<p>&nbsp;</p>\r\n\r\n<p>This video shows you how to compile Yaffs into Linux. It’s just over 10 minutes long, and if you download it, it’s&nbsp;325MB. After watching this video you should be able to include Yaffs in Linux. Once you have Yaffs available you will be able to mount a simulated&nbsp;NAND&nbsp;device, or if you have a Flash device attached, you will be able to use it.&nbsp;The demo was run in a Virtualbox system, and is available as a&nbsp;<a href=\"http://www.yaffs.net/test-yaffs-under-linux-using-virtualbox-and-vagrant\">Vagrant box from our Downloads section</a>&nbsp;with details of how to build and use a simulated&nbsp;NAND&nbsp;device. &nbsp;</p>\r\n\r\n<p><em>The script for the video:</em></p>\r\n\r\n<p>Hello, today I\'m going to show you how to compile Yaffs into the linux kernel.&nbsp;Yaffs is the most widely used file system which is specialised for Flash memory. It\'s used in millions of devices, both under Linux and other operatings systems. It\'s available under the Gnu Public Licence – the GPL – and commercial terms.&nbsp;You can find out more about Yaffs at yaffs.net.</p>\r\n\r\n<p>Today we\'ll be targetting intel x86 but with some slight changes we could target another &nbsp;architecture – for instance ARM.&nbsp;This demo is being run in a Virtualbox machine, and the resulting system is available as a Vagrant box, so you can download the image and test it yourself.&nbsp;If you\'ve never used vagrant, it provides&nbsp; a way to get a virtual system up and running in a few minutes.</p>\r\n\r\n<p><strong>Login</strong></p>\r\n\r\n<p>We\'re starting off with a stock Ubunutu Precise 12.04 386 server. We\'re using 386 because it\'s the lowest common demoninator, so the virtualbox will run on any system capable of running virtualbox, but this works just as well for 64 bit architecture.</p>\r\n\r\n<p>Here we are at the command-line of a brand-new installation.&nbsp;To make a kernel with Yaffs you will need all the usual kernel-build tools for your distribution, the kernel source code, and the Yaffs source code.</p>\r\n\r\n<p>If you skipped the first video, you won\'t have seen how to download Yaffs. Here\'s a brief clip of retrieving a GPL licenced copy of the Yaffs source.</p>\r\n\r\n<p><strong>git clone git://www.aleph1.co.uk/yaffs2</strong><br />\r\n<strong>ls</strong></p>\r\n\r\n<p>We\'re starting off in the directory where I stored the kernel and Yaffs source.<br />\r\nThe next step isn\'t strictly necessary, but it\'s useful to if you are going to be doing development: I\'m going to make a branch for my changes to the kernel. Of course if you are using subversion, cvs or some other system for version control then you\'ll want to skip this step or replace it</p>\r\n\r\n<p>Let\'s list the branches<br />\r\n<strong>git branch</strong><br />\r\nOnly one makes it easy.<br />\r\n<strong>Git checkout master -b yaffs-demo-x86</strong><br />\r\nOkay, so we\'ve created a branch.<br />\r\n<strong>git branch</strong><br />\r\nAnd the star indicates that we are working in our new branch.<br />\r\nNow we have the kernel source, but we need to include Yaffs.<br />\r\nLuckily Yaffs comes with a script which automates the source changes necessary to include it.<br />\r\n<strong>cd ../yaffs</strong><br />\r\nIt\'s always a good idea to check the README file. Especially if you are doing this yourself.<br />\r\n<strong>less readme-linux.txt</strong><br />\r\nSo the script we use to patch the kernel is<br />\r\n<strong>./patch-ker.sh c m ~/kernel/source</strong><br />\r\nThe c tells the script to copy the changes rather than linking them, and the m indicates that we want the multiprocess option because more than one process might be using Yaffs at one time.</p>\r\n\r\n<p>Right, Yaffs has been patched into the kernel.&nbsp;Now we need to configure the kernel build.<br />\r\nBecause I\'m working on a virtual machine, I don\'t need to worry about different flavours of the kernel configuration. I can just go ahead and edit the default configuration.&nbsp;To avoid a long compile, I\'m going to remove pretty much all of the non-essential drivers, and most of the hardware – remember this is running on a virtual machine.<br />\r\n<strong>make menuconfig</strong><br />\r\nTo include Yaffs we need to enable two things.&nbsp;<br />\r\nThe memory technology device support (MTD) and the caching block device access for MTD.<br />\r\nThe MTD settings are in the Device drivers section. Usually it will be on. The caching should be on too.&nbsp;Once those are enabled, Yaffs becomes available as an optional file system.<br />\r\nGo into File systems, Miscellaneous and enable Yaffs.</p>\r\n\r\n<p>Here\'s a look at the various options.</p>\r\n\r\n<p>I\'ve set up Yaffs. Now I\'m going to go ahead and turn off all the things that I don\'t need in this kernel. There are a lot of them, and there\'s no need to watch hundreds of items being unticked.<br />\r\n...Skipping ahead....<br />\r\nOnce the config is suitable, we can exit and save.</p>\r\n\r\n<p>Okay, we\'re ready to build the kernel.&nbsp;Just to make sure that everything is fine..</p>\r\n\r\n<p><strong>fakeroot make-kpkg clean</strong></p>\r\n\r\n<p>and let\'s kick the build off</p>\r\n\r\n<p><strong>fakeroot make-kpkg –initrd –append-to-version=yaffs kernel-image</strong></p>\r\n\r\n<p>and now, since this is running on a uniprocessor virtual machine, I\'ll be going for some lunch. But there\'s no need for you to wait...</p>\r\n\r\n<p>So, the build is finished. It took about 1/2 hour. Your mileage will vary.</p>\r\n\r\n<p>We have a Debian package, and I\'m going to go ahead and install that.</p>\r\n\r\n<p><strong>sudo dpkg&nbsp;–install</strong></p>\r\n\r\n<p>We should have our new build in the grub.&nbsp;If we reboot, we’ll have Yaffs available.&nbsp;In the next video we’ll show you how to set up a Yaffs file system.&nbsp;You can download a copy of the virtual machine but you’ll need vagrant to use it. Details are on the&nbsp;site.</p>\r\n\r\n<p>Thanks for&nbsp;watching.</p>\r\n','<p>This video shows you how to compile Yaffs into Linux. It&rsquo;s just over 10 minutes long, and if you download it, it&rsquo;s&nbsp;325MB. After watching this video you should be able to include Yaffs in Linux.</p>','full_html'),('yaffs_user_logo',0,460,478,'und',0,'<p>Leica Geosystems products and services are trusted by professionals worldwide to help them capture, analyze, and present spatial information. Leica Geosystems is best known for its broad array of products that capture accurately, model quickly, analyze easily, and visualize and present spatial information.</p>\r\n\r\n<p>Leica Geosystems use Yaffs.</p>\r\n\r\n<p>&nbsp;</p>\r\n','Leica Geosystems products and services are trusted by professionals worldwide to help them capture, analyze, and present spatial information. Leica Geosystems is best known for its broad array of products that capture accurately, model quickly, analyze easily, and visualize and present spatial information.','basic_html'),('article',0,461,589,'und',0,'<p><strong>Draft Agreement Between Aleph One Limited and Licence-holder</strong></p>\r\n\r\n<p><strong>for the use of YAFFS1, YAFFS2 and YAFFS/direct</strong></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><strong>1. Definitions:</strong></p>\r\n\r\n<p>ALEPH ONE Ltd, a company registered in England and Wales, Number 1017960, having its Registered Office at The Old Courthouse, 123 High Street, Bottisham, CAMBRIDGE CB25 9BA UK</p>\r\n\r\n<p>LICENCE-HOLDER - The firm of Licence-holder having its administrative offices at</p>\r\n\r\n<p>SOURCE CODE - Code owned by Aleph One Ltd and supplied under this Licence</p>\r\n\r\n<p>BINARY CODE - Code which has been compiled from source code</p>\r\n\r\n<p>PRODUCT is To Be Agreed</p>\r\n\r\n<p>YAFFS FILESYSTEMS - any Filesystem Images made using YAFFS source code or YAFFS binary code</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><strong>2. The Licence:</strong></p>\r\n\r\n<p>Allows Licence-holder to use software of Aleph One Ltd to create the File System, FS and incorporate the FS in the defined product .</p>\r\n\r\n<p>Entitles Licence-holder to distribute binary code compiled from the source code provided.</p>\r\n\r\n<p>Does not entail any obligation to reveal the Binary code .</p>\r\n\r\n<p>Prohibits Licence-holder from releasing the source code to other parties, except to the extent necessary to permit sub-contractors to work with Licence-holder on a project using the code. Licence-holder is responsible for ensuring compliance with all the terms of this licence by any sub-contractor used.</p>\r\n\r\n<p>Is only available in a non-exclusive form.</p>\r\n\r\n<p>Is applicable worldwide.</p>\r\n\r\n<p>Has no time limit or per-unit royalty, but a fixed price paid at the time of signature as specified in Section 4 below.</p>\r\n\r\n<p>Applies to use of the FS only for the Product described in Section 1, rather than to a company/user/person. It cannot be transferred to another product .</p>\r\n\r\n<p>Provides the Source Code and any derived filesystems without any warranty but &gt;AS IS&lt; save that (to the best of Aleph One\'s knowledge) the use of the Source Code does not infringe the intellectual property rights of any third party.</p>\r\n\r\n<p><br />\r\n&nbsp;</p>\r\n\r\n<p><strong>3. Supporting information:</strong></p>\r\n\r\n<p>Aleph One Ltd supplies certain pieces of software, with different licences associated with them:</p>\r\n\r\n<p>~~ Source Code for YAFFS1, YAFFS2 and YAFFS/direct and Bootloader, being the subject of this Licence Agreement, for incorporation in a Product.</p>\r\n\r\n<p>~~ YAFFS Development Tools; images created with the tools may be incorporated into a Product. The images are not affected by the licence status of the Tools. When these Tool files are supplied in the tarball we send they will appear with a header saying they are used under the GNU Public Licence, GPL. That term applies only to the Tools; the other files in the tarball will have headers making clear they are used under a paid licence from Aleph One Ltd.</p>\r\n\r\n<p>~~ Access to all information on YAFFS published by Aleph One Ltd at http://www.yaffs.net</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>Source code modifications and enhancements made by Licence-holder remain the property of Licence-holder , but may not be redistributed or sold to third parties by Licence-holder without consent of Aleph One Ltd.</p>\r\n\r\n<p><br />\r\n&nbsp;</p>\r\n\r\n<p><strong>4. Price: </strong></p>\r\n\r\n<p>Ten Thousand Pounds Sterling, £10,000. payable at the time of signature of this licence.</p>\r\n\r\n<p>After payment for the Licence is received, Aleph One Ltd will provide a tarball with file headers showing the code is being used by the Licence-holder under a paid licence from Aleph One Ltd.</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><strong>Signed by:</strong></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>Laurence van Someren&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <em>Name</em></p>\r\n\r\n<p>Director&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <em>Position</em></p>\r\n\r\n<p>for Aleph One Limited&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for <em>Licence-holder</em></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>Date 2014 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Date 2014</p>\r\n\r\n<p>Version 23</p>\r\n\r\n<p>The following section does not form part of the Agreement:-</p>\r\n\r\n<p><em>We use a Licence Agreement written in English.&nbsp; We do not do this because English is our first language, but because English is the language understood by almost all our customers.&nbsp; We remain constantly aware&nbsp; of our good fortune in having it as a first language, and try to be sensitive to the needs of customers who use other languages more easily.</em></p>\r\n\r\n<p><br />\r\n&nbsp;</p>\r\n\r\n<p>&nbsp;</p>\r\n','<p>An example of the framework Licence Agreement showing the necessary elements and open to negotiation</p>','basic_html'),('page',0,462,590,'und',0,'<h3>What sorts of licence are there?</h3>\r\n\r\n<p>There are two; GNU General Public Licence version 2, and Paid licences.<br />\r\nAnyone can take our Yaffs file system from http://www.yaffs.net&nbsp; free of charge; you can work and play with and test the code as much as you like, and make sure it suits your purposes. You will be doing so under the well known GNU GPL, described in detail at http://www.gnu.org/licenses/old-licenses/gpl-2.0.html</p>\r\n\r\n<h3>That sounds great! Why should I want a paid licence?</h3>\r\n\r\n<p>The GPL obliges you to release all associated code of your own that you use with any GPL software to anyone who asks for it.&nbsp; If you do not wish to release your own code, then you can buy a Licence from Aleph One Ltd which does not have that obligation.</p>\r\n\r\n<h3>What sorts of systems use Yaffs?</h3>\r\n\r\n<p>There is a wide range including GPS equipment for surveyors, sewing machines, traffic control equipment, Point-of-Sale tills, Set-Top-Boxes, DVD writers, high-end video-filming equipment and so on and on - including Android telephones!&nbsp; These have provided a very large test-bed for Yaffs, and of course they use it under GPL since Android is an Open Source project.</p>\r\n\r\n<h3>Who uses Yaffs now?</h3>\r\n\r\n<p>The Yaffs.net Home page shows (at its foot) the logos of some of the users, but the range is much wider than those displayed there.&nbsp; They tend to have in common a need for great confidence in the robustness of the FS in demanding circumstances like heavy work, accumulated cell-failures, and random power failures.&nbsp; A number of them have bought more than one Licence at different times because they know it works!</p>\r\n\r\n<h3>What are the terms of the paid licences like?</h3>\r\n\r\n<p>All Yaffs licences from Aleph One are non-exclusive, worldwide, perpetual, irrevocable and free of any royalty; they are paid for once when an agreement is signed, and they apply only to the one or more products specified at the time of the agreement.</p>\r\n\r\n<h3>What do we do next?</h3>\r\n\r\n<p>Tell us some more about the product you will use Yaffs in.&nbsp; We like the Agreement to contain a brief description of the hardware involved and the part number or product name and any internal code name.&nbsp; If you want us to sign a Non-Disclosure Agreement before you give us these details, send it to us; we are used to signing them.&nbsp; We can send you a standard form if you do not have one.<br />\r\nThen we will send a draft Agreement and price to you, and negotiate until we are both satisfied.&nbsp; Next we each sign and exchange copies of the Agreement and you pay us.</p>\r\n\r\n<h3>How does that help us?</h3>\r\n\r\n<p>After you pay for a Licence you get a tarball of files to put in your product which make clear in the file headers that you are using Yaffs under a licence from Aleph One Ltd.&nbsp; That makes a paid licence different from a GNU General Public Licence.&nbsp; We can do that because Aleph One Ltd owns Yaffs completely.<br />\r\nIts other virtues are that it handles different page sizes and large numbers of files, and it is economical on other resources such as RAM.&nbsp; Like everyone else, Licence Holders have access to the continuing improvements which are being made in Yaffs.</p>\r\n\r\n<h3>What about the OS?</h3>\r\n\r\n<p>Yaffs is agnostic about the OS it is used with.&nbsp; While many users combine it with Linux, it has been used with 32-bit and 64-bit OSs and with no OS at all.&nbsp; Cases such as VxWorks and WinCE are a bit more complex.&nbsp; We have done work on a wrapper to make it easier to use Yaffs with WinCE.&nbsp; We are working on making Yaffs easy to use with VxWorks too; let us know if you are interested in the resuults.&nbsp;<br />\r\nThe relationship between the OS and the rest of Yaffs is illustrated in the diagram on the Home Page.&nbsp; At the heart of Yaffs is the Yaffs Direct Interface, which is a well-documented sub-set of Yaffs.&nbsp; Click on it in the diagram for more information.</p>\r\n\r\n<h3>How does this relate to the GPL?</h3>\r\n\r\n<p>The point of GNU General Public Licence v2 is to share work to improve Open Source software for the common good.&nbsp; A huge amount of development takes place quietly and out of the public eye, and it is released into the common pool of software so others can both benefit from it and contribute to it.<br />\r\nOpen Source software is transparent to all who use it, and its development therefore requires sharing your contributions with anyone else who wants them.&nbsp; The GPL was devised to make this possible.&nbsp; It also makes perfectly clear that the open source code is supplied AS IS and without any warranty. This shields developers and contributors from litigators who want to blame them for a fault.<br />\r\nOne user of Yaffs makes seismic monitoring equipment capable of detecting underground nuclear explosions; they require Open Source software.</p>\r\n\r\n<h3>How does the LGPL bear on all of this?</h3>\r\n\r\n<p>Because Bootloaders are often proprietary we provide with Yaffs a few kBytes of bootloader code which is licensed under LGPL, the GNU Lesser Public Licence, rather than under GPL.&nbsp; This avoids the risk of what proprietary code owners often describe as contamination of their code by code useful to Yaffs.<br />\r\nThe LGPL is shown at&nbsp; http://www.gnu.org/licenses/lgpl.html&nbsp; The tarball with modified headers you get from us will have your name only in the Yaffs file headers and not in the headers of tools such as the bootloader.&nbsp; This practice is common in the Open Source world.</p>\r\n\r\n<h3>How much does a licence from Aleph One cost?</h3>\r\n\r\n<p>The price depends a bit on the sort of market you are working in; a firm making industrial control equipment or office copiers pays a base price, but a mobile phone maker pays more.&nbsp; The base price is GBP10k. Note that is not US$ but GB Pounds Sterling.</p>\r\n\r\n<p><br />\r\nApril 2015</p>\r\n\r\n<p><br />\r\n<br />\r\n<br />\r\n<br />\r\n<br />\r\n&nbsp;</p>\r\n','<p>More on the details and background of Licences for Yaffs</p>','basic_html'),('paper',0,466,611,'und',0,'	<p class=\"western\">We have been developing flash file system for\r\n	embedded systems since 1995. During that time, we have gained a\r\n	wealth of knowledge and experience.</p>\r\n	<p class=\"western\">This document outlines some of the major issues\r\n	that must be considered when selecting a Flash File system for\r\n	embedded use. It also explains how using the Yaffs File System\r\n	increases reliability, reduces risk and saves money.</p>\r\n\r\n</p>\r\n<h1 class=\"western\" style=\"page-break-before: always\">Introduction</h1>\r\n<p class=\"western\" align=\"left\">As embedded system complexity\r\nincreases and flash storage prices decrease, we see more use of\r\nembedded file systems to store data, and so data corruption and loss\r\nhas become an important cause of system failure.</p>\r\n<p class=\"western\" align=\"left\">When Aleph One began the development\r\nof Yaffs in late 2001, we built on experience in flash file system\r\ndesign since 1995. This experience helped to identify the key factors\r\nin making Yaffs a fast and robust flash file system now being widely\r\nused around the world.</p>\r\n<p class=\"western\" align=\"left\">Although it was originally developed\r\nfor Linux, Yaffs was designed to be highly portable. This has allowed\r\nYaffs to be ported to many different OSs (including Linux, BSD,\r\nWindows CE) and numerous RTOSs (including VxWorks, eCos and pSOS).</p>\r\n<p class=\"western\" align=\"left\">Yaffs is written in fully portable C\r\ncode and has been used on many different CPU architectures – both\r\nlittle- and big-endian. These include ARM, x86 and PowerPC, soft\r\ncores such as NIOS and Microblaze and even various DSP architectures.</p>\r\n<p class=\"western\" align=\"left\">We believe that the Yaffs code base\r\nhas been used on more OS types and more CPU types than any other file\r\nsystem code base.</p>\r\n<p class=\"western\" align=\"left\">Since its introduction, Yaffs has\r\nbeen used in hundreds of different products and hundreds of millions\r\nof different devices in widely diverse application areas from mining\r\nto aerospace and everything in between.</p>\r\n<p class=\"western\" align=\"left\">Specific examples include:</p>\r\n<ul>\r\n	<li/>\r\n<p class=\"western\" align=\"left\">communications (two-way radios\r\n	and infrastructure, mobile phones, cell towers, modems, routers...)</p>\r\n	<li/>\r\n<p class=\"western\" align=\"left\">retail (point of sale,\r\n	inventory control...)</p>\r\n	<li/>\r\n<p class=\"western\" align=\"left\">entertaiment (video cameras,\r\n	TV sets, DVD players, set-top boxes...)</p>\r\n	<li/>\r\n<p class=\"western\" align=\"left\">sewing machines and office\r\n	copiers</p>\r\n	<li/>\r\n<p class=\"western\" align=\"left\">industrial equipment (PLCs,\r\n	machinery control...)</p>\r\n	<li/>\r\n<p class=\"western\" align=\"left\">construction/surveying\r\n	equipment (theodolites, machinery control...)</p>\r\n	<li/>\r\n<p class=\"western\" align=\"left\">avionics and satellite\r\n	equipment</p>\r\n	<li/>\r\n<p class=\"western\" align=\"left\">transport (bus, train and\r\n	traffic-signal management/information systems...)</p>\r\n	<li/>\r\n<p class=\"western\" align=\"left\">and many more.</p>\r\n</ul>\r\n<p class=\"western\" align=\"left\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\" align=\"center\"><i><b>You may be using Yaffs every\r\nday without even realising it.</b></i></p>\r\n<p class=\"western\" align=\"center\"><i><b>We have a gratifying number\r\nof repeat customers for licences.</b></i></p>\r\n<h1 class=\"western\"><br/>\r\n<br/>\r\n\r\n</h1>\r\n<h1 class=\"western\" style=\"page-break-before: always\">Do Embedded\r\nSystems have different file system needs?</h1>\r\n<p class=\"western\">To answer this question, we really have to start\r\nby asking a slightly different question:</p>\r\n<p class=\"western\" align=\"center\"><i>How are embedded systems\r\ndifferent than regular computers?</i></p>\r\n<p class=\"western\" align=\"justify\" style=\"font-style: normal\">When a\r\ncustomer buys a regular computer system, they go shopping for a\r\ncomputer. They talk to the salesperson about Gigabytes, Megahertz and\r\noperating systems. They treat it as a computer and expect it to\r\nbehave like a computer (including shutting it down properly and\r\noccasionally having file system problems or needing upgrades).</p>\r\n<p class=\"western\" align=\"justify\" style=\"font-style: normal\">When\r\nthey buy a fancy sewing machine, it probably has an embedded file\r\nsystem controlling it. The customer went shopping for a sewing\r\nmachine and bought a computer that they don\'t even know about. They\r\ndon\'t treat it like a computer, but like a sewing machine; they\r\ncertainly do not expect it to have file system problems.</p>\r\n<h4 class=\"western\">How people treat computers differently from\r\nembedded systems</h4>\r\n<table width=\"100%\" cellpadding=\"4\" cellspacing=\"0\" style=\"page-break-inside: avoid\">\r\n	<col width=\"85*\">\r\n	<col width=\"85*\">\r\n	<col width=\"85*\">\r\n	<tr valign=\"top\">\r\n		<td width=\"33%\" style=\"border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0.1cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\" align=\"left\"><font size=\"2\" style=\"font-size: 11pt\"><b>Issue</b></font></p>\r\n		</td>\r\n		<td width=\"33%\" style=\"border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0.1cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\" align=\"left\"><font size=\"2\" style=\"font-size: 11pt\"><b>Computer</b></font></p>\r\n		</td>\r\n		<td width=\"33%\" style=\"border: 1px solid #000000; padding: 0.1cm\">\r\n			<p class=\"western\" align=\"left\"><font size=\"2\" style=\"font-size: 11pt\"><b>Embedded\r\n			system</b></font></p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"33%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\" align=\"left\"><font size=\"2\" style=\"font-size: 11pt\">Shut\r\n			down</font></p>\r\n		</td>\r\n		<td width=\"33%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\" align=\"left\"><font size=\"2\" style=\"font-size: 11pt\">User\r\n			expects to do a clean shut down.</font></p>\r\n		</td>\r\n		<td width=\"33%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\" align=\"left\"><font size=\"2\" style=\"font-size: 11pt\">User\r\n			just unplugs device.</font></p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"33%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\" align=\"left\"><font size=\"2\" style=\"font-size: 11pt\">Reinstalling\r\n			software</font></p>\r\n		</td>\r\n		<td width=\"33%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\" align=\"left\"><font size=\"2\" style=\"font-size: 11pt\">Users\r\n			expect to have to deal with corruption and reinstall software\r\n			occasionally.</font></p>\r\n		</td>\r\n		<td width=\"33%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\" align=\"left\"><font size=\"2\" style=\"font-size: 11pt\">Users\r\n			do not expect to deal with upgrades or data loss or corruption.</font></p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"33%\" height=\"11\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\" align=\"left\"><font size=\"2\" style=\"font-size: 11pt\">Software\r\n			Upgrade Failure</font></p>\r\n		</td>\r\n		<td width=\"33%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\" align=\"left\"><font size=\"2\" style=\"font-size: 11pt\">Annoying</font></p>\r\n		</td>\r\n		<td width=\"33%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\" align=\"left\"><font size=\"2\" style=\"font-size: 11pt\">Can\r\n			be devastating</font></p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"33%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\" align=\"left\"><font size=\"2\" style=\"font-size: 11pt\">Attitude\r\n			to data loss</font></p>\r\n		</td>\r\n		<td width=\"33%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\" align=\"left\"><font size=\"2\" style=\"font-size: 11pt\">Annoying,\r\n			but expected</font></p>\r\n		</td>\r\n		<td width=\"33%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\" align=\"left\"><font size=\"2\" style=\"font-size: 11pt\">System\r\n			has failed.</font></p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"33%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\" align=\"left\"><font size=\"2\" style=\"font-size: 11pt\">Cost\r\n			of failure</font></p>\r\n		</td>\r\n		<td width=\"33%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\" align=\"left\"><font size=\"2\" style=\"font-size: 11pt\">Relatively\r\n			minor</font></p>\r\n		</td>\r\n		<td width=\"33%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\" align=\"left\"><font size=\"2\" style=\"font-size: 11pt\">Can\r\n			shut down factory or even cause injury/death.</font></p>\r\n		</td>\r\n	</tr>\r\n	<tr valign=\"top\">\r\n		<td width=\"33%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\" align=\"left\"><font size=\"2\" style=\"font-size: 11pt\">Delayed\r\n			boot due to file system recovery</font></p>\r\n		</td>\r\n		<td width=\"33%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: none; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0cm\">\r\n			<p class=\"western\" align=\"left\"><font size=\"2\" style=\"font-size: 11pt\">Annoying,\r\n			but expected.</font></p>\r\n		</td>\r\n		<td width=\"33%\" style=\"border-top: none; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000; padding-top: 0cm; padding-bottom: 0.1cm; padding-left: 0.1cm; padding-right: 0.1cm\">\r\n			<p class=\"western\" align=\"left\"><font size=\"2\" style=\"font-size: 11pt\">This\r\n			is as bad as a failure.</font></p>\r\n		</td>\r\n	</tr>\r\n</table>\r\n<p class=\"western\" align=\"left\" style=\"font-style: normal\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\" align=\"justify\">So people have different attitudes\r\nto computers and embedded systems. As a result, embedded systems need\r\nto be designed differently from computers. That is particularly\r\nimportant with reliability issues.</p>\r\n<p class=\"western\" align=\"center\" style=\"margin-bottom: 0.01cm\"><i><b>Data\r\ncorruption is a leading cause of embedded system failure, </b></i>\r\n</p>\r\n<p class=\"western\" align=\"center\" style=\"margin-bottom: 0.01cm\"><i><b>product\r\nreturns and warranty costs.</b></i> \r\n</p>\r\n<p class=\"western\" align=\"center\" style=\"margin-bottom: 0.01cm\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\" align=\"justify\">The differences outlined above\r\nshow some of the reasons why embedded systems must perform\r\ndifferently to regular computers, particularly in the way data\r\nstorage is handled. These examples allow us to identify some very\r\nimportant product-level criteria for embedded file systems:</p>\r\n<ul>\r\n	<li/>\r\n<p class=\"western\" align=\"left\">High resilience against data\r\n	corruption, particularly in the event of power loss.</p>\r\n	<li/>\r\n<p class=\"western\" align=\"left\">Prompt file system recovery\r\n	after power loss - no excessive time penalty</p>\r\n	<li/>\r\n<p class=\"western\" align=\"left\">Simple data integrity model to\r\n	ensure data is not compromised.</p>\r\n</ul>\r\n<p class=\"western\" align=\"left\">Of course we also want the embedded\r\nfile system to have some other very useful features:</p>\r\n<ul>\r\n	<li/>\r\n<p class=\"western\" align=\"left\">High read/write performance\r\n	with low latency.</p>\r\n	<li/>\r\n<p class=\"western\" align=\"left\">Familiar programming models to\r\n	facilitate development.</p>\r\n	<li/>\r\n<p class=\"western\" align=\"left\">Proven track record to reduce\r\n	risk.</p>\r\n	<li/>\r\n<p class=\"western\" align=\"left\">Full source code access to aid\r\n	development.</p>\r\n	<li/>\r\n<p class=\"western\" align=\"left\">Portability to provide a\r\n	future-proof solution for new products.</p>\r\n</ul>\r\n<p class=\"western\" align=\"center\"><i><b>Selecting an appropriate file\r\nsystem is crucial to product success.</b></i></p>\r\n<h1 class=\"western\" style=\"page-break-before: always\">Why does power\r\nfailure corrupt data?</h1>\r\n<p class=\"western\">Most power fail data loss in a File System is\r\ncaused through two mechanisms:</p>\r\n<ul>\r\n	<li/>\r\n<p class=\"western\">Corruption of allocation tables \r\n	</p>\r\n	<li/>\r\n<p class=\"western\">Loss of cached data that was not yet\r\n	written to the flash.</p>\r\n</ul>\r\n<h2 class=\"western\">Corruption of allocation tables and similar\r\nstructures.</h2>\r\n<p class=\"western\">Most file systems have allocation tables, bitmaps\r\nor similar structures which hold pointers showing which parts of the\r\nfile storage medium are being used and which parts of which file are\r\nstored there. These tables are critical to looking up files and data\r\nin the file system. If they are corrupted, then files and data become\r\ncorrupted. In the most dramatic cases, table corruption can destroy\r\nthe whole system.  \r\n</p>\r\n<p class=\"western\">Some file systems make these tables more robust by\r\nkeeping two copies, or by using journaling (which keeps a short log\r\nof changes, allowing the tables to be fixed up if the table changing\r\ngets interrupted) but this causes extra writes to the media, making\r\nthe file system slower.</p>\r\n<p class=\"western\">These tables are typically updated many times\r\nduring writing any file, so there are multiple opportunities for the\r\ntables to be corrupted or left in an inconsistent state due to a\r\npower loss.</p>\r\n<p class=\"western\">If power is interrupted at a critical point, then\r\nsome restoration (such as Microsoft chkdsk or booting in <span style=\"font-style: normal\">safe\r\nmode</span>) is often required to try to restore the tables. This may\r\nbe automatic, but then system start-up is delayed.</p>\r\n<p class=\"western\">Yaffs is very different; it is a log structured\r\nfile system which writes tagged data to the flash, and does not store\r\nallocation tables or such.</p>\r\n<p class=\"western\" align=\"center\"><i><b>If it isn\'t even stored, it\r\ncan\'t be corrupted!</b></i></p>\r\n<p class=\"western\">This has three dramatic effects:</p>\r\n<ul>\r\n	<li/>\r\n<p class=\"western\">Yaffs has no tables, so is immune to these\r\n	failure modes.</p>\r\n	<li/>\r\n<p class=\"western\">There are no extra tables to be written, so\r\n	Yaffs does not have to resort to caching to achieve good\r\n	performance.</p>\r\n	<li/>\r\n<p class=\"western\">Less flash writes means less flash wear,\r\n	improving product life and reducing power consumption.</p>\r\n</ul>\r\n<p class=\"western\">When a Yaffs file system is booted, the normal\r\nboot up sequence takes care of building up system state. There is\r\nthus no need for any special restoration code to be run. A boot up\r\nafter a power failure is not a special recovery condition, it is just\r\na normal boot up.</p>\r\n<p class=\"western\" align=\"center\"><i><b>Yaffs does not have, or need,\r\nspecial recovery handling.</b></i></p>\r\n<h2 class=\"western\" style=\"page-break-after: avoid\"><font face=\"Liberation Sans, sans-serif\"><i><b>Trade-off\r\nin cached data</b></i></font></h2>\r\n<p class=\"western\"><font face=\"Liberation Sans, sans-serif\"><font size=\"2\" style=\"font-size: 11pt\">File\r\nsystems tend to be inefficient in the way they write data.  Writing\r\njust one file requires many changes to the allocation tables; writing\r\nmany files requires far more changes, often to those same tables. By\r\ndelaying those writes and holding data in RAM briefly the file system\r\ncan do fewer writes to achieve the same set of changes. This can\r\nimprove write speed, at a price.</font></font></p>\r\n<p class=\"western\"><font face=\"Liberation Sans, sans-serif\"><font size=\"2\" style=\"font-size: 11pt\">Data\r\nwhich has not been written but just cached in RAM is vulnerable while\r\nit is there; it can all be lost if power fails, even including some\r\nthat the FS had apparently written already.</font></font></p>\r\n<p class=\"western\"><font face=\"Liberation Sans, sans-serif\"><font size=\"2\" style=\"font-size: 11pt\">Most\r\nfile systems support functions to reduce this inefficiency and force\r\nthe cache to be written out, but this may take many seconds, leaving\r\na significant period of vulnerability, and delaying system\r\noperations.  Excessive use of these functions to improve reliability\r\nwill typically impair write performance.</font></font></p>\r\n<p class=\"western\"><font face=\"Liberation Sans, sans-serif\"><font size=\"2\" style=\"font-size: 11pt\">A\r\nparticlarly serious example of critical data loss can occur if power\r\nor communication fails during a firmware upgrade.  Such a failure\r\ncripples the product, which must be returned for servicing.  Yaffs\r\nhas caching policies and data integrity models which make it easier\r\nto avoid this kind of fatal failure, and which have been tested very\r\nextensively. </font></font>\r\n</p>\r\n<p class=\"western\"><font face=\"Liberation Sans, sans-serif\"><font size=\"2\" style=\"font-size: 11pt\">Since\r\nYaffs is inherently faster and simpler, it does not need deep\r\ncaching. The Yaffs cache is small and used only for data alignment\r\npurposes and improving the throughput of very small reads and writes.\r\nYaffs files are always flushed from the cache when they are closed.\r\nYaffs also provides its own cache-flushing functions, but these are\r\nvery fast because the cache is small.</font></font></p>\r\n<p class=\"western\" align=\"center\"><font face=\"Liberation Sans, sans-serif\"><font size=\"2\" style=\"font-size: 11pt\"><i><b>By\r\nthe time Yaffs closes a file, all the data is guaranteed to be safe\r\non the flash.</b></i></font></font></p>\r\n<p class=\"western\"><font face=\"Liberation Sans, sans-serif\"><font size=\"2\" style=\"font-size: 11pt\">This\r\nsimple caching policy makes it very easy for programmers to write\r\nsoftware that is robust against power loss and avoids obscure failure\r\nmodes.  The simplicity confers more reliable operation, faster\r\nproduct development and huge savings in development and maintenance\r\ncosts.</font></font></p>\r\n<p class=\"western\" align=\"center\"><font face=\"Liberation Sans, sans-serif\"><font size=\"2\" style=\"font-size: 11pt\"><i><b>Reliable\r\nfile systems pay for themselves many times over.</b></i></font></font></p>\r\n<h1 class=\"western\" style=\"page-break-before: always\">Product risk\r\nreduction</h1>\r\n<p class=\"western\">At first glance, a file system seems like it\r\nshould be a simple body of code: just a few functions that read,\r\nwrite data and look things up by name. However, the reality is much\r\nmore complex than that.</p>\r\n<p class=\"western\">One of the most challenging aspects of file\r\nsystems is that errors are stored and incremental. Unlike most\r\nsoftware errors which can be cleared by a reset, storage errors are\r\npersistent.</p>\r\n<p class=\"western\" align=\"center\"><i><b>A reboot will typically not\r\nfix file-system errors.</b></i></p>\r\n<p class=\"western\">Customers might tolerate a product that needs to\r\nbe reset once in a while, but file system failures are often fatal.\r\nAs a result, file system issues can be very damaging to long-term\r\nproduct reliability.</p>\r\n<p class=\"western\">This is further complicated by flash memory. NAND\r\nflash is the only type of semiconductor hardware which leaves the\r\nfactory with known variable errors, expecting the file system\r\nsoftware to handle the problems.</p>\r\n<p class=\"western\">Flash, NAND in particular, has its own failure\r\nmodes and these are best handled by a file system specifically\r\ndesigned for NAND.</p>\r\n<p class=\"western\" align=\"center\"><i><b>Yaffs was specifically\r\ndesigned to use with NAND and NOR flash chips.</b></i></p>\r\n<p class=\"western\">Flash memory chip errors may only show up after\r\nthe product has been used a while, or in a fraction of the flash\r\nparts. Typical testing during development (e.g. bench testing) will\r\noften fail to expose all types of flash chip error, and others will\r\nonly be exposed during pilot- or early-production. These put release\r\ndates at risk, which can cause huge revenue losses.</p>\r\n<p class=\"western\">We have a few clients who only determined that\r\nthey had file system issues when they did a pilot run. That prompted\r\nthem to try Yaffs and get their products shipping. While we are glad \r\nthey ended up with a good product, unfortunately they lost revenue\r\nand customer goodwill.</p>\r\n<p class=\"western\" align=\"center\"><i><b>Finding problems late in\r\ndevelopment creates business risk.</b></i></p>\r\n<p class=\"western\">It is thus not surprising that much of our\r\nbusiness is repeat business. \r\n</p>\r\n<h1 class=\"western\" style=\"page-break-before: always\">Yaffs testing</h1>\r\n<p class=\"western\">Testing on its own does not create good software\r\nbut it does help to verify that the software is working correctly.</p>\r\n<p class=\"western\">Yaffs has many automated tests that are run on a\r\nregular basis. Automated tests allow the testing to be run without\r\nhuman intervention, thus allowing more testing to be done.</p>\r\n<p class=\"western\">The tests are too numerous to discuss completely\r\n(see the Further Information below). W<span style=\"font-weight: normal\">e</span>\r\nhighlight one: the power-fail stress test.</p>\r\n<p class=\"western\">The power-fail stress test is a test harness that\r\nuses software simulations of flash devices and some software and\r\nscripts to simulate the effects of removing power from a Yaffs-based\r\nsystem <span style=\"font-weight: normal\">while it is writing</span>\r\nto flash. This test is normally run for 100,0000 to 1 million\r\npower-fail simulation cycles, taking many days.</p>\r\n<p class=\"western\">This particular test suite was originally\r\ndeveloped in 2008 during the development of some new features. The\r\ntests are very rigorous. In the beginning, this test suite would find\r\na problem after less than 100 power fail iterations. As we identified\r\nand fixed the bugs, this number crept up and we now run millions of\r\ncycles without seeing a single problem.</p>\r\n<p class=\"western\" align=\"center\"><i><b>Yaffs survives millions of\r\npower failures in simulation test benches.</b></i></p>\r\n<p class=\"western\">In addition, many of our clients have also run\r\nhardware power failure tests, using a relay and a micro-controller to\r\nkill power to the device under test.  They have been very satisfied\r\nwith the results.</p>\r\n<p class=\"western\" align=\"left\" style=\"margin-bottom: 0cm; orphans: 0; widows: 0; page-break-before: auto\">\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\"><font size=\"4\" style=\"font-size: 16pt\"><b>Licensing</b></font></p>\r\n<p class=\"western\">Yaffs is available under GNU Public License V2,\r\nGPL2, from our git repository at <a href=\"http://www.yaffs.net/\">www.yaffs.net</a>.\r\nYou may use that code for testing free of charge and for as long as\r\nyou want.</p>\r\n<p class=\"western\" align=\"left\" style=\"font-weight: normal\"><i>You\r\nwill be using it under the conditions of GPL2 with the obligation to\r\nrelease your associated source code when you start to sell or\r\ndistribute a product.</i></p>\r\n<p class=\"western\" align=\"left\" style=\"font-weight: normal\"><i>We can\r\nthen sell you a Licence to use Yaffs which removes that obligation\r\nand protects your intellectual property.</i></p>\r\n<p class=\"western\" align=\"center\"><i><b>With Yaffs you can try before\r\nyou buy!</b></i></p>\r\n<h1 class=\"western\">Conclusions</h1>\r\n<p class=\"western\">Selecting a robust flash file system is key to :</p>\r\n<ul>\r\n	<li/>\r\n<p class=\"western\">building a successful product.</p>\r\n	<li/>\r\n<p class=\"western\">reducing risk, warranty costs and\r\n	liability.</p>\r\n	<li/>\r\n<p class=\"western\">reducing development costs.</p>\r\n</ul>\r\n<p class=\"western\" align=\"center\"><i><b>Yaffs has proven itself and\r\ncan pay for itself many times over.</b></i></p>\r\n<h1 class=\"western\">Further information</h1>\r\n<p class=\"western\">This document is intentionally brief. There are\r\nmany documents at <a href=\"http://www.yaffs.net/\">http://www.yaffs.net</a>\r\nfor those that want more information, including:</p>\r\n<p class=\"western\"><b>How Yaffs Works:</b> detailed description of\r\ninternal design.</p>\r\n<p class=\"western\"><b>Yaffs Robustness and Testing:</b> how  we know\r\nYaffs handles various flash failure scenarios.</p>\r\n<p class=\"western\"><br/>\r\n<br/>\r\n\r\n</p>\r\n<p class=\"western\">For further information please contact\r\n<a href=\"mailto:info@yaffs.net\">info@yaffs.net</a> or access\r\n<a href=\"http://www.yaffs.net/\">http://www.yaffs.net</a></p>','Failures in an embedded File System in a product are much more serious to the user than failures in an office computer.&nbsp; Power failures and failures to cache data properly can be avoided by choosing a FFS specifically designed for reliability from the ground up.','raw_html'),('paper',0,479,592,'und',0,'<p>The source and the definitive version of this document can be found in our git repository,&nbsp;<a href=\"http://www.aleph1.co.uk/gitweb/?p=yaffs-docs;a=tree;h=f4fcbdc9da052aa926c4bc2275547ca310eebbd8;hb=9d50c62a1c24f1b9dd00ec3eb6d0bddff0aed17d\">together with other Yaffs documents</a>.</p>\r\n\r\n<h2>1 Background</h2>\r\n\r\n<p>The purpose of this document is to describe the Yaffs-for-VxWorks wrapper as well as provide sufficient information to port Yaffs to the VxWorks BSP. This document assumes a working knowledge of VxWorks.</p>\r\n\r\n<p>This document does not describe the inner workings of Yaffs and a study of other Yaffs documents is recommended. Documents shown below in <em>italics</em> are available at <em>http://www.yaffs.net/documents...</em></p>\r\n\r\n<h2>2 Licensing</h2>\r\n\r\n<p>Yaffs was originally released for Linux under the GNU Public License (GPL). Various embedded developers soon identified that Yaffs would be ideal for their applications, but were not able to use GPL based code in their systems. Aleph One Ltd has alternative licensing arrangements to support such applications.</p>\r\n\r\n<p>Since VxWorks is proprietary code that is incompatible with GPL, alternative licensing arrangements must be sought to use Yaffs with VxWorks or most other embedded RTOSs.</p>\r\n\r\n<h2>3 What are Yaffs and Yaffs Direct Interface?</h2>\r\n\r\n<p>Yaffs stands for Yet Another Flash File System and was the first file system designed from the ground up for NAND flash storage.</p>\r\n\r\n<p>In 2002 Aleph One set out to identify file system options for using NAND Flash as a file system. Various file systems available at the time were evaluated and all were found lacking in one way or another. The need for a suitable NAND storage file system was identified and Yaffs was designed to fill that need.</p>\r\n\r\n<p>Although Yaffs was originally designed for NAND flash, it has been used successfully with NOR flash systems and even as a RAM file system. This allows high reliability file systems to be constructed using NOR flash, with a future migration path to NAND flash for higher density and performance.</p>\r\n\r\n<p>Yaffs was originally designed for use with the Linux operating system, but was designed in a very modular way. The operating-system-specific code was kept separate from the main Yaffs file system code. This allows Yaffs to be ported quite cleanly to other operating systems through operating system personality modules. One such personality module is the Yaffs Direct Interface (YDI) which allows Yaffs to be simply integrated with embedded systems, with or without an RTOS. See http://www.yaffs.net/documents/yaffs-direct-interface</p>\r\n\r\n<p>The current version is Yaffs2, which supports a wider range of NAND flash components including 2k/4k/8k or even 16k page devices and devices with multi-level cells (MLC), and produces equivalent or better performance. Yaffs2 include Yaffs1 compatibility code so Yaffs1 images still work and migration is quite simple. Yaffs1 or Yaffs2 mode of operation are simply selected by a run-time parameter.</p>\r\n\r\n<p>As well as providing a NAND file system, YDI also provides a RAM emulation layer to allow Yaffs to operate as a RAM file system too. While the RAM emulation is perhaps not as efficient as a dedicated RAM file system, this does allow one well proven file system to use both RAM and flash.</p>\r\n\r\n<p>Yaffs has been used for many products using various operating systems including Windows Embedded Compact (previously called Windows CE) and various RTOSs, including ThreadX, vXworks, pSOS to name just a few. Note that there is a native port of Yaffs to eCOS that does not use YDI. This is supported and distributed by eCocCentric.(http://www.ecoscentric.com/).</p>\r\n\r\n<h2>4 Why use Yaffs?</h2>\r\n\r\n<p>For an in depth understanding of the advantages of Yaffs, please read <em>http://www.yaffs.net/documents/considerations-choosing-flash-file-system</em></p>\r\n\r\n<p>For a brief overview: 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>\r\n\r\n<p>Some features to consider:</p>\r\n\r\n<ul>\r\n	<li>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.</li>\r\n	<li>Yaffs is written in portable C and is endian neutral.</li>\r\n	<li>Yaffs provides bad block handling and ECC algorithms to handle deficiencies in NAND flash.</li>\r\n	<li>Yaffs is a log-structured file system which makes it very robust to corruptions caused by power failures etc.</li>\r\n	<li>Yaffs has highly optimised and predictable garbage collection strategies. This makes it high performance and very deterministic when compared with similar file systems.</li>\r\n	<li>Yaffs has a lower memory footprint than most other log-structured flash file systems.</li>\r\n	<li>Yaffs provides a wide range of POSIX-style file system support including directories, symbolic and hard links etc. through standard file system interface calls.</li>\r\n	<li>Yaffs is highly configurable to work with various flash geometries, various ECC options, caching options etc.</li>\r\n	<li>Yaffs Direct Interface is simple to integrate in a system – only a few interface functions are required.</li>\r\n	<li>Yaffs can be used with a wide range of memory technologies.</li>\r\n</ul>\r\n\r\n<h2>5 What is Yaffs -for-VxWorks?</h2>\r\n\r\n<p>Many organizations have used Yaffs on VxWorks with just Yaffs Direct Interface (YDI). So what benefit does Yaffs-for-VxWorks offer?</p>\r\n\r\n<p>YDI provides a POSIX-like API, but with Yaffs specific names. For example: yaffs_open(), yaffs_read(), yaffs_close() etc.</p>\r\n\r\n<p>While YDI provides a solution for many systems, and is very well proven, it has one major drawback. It is not a native file system. That means:</p>\r\n\r\n<ul>\r\n	<li>Existing code that calls open(), read(), write() etc cannot be immediately used with YDI. The code needs to be rewritten to call the YDI functions: yaffs_open(), yaffs_read()... This porting is costly and error prone.</li>\r\n	<li>Code written for YDI is then locked to Yaffs and makes portability/testability problems.</li>\r\n	<li>Tools such as the VxWorks console shell cannot be used to access Yaffs files via YDI.</li>\r\n</ul>\r\n\r\n<p>Yaffs-for-VxWorks fixes these limitations..</p>\r\n\r\n<p>Yaffs-for-VxWorks is a wrapper around YDI that plugs YDI in as a native file system (ie. Yaffs becomes a file system that is accessed no different from any of the other file systems on system. This makes it really easy to migrate existing VxWorks software, or develop new VxWorks software to get the benefits of Yaffs.</p>\r\n\r\n<p>Yaffs-for-VxWorks follows the VxWorks operating system model used by other VxWorks file systems, so it is easy for VxWorks developers to integrate Yaffs and integrate it with their normal workflow.</p>\r\n\r\n<p>As mentioned above, Yaffs-for-VxWorks is a wrapped version of YDI. That means all the testing and experience of using YDI since 2002 is incorporated into Yaffs-for-VxWorks.</p>\r\n\r\n<p>Yaffs is already supported in u-boot, so if you\'re using u-boot as a boot loader then there is already seamless support for Yaffs file system access between the boot loader and VxWorks.</p>\r\n\r\n<p>Some organizations have developed their own VxWorks wrappers for Yaffs, but using the Yaffs-for-VxWorks wrapper saves a lot of integration and testing effort.</p>\r\n\r\n<p>Once the Yaffs-for-VxWorks file system code is loaded into the kernel, flash devices are added using yaffs_devAdd(). They are then available in the VxWorks file system for access just like any other files in the system.</p>\r\n\r\n<p><img alt=\"Yaffs and VxWorks conceptual relationships\" src=\"/sites/yaffs.net/files/images/yaffs-vxworks.png\" /></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<h2>6 Yaffs-for-VxWorks code</h2>\r\n\r\n<p>Yaffs-for-VxWorks is supplied as a VxWorks Downloadable Kernel Module (DKM) project with full source code. This can then be modifies into a BSP layer or library and compiled directly into the kernel.</p>\r\n\r\n<p>The code comprises Yaffs Direct Interface (YDI) plus two wrapper files:</p>\r\n\r\n<ul>\r\n	<li>yaffs_drv.c: This file does all the iosLib interfacing (ie. plugs Yaffs in as a VxWorks file system and plugs in the flash devices as file system devices. This file provides one externally visible function call: yaffs_devAdd() which allows Yaffs devices (ie. Flash drivers) to be plugged in.</li>\r\n	<li>yaffx_vx_glue.c: This file provides all the OS resources that Yaffs needs from VxWorks. For example, it initialises a semaphore and does any error code routing.</li>\r\n</ul>\r\n\r\n<p>In addition, if the Yaffs filesystem driver is build as a DKM, a file called yaffs_dkm.c provides the dummy DKM start() function.</p>\r\n\r\n<p>The code is provided as a DKM project. This includes the specification of the DEFINES needed to compile Yaffs under VxWorks. If the code is moved out of the DKM then it is important to make sure the correct DEFINES are set up.</p>\r\n\r\n<h2>7 Example Simulated Flash Driver</h2>\r\n\r\n<p>The Yaffs-for-VxWorks package provides an example Yaffs device that runs on a RAM simulator. This allows the file system to be tested in a simulation target without flash memory (eg the VxWorks simulator). This also provides an example for how to develop a flash driver and plug it in to Yaffs.</p>\r\n\r\n<h2>8 Example Real Time Process(RTP)</h2>\r\n\r\n<p>An example RTP is provided that performs some basic file system operations and demonstrates a working filesystem.</p>\r\n\r\n<p>This RTP uses standard file system calls (open(), read(), write()...) demonstrating that the Yaffs-for-VxWorks layer is operating as a native file system.</p>\r\n\r\n<h2>9 Integrating a Flash Device</h2>\r\n\r\n<p>Integrating a flash device is a relatively straight-forward process.</p>\r\n\r\n<p>The device is set up as a yaffs_device structure, which is then installed into Yaffs by calling the yaffs_devAdd() function.</p>\r\n\r\n<p>The NAND simulator can serve as an example for how to do this. The following snippet outlines the requirements. For a better description of the params and drv sub-structures refer to http://www.yaffs.net/yaffs-tuning-and-configuration.</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p><code>struct yaffs_dev *yramsim_CreateRamSim(...)<br />\r\n{<br />\r\n...<br />\r\n&nbsp; dev = malloc(sizeof(*dev));<br />\r\n...<br />\r\n&nbsp; /* First set everything to NULL. */<br />\r\n&nbsp; memset(dev, 0, sizeof(*dev));<br />\r\n&nbsp;<br />\r\n&nbsp; /*&nbsp;<br />\r\n&nbsp; &nbsp;* There are three sections to the yaffs_dev structure<br />\r\n&nbsp; &nbsp;* that needs to be initialised:<br />\r\n&nbsp; &nbsp;* * The params sub-structure which are all the control<br />\r\n&nbsp; &nbsp;* parameters.<br />\r\n&nbsp; &nbsp;* * The drv sub-structure which holds the driver functions.<br />\r\n&nbsp; &nbsp;* * The context which holds a private pointer (used to hold a<br />\r\n&nbsp; &nbsp;* driver context).<br />\r\n&nbsp; &nbsp;*/<br />\r\n&nbsp; p = &amp;dev-&gt;param;<br />\r\n&nbsp; p-&gt;name = strdup(name);<br />\r\n&nbsp; p-&gt;start_block = start_block;<br />\r\n&nbsp; p-&gt;end_block = end_block;<br />\r\n&nbsp; p-&gt;total_bytes_per_chunk = DATA_SIZE;<br />\r\n&nbsp; p-&gt;spare_bytes_per_chunk= SPARE_SIZE;<br />\r\n&nbsp; p-&gt;chunks_per_block = PAGES_PER_BLOCK;<br />\r\n&nbsp; p-&gt;n_reserved_blocks = 2;<br />\r\n&nbsp; p-&gt;use_nand_ecc = 1;<br />\r\n&nbsp; p-&gt;inband_tags = 0;<br />\r\n&nbsp; p-&gt;is_yaffs2 = 1;<br />\r\n&nbsp;<br />\r\n&nbsp; d= &amp;dev-&gt;drv;<br />\r\n&nbsp; d-&gt;drv_initialise_fn = yramsim_initialise;<br />\r\n&nbsp; d-&gt;drv_deinitialise_fn = yramsim_deinitialise;<br />\r\n&nbsp; d-&gt;drv_read_chunk_fn = yramsim_rd_chunk;<br />\r\n&nbsp; d-&gt;drv_write_chunk_fn = yramsim_wr_chunk;<br />\r\n&nbsp; d-&gt;drv_erase_fn = yramsim_erase;<br />\r\n&nbsp; d-&gt;drv_check_bad_fn = yramsim_check_block_bad;<br />\r\n&nbsp; d-&gt;drv_mark_bad_fn = yramsim_mark_block_bad;<br />\r\n&nbsp;<br />\r\n&nbsp; dev-&gt;driver_context= (void *)sim;<br />\r\n&nbsp;<br />\r\n&nbsp; return dev;<br />\r\n}<br />\r\n&nbsp;<br />\r\n&nbsp;<br />\r\nvoid start(void)<br />\r\n{<br />\r\n&nbsp; int result;<br />\r\n&nbsp; struct yaffs_dev *dev;<br />\r\n&nbsp;<br />\r\n&nbsp; printf(\"Yaffs RAMSIM started\\n\");<br />\r\n&nbsp;<br />\r\n&nbsp; /* Create and add a RAM simulator device.<br />\r\n&nbsp; &nbsp;* To add a different sort of device, set up the device<br />\r\n&nbsp; &nbsp;* and call yaffs_devAdd.<br />\r\n&nbsp; &nbsp;*&nbsp;<br />\r\n&nbsp; &nbsp;*/<br />\r\n&nbsp; dev = yramsim_CreateRamSim(\"/yramsim\", 0, 400, 0, 399);<br />\r\n&nbsp; printf(\"device is %p\\n\", dev);<br />\r\n&nbsp;<br />\r\n&nbsp; if (dev) {<br />\r\n&nbsp; result = yaffs_devAdd(dev);<br />\r\n&nbsp; printf(\"yaffs_devAdd() returned %d\\n\", result);<br />\r\n&nbsp; printf(\"yaffs RAM simulator now available in file system as %s\",<br />\r\n&nbsp; dev-&gt;param.name);<br />\r\n&nbsp;<br />\r\n}<br />\r\n}</code></p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<h2>10 Appendix: Running the examples on the VxWorks simulator</h2>\r\n\r\n<p>Once you have built the Yaffs_filesystem_driver and Yaffs_RAMSIM_device projects, you can start up Yaffs on the simulator as follows:</p>\r\n\r\n<ol>\r\n	<li>Start the simulator.</li>\r\n	<li>Load the Yaffs_filesystem_driver DKM by right clicking on the Yaffs_filesystem_driver project, then selecting Run/Debug Kernel Task...</li>\r\n	<li>Load the Yaffs_RAMSIM_device DKM by right clicking on the Yaffs_filesystem_driver project, then selecting Run/Debug Kernel Task...</li>\r\n</ol>\r\n\r\n<p>At this stage the VxWorks console should look something like:</p>\r\n\r\n<pre>\r\n _________            _________\r\n\r\n \\77777777\\          /77777777/\r\n\r\n  \\77777777\\        /77777777/\r\n\r\n   \\77777777\\      /77777777/\r\n\r\n    \\77777777\\    /77777777/\r\n\r\n     \\77777777\\   \\7777777/\r\n\r\n      \\77777777\\   \\77777/              VxWorks 7\r\n\r\n       \\77777777\\   \\777/\r\n\r\n        \\77777777\\   \\7/     Core Kernel version: 1.0.10.2\r\n\r\n         \\77777777\\   -      Build date: Oct 13 2015 12:10:53\r\n\r\n          \\77777777\\\r\n\r\n           \\7777777/         Copyright Wind River Systems, Inc.\r\n\r\n            \\77777/   -                 1984-2015\r\n\r\n             \\777/   /7\\\r\n\r\n              \\7/   /777\\\r\n\r\n               -   -------\r\n\r\n\r\n              Board: SIMLINUX board\r\n\r\n     OS Memory Size: 511MB\r\n\r\n   ED&amp;R Policy Mode: Deployed\r\n\r\n        Debug Agent: Started (always)\r\n\r\n    Stop Mode Agent: Not started\r\n\r\n\r\nLoading symbol table from charlesqcore:/home/charles/WindRiver/workspace/VIP_1/default/vxWorks.sym ...done\r\n\r\n-&gt; \r\n\r\nYaffs file system DKM started\r\n\r\nYaffs flash devices can now be added by calling yaffs_devAdd()\r\n\r\nYaffs RAMSIM started\r\n\r\ndevice is 0x8829e010\r\n\r\nAdding Yaffs device 0x8829e010 (/yramsim)\r\n\r\nyaffs_devAdd() returned 0\r\n\r\nyaffs RAM simulator now available in file system as /yramsim</pre>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>At this stage you should be able to see the yaffs file system is running:</p>\r\n\r\n<pre>\r\n-&gt; ls \"/yramsim\"\r\n\r\n/yramsim/lost+found \r\n\r\nvalue = 0 = 0x0\r\n\r\n-&gt; </pre>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>If you have built the yaffs_test project, then try running that. This should show something like:</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<pre>\r\nStart running Yaffs test\r\n\r\n…\r\n\r\ndump directory from pwd\r\n\r\n./lost+found inode 2 length 2048 mode 41B6 directory\r\n\r\n\r\nfs size: 52297728 (51072k), free 51642368 (50432k), n files 4\r\n\r\nwrite_check_test()\r\n\r\nopening a\r\n\r\nOpen of a returned 3\r\n\r\nwrite_stuff_to_file returned 100000\r\n\r\n…\r\n\r\nFinished running Yaffs test</pre>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<p>Do a file listing &nbsp;again will show the file system state after running the test:</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<pre>\r\n-&gt; llr \"/yramsim\"\r\n\r\n\r\nListing Directory /yramsim:\r\n\r\ndrwxrwxrw-  1 0       0                 2048 Nov 25 14:07 level1/\r\n\r\n-rw-rw-rw-  1 0       0                50505 Nov 25 14:07 seek-trunc \r\n\r\n-rw-rw-rw-  1 0       0               123000 Nov 25 14:07 s \r\n\r\ndrw-rw-rw-  1 0       0                 2048 Nov 25 14:06 lost+found/\r\n\r\n\r\nListing Directory /yramsim/level1:\r\n\r\ndrwxrwxrw-  1 0       0                 2048 Nov 25 14:07 level2/\r\n\r\n\r\nListing Directory /yramsim/level1/level2:\r\n\r\ndrwxrwxrw-  1 0       0                 2048 Nov 25 14:07 level3/\r\n\r\n\r\nListing Directory /yramsim/level1/level2/level3:\r\n\r\ndrwxrwxrw-  1 0       0                 2048 Nov 25 14:07 level4/\r\n\r\n\r\nListing Directory /yramsim/level1/level2/level3/level4:\r\n\r\n\r\nListing Directory /yramsim/lost+found:\r\n\r\nvalue = 0 = 0x0</pre>\r\n\r\n<p>&nbsp;</p>\r\n','<p>The purpose of this document is to describe the Yaffs-on-VxWorks wrapper and provide sufficient information to port Yaffs to the VxWorks BSP. It assumes a working knowledge of VxWorks.</p><p>It does not describe the inner workings of Yaffs, and study of other Yaffs documents is recommended. Documents shown below in&nbsp;<i>Italics</i>&nbsp;will be found at&nbsp;<i>http://yaffs.net/documents . . .</i></p><p>The source and the definitive version of this document can be found in our git repository, <a href=\"http://www.aleph1.co.uk/gitweb/?p=yaffs-docs;a=tree;h=f4fcbdc9da052aa926c4bc2275547ca310eebbd8;hb=9d50c62a1c24f1b9dd00ec3eb6d0bddff0aed17d\">together with other Yaffs documents</a>.</p>','full_html'),('restr',0,481,563,'en',0,'<p>Use this page to control the site.<br />\r\n<br />\r\nOnly administrators can see and use this page.&nbsp;<br />\r\n&nbsp;</p>\r\n\r\n<ul>\r\n	<li><a href=\"/\">Go to the Home page.</a><br />\r\n	Use this to see the front page that ordinary users see. There may be slight differences as you will be seeing it as a logged in user.<br />\r\n	&nbsp;</li>\r\n	<li><a href=\"/admin/content\">List all the content on the site</a><br />\r\n	By default this lists both&nbsp;the published and unpubllshed content. List only a part&nbsp;by using the dropdown on the page. Also, below, on this page, you can find a list of the 10 most recent pieces of content, published and unpublished.<br />\r\n	&nbsp;</li>\r\n	<li>Add a new paper<br />\r\n	&nbsp;</li>\r\n	<li>Organise the highlighted list of papers<br />\r\n	Currently this is not accessible. Ask Jeff. All other lists can be re-ordered on their pages. To get some content&nbsp;into a list, edit the content, and choose the document type appropriate to the list.</li>\r\n</ul>\r\n\r\n<p>There may be items you think should be on this page. Please edit it, or ask for the addition.</p>\r\n','','basic_html'),('page',0,487,620,'en',0,'<p>Yaffs (Yet Another Flash File System) is an open-source file system specifically designed to be fast, robust and suitable for embedded use with NAND and NOR Flash. It is widely used with Linux, RTOSs, or no OS at all, in consumer devices. It is available under GNU Public License, GPL, or on commercial terms from Aleph One.</p>\r\n\r\n<p>&nbsp;</p>\r\n','','full_html'),('page',0,488,512,'en',0,'<p>You can do a lot to get going with Yaffs on your own, using the resources of this site. If you are serious about using it you should <a href=\"http://stoneboat.aleph1.co.uk/mailman/listinfo/yaffs\">join the Mailing List</a> and take a look at its Archive <a href=\"http://www.aleph1.co.uk/lurker/list/yaffs.html\"> HERE</a></p>\r\n\r\n<p>Please note that we have a git repository containing further documentation, including the YaffsForVxWorks document, <a href=\"http://www.aleph1.co.uk/gitweb/?p=yaffs-docs;a=tree;h=f4fcbdc9da052aa926c4bc2275547ca310eebbd8;hb=9d50c62a1c24f1b9dd00ec3eb6d0bddff0aed17d\">HERE</a></p>\r\n\r\n<h3>Main</h3>\r\n\r\n<ul>\r\n	<li><a href=\"http://localhost:8093/yaffs-overview\">Yaffs Overview</a><br />\r\n	A single page - double-sided - overview.<br />\r\n	&nbsp;</li>\r\n	<li><a href=\"/documents/faq\">FAQ</a><br />\r\n	Common technical questions about Yaffs (and not about Licences).<br />\r\n	&nbsp;</li>\r\n	<li><a href=\"http://localhost:8093/yaffs-licence-faqs\">Yaffs Licence FAQs</a><br />\r\n	Questions related to licensing Yaffs for commercial projects.<br />\r\n	&nbsp;</li>\r\n	<li><a href=\"/licences-more-background-and-detail\">Further licensing background and detail</a><br />\r\n	Fuller discussion about the different types of licenses, the benefits and conditions of each.&nbsp;</li>\r\n</ul>\r\n\r\n<ul>\r\n	<li><a href=\"/yaffs-licence-sample\">Yaffs Licence Sample</a><br />\r\n	An example licence for commercial, non-GPL use of Yaffs<br />\r\n	<br />\r\n	<em>Abstract</em>:<br />\r\n	While the Yaffs code is available free of charge under GPL, that entails the obligation to disclose Source Code for your application using Yaffs. An Aleph One Licence does not impose that obligation and so is attractive for proprietary projects.</li>\r\n</ul>\r\n\r\n<h3>Technical</h3>\r\n\r\n<ul>\r\n	<li><a href=\"/documents/how-yaffs-works\">How Yaffs Works</a><br />\r\n	All the technical details on the inner workings of Yaffs.<br />\r\n	<br />\r\n	<em>Abstract</em>:<br />\r\n	This document gives a reasonable explanation of most of the core mechanisms that make Yaffs work. As of the time of writing this, the Yaffs2 code base includes approximately 19,000 lines of code making a very detailed discussion impractical. This document should serve as a first port of call for understanding Yaffs. Further detailed questions and discussions are welcomed on the Yaffs discussion list.<br />\r\n	&nbsp;</li>\r\n	<li><a href=\"/yaffs-tuning-and-configuration\">Yaffs Tuning</a><br />\r\n	How you can make Yaffs work best for your needs under Linux and with Yaffs Direct.<br />\r\n	<br />\r\n	<em>Abstract</em>:\r\n	<p>Yaffs has many options for tuning for speed or memory use. This document details them for Yaffs Direct and Linux, and covers compile time flags and settings, initialisation parameters, tracing, and state inspection.<br />\r\n	&nbsp;</p>\r\n	</li>\r\n	<li>\r\n	<p><a href=\"/documents/yaffs-direct-interface\">The Yaffs Direct Interface</a><br />\r\n	A description of the Yaffs Direct Interface and how it works.<br />\r\n	<br />\r\n	<em>Abstract</em>:<br />\r\n	The Yaffs Direct Interface (YDI) is a low level mechanism for using Yaffs. It\'s particularly useful on systems that don\'t support POSIX. This document discusses the interface in detail. The YDI includes the base operands that must be implemented to use Yaffs with a particular OS and particular NAND flash. As such, this document is of interest if you are implementing Yaffs on a RTOS or directly on hardware.<br />\r\n	&nbsp;</p>\r\n	</li>\r\n	<li><a href=\"/documents/yaffs-vxworks\">Yaffs for VxWorks</a><br />\r\n	Details of how Yaffs works with VxWorks<br />\r\n	<br />\r\n	<em>Abstract</em>:<br />\r\n	Yaffs-for-VxWorks is a wrapper around the Yaffs Direct Interface (YDI), that plugs&nbsp;YDI&nbsp;in as a native file system (ie. Yaffs becomes a file system that is accessed in the same way other file systems on system. This makes it really easy to migrate existing VxWorks software, or develop new VxWorks software to get the benefits of&nbsp;Yaffs.</li>\r\n</ul>\r\n\r\n<h3>Detail</h3>\r\n\r\n<ul>\r\n	<li><a href=\"/documents/yaffs-nand-flash-failure-mitigation\">Yaffs NAND Failure Mitigation</a><br />\r\n	Discusses&nbsp;NAND&nbsp;failure modes and the measures that Yaffs takes to mitigate against&nbsp;these.<br />\r\n	<br />\r\n	<em>Abstract</em>:<br />\r\n	NAND flash is one of very few types of electronic device which are knowingly shipped with errors and are expected to generate further errors without causing system failure.&nbsp;This document describes the most important failure modes and how they may be addressed in software.</li>\r\n</ul>\r\n\r\n<ul>\r\n	<li><a href=\"/documents/yaffs-robustness-and-testing\">Yaffs Robustness and Testing</a><br />\r\n	The testing regime for Yaffs, and how we can be so certain that it\'s rock solid.<br />\r\n	<br />\r\n	<em>Abstract:</em><br />\r\n	Many embedded systems need to store critical data, making reliable file systems an important part of modern embedded system design. That robustness is not achieved through chance. Robustness is only achieved through design and extensive testing to verify that the file system functions correctly and is resistant to power failure. This document describes some of the important design criteria and design features used to achieve a robust design. The test methodologies are also described.<br />\r\n	&nbsp;</li>\r\n	<li>\r\n	<p><a href=\"/yaffs-2-specification\">Yaffs 2 Specification</a><br />\r\n	The original motivation for Yaffs2 was to add support for the new NAND with 2kB pages instead of 512-byte pages and strictly sequential page writing order. This document details the updated system and the benefits over Yaffs1.</p>\r\n	</li>\r\n	<li>\r\n	<p><a href=\"http://localhost:8093/comparison-yaffs-vs-jffs\">Comparison between Yaffs (Yaffs2) and JFFS2</a><br />\r\n	If you are trying to decide between Yaffs2 and JFFS2 then this note will give you an idea of the relative advantages of each.</p>\r\n	</li>\r\n	<li>\r\n	<p><a href=\"http://localhost:8093/yaffs-porting-guide\">Yaffs Porting Guide</a><br />\r\n	A description of what needs to be done to implement Yaffs2 on an OS using the Yaffs Direct Interface, using eCos as an example, on Balloon Board hardware.</p>\r\n	</li>\r\n	<li>\r\n	<p><a href=\"/running-yaffs-direct-tests\">Running Yaffs Direct Tests</a><br />\r\n	Provides an outline to the various tests that are incorporated into Yaffs Direct.</p>\r\n	</li>\r\n</ul>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<h3>Archive</h3>\r\n\r\n<ul>\r\n	<li><a href=\"http://localhost:8093/yaffs-talk-pdf-slides-celf-2007\">Yaffs Talk - PDF of slides from CELF, 2007</a><br />\r\n	This contains an overview of Yaffs, and a comparison of Yaffs1 and Yaffs2.<br />\r\n	&nbsp;</li>\r\n	<li><a href=\"/paper-investigating-log-management-crash-recovery-mechanism\">Paper investigating a log management &amp; crash recovery mechanim for flash</a><br />\r\n	From 2006.</li>\r\n</ul>\r\n\r\n<ul>\r\n	<li><a href=\"http://localhost:8093/yaffs-original-specification\">Yaffs Original Specification</a><br />\r\n	The initial specification for Yaffs. Circa 2002. This is sometimes known as Yaffs1. Details of the filing system, including short backgrounder. Read this if you want to know what it is, what it does and how it works. This specification does not cover Yaffs2.<br />\r\n	&nbsp;</li>\r\n	<li><a href=\"http://localhost:8093/state-nand-mtd-driver-start-project\">State of NAND MTD driver at start of project</a><br />\r\n	&nbsp;</li>\r\n	<li><a href=\"http://localhost:8093/yaffs-history\">Yaffs History</a><br />\r\n	A chronology and list of milestones in Yaffs development up to 2006.<br />\r\n	&nbsp;</li>\r\n	<li><a href=\"http://localhost:8093/yaffs-nand-specific-flash-file-system-introductory-article\">Yaffs: the NAND-specific flash file system - Introductory Article</a>&nbsp;<br />\r\n	This article from 2002 describes the benefits and problems associated with NAND flash, the steps that Yaffs1 takes to overcome the problems, and how that drove some design decisions. Parts of this are still relevant in 2012.<br />\r\n	&nbsp;</li>\r\n	<li><a href=\"http://localhost:8093/howto-incorporate-yaffs-linux\">HOWTO incorporate Yaffs1 in Linux</a>.<br />\r\n	&nbsp;</li>\r\n	<li><a href=\"http://localhost:8093/yaffs-development-notes\">Yaffs1 Development Notes</a><br />\r\n	Useful notes if you are working with Yaffs1, about how Yaffs can be used.<br />\r\n	&nbsp;</li>\r\n	<li><a href=\"http://localhost:8093/yaffs1-memory-footprint\">Yaffs (Yaffs1) memory footprint</a><br />\r\n	An example calculation for the memory that Yaffs1 uses.<br />\r\n	&nbsp;</li>\r\n	<li><a href=\"http://localhost:8093/fuel-embedded-database-use-yaffs\">FUEL Embedded Database for use with Yaffs</a><br />\r\n	&nbsp;</li>\r\n</ul>\r\n','','basic_html'),('page',0,489,516,'en',0,'<p>You can use this Vagrant box to test Yaffs.</p><p>To run it you will need VirtualBox, which you can download from&nbsp;<a href=\"https://www.virtualbox.org/\">https://www.virtualbox.org/</a>&nbsp;(50 to 90MB download). To run Virtualbox you will need a PC which is capable of virtualisation. Any PC made in the since about 2006 should be capable of this, apart from notepads, and even some notepads have virtualisation.&nbsp;</p><p>Follow the instructions to install VirtualBox on your system. It\'s available for Linux, Solaris, Windows and Mac.&nbsp;The Vagrant box was created using VirtualBox 4.1, but version 4.0 should be ok too if you have a problem with the 4.1 series.&nbsp;</p><p>Once VirtualBox is installed you will need to download and install Vagrant. You find Vagrant at&nbsp;<a href=\"http://vagrantup.com/\">http://vagrantup.com/</a>. Download and install the latest version for your operating system from&nbsp;<a href=\"http://downloads.vagrantup.com/\">http://downloads.vagrantup.com/</a>. Vagrant is a download of between 10 and 60MB, depending on your operating system, excluding any Vagrant boxes you choose to download.&nbsp;The install instructions can be found at&nbsp;<a href=\"http://vagrantup.com/v1/docs/getting-started/index.html\">http://vagrantup.com/v1/docs/getting-started/index.html</a></p><p>Now, download the <a href=\"https://docs.google.com/open?id=0ByOfch_s-hgmVmlENG80bHpwMlk\">Yaffs Vagrant box</a>, saving it to your hard drive. This is a large download - 3GB, so if you are on a slow network, you may wish to schedule it for a convenient time.</p><p>After you have Vagrant installed, to test the Yaffs box, open a command line/terminal and type:</p>\r\n<pre style=\"padding-top: 8.5px; padding-right: 8.5px; padding-bottom: 8.5px; padding-left: 8.5px; font-family: Menlo, Monaco, \'Courier New\', monospace; font-size: 14px; color: rgb(51, 51, 51); border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; margin-top: 0px; margin-bottom: 9px; line-height: 1.6em; background-color: rgb(254, 251, 243); border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgba(0, 0, 0, 0.199219); border-right-color: rgba(0, 0, 0, 0.199219); border-bottom-color: rgba(0, 0, 0, 0.199219); border-left-color: rgba(0, 0, 0, 0.199219); border-image: initial; white-space: pre-wrap; word-break: break-all; word-wrap: break-word; -webkit-box-shadow: rgba(0, 0, 0, 0.0976563) 0px 1px 2px; box-shadow: rgba(0, 0, 0, 0.0976563) 0px 1px 2px; \"><span style=\"line-height: 1.6em; \">$ mkdir ~/yaffsprecise\r\n$ cd ~/yaffsprecise\r\n$ </span>vagrant box add yaffsprecise /wherever/you/saved/package.box\r\n$ vagrant init yaffsprecise\r\n$ vagrant up\r\n$ vagrant ssh</pre>\r\n<p>This will leave you at the command line of the Yaffs box.&nbsp;</p><p>You can find the kernel and yaffs in the ~/kernel directory (i.e. /home/vagrant/kernel).</p><p>You can create a Yaffs Nand Simulated drive using the following:</p>\r\n<pre style=\"padding-top: 8.5px; padding-right: 8.5px; padding-bottom: 8.5px; padding-left: 8.5px; font-family: Menlo, Monaco, \'Courier New\', monospace; font-size: 14px; color: rgb(51, 51, 51); border-top-left-radius: 4px; border-top-right-radius: 4px; border-bottom-right-radius: 4px; border-bottom-left-radius: 4px; margin-top: 0px; margin-bottom: 9px; line-height: 1.6em; background-color: rgb(254, 251, 243); border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgba(0, 0, 0, 0.199219); border-right-color: rgba(0, 0, 0, 0.199219); border-bottom-color: rgba(0, 0, 0, 0.199219); border-left-color: rgba(0, 0, 0, 0.199219); border-image: initial; white-space: pre-wrap; word-break: break-all; word-wrap: break-word; -webkit-box-shadow: rgba(0, 0, 0, 0.0976563) 0px 1px 2px; box-shadow: rgba(0, 0, 0, 0.0976563) 0px 1px 2px; \"><span style=\"line-height: 1.6em; \">$ sudo </span><span style=\"color: rgb(34, 34, 34); line-height: 20px; text-align: justify; \">sudo modprobe nandsim first_id_byte=0xec second_id_byte=0xd3 third_id_byte=0x51 </span><span style=\"color: rgb(34, 34, 34); line-height: 20px; text-align: justify; \">fourth_id_byte=0x15\r\n</span><span style=\"color: rgb(34, 34, 34); line-height: 20px; text-align: justify; \">$ sudo mount -t yaffs /dev/mtdblock0 /media/nand</span></pre>\r\n<div>In the commands above, there\'s no need to modprobe mtd or mtdblock because the Vagrant image has these compiled into the kernel.&nbsp;</div><div>&nbsp;</div><div>Once you have mounted your Yaffs partition, you can experiment with writing and deleting files, watching what happens.</div><p>&nbsp;</p>','','full_html'),('article',0,497,568,'en',0,'<p>Test article.</p>\r\n\r\n<p>&nbsp;</p>\r\n\r\n<table>\r\n	<tbody>\r\n		<tr>\r\n			<td>s</td>\r\n			<td>s</td>\r\n		</tr>\r\n		<tr>\r\n			<td>f</td>\r\n			<td>d</td>\r\n		</tr>\r\n		<tr>\r\n			<td>&nbsp;</td>\r\n			<td>&nbsp;</td>\r\n		</tr>\r\n	</tbody>\r\n</table>\r\n\r\n<p>&nbsp;</p>\r\n','','full_html'),('page',0,498,615,'en',0,'<p>Aleph One, as owners of Yaffs, sell commercial Licences for the use of Yaffs which&nbsp;do&nbsp;<em>NOT</em>&nbsp;carry the obligations of GPL. (Under the GPL, if you distribute your product with Yaffs, you are required to licence your product under the GPL and make available the full source code for a small charge.)</p>\r\n\r\n<p>Commercial Yaffs licences are non-exclusive, perpetual, world-wide, royalty-free and paid for with a single fee for one product. A commercial Licence entitles you to most further development and improvement of the Yaffs code.</p>\r\n\r\n<p>Contributing modifications of Yaffs code to the mainline code does not&nbsp;alter its Licence status.The base price for a Licence for a single Product is GB£10,000. Sterling.</p>\r\n\r\n<p>You can find further information about Licences in these documents:</p>\r\n\r\n<ul>\r\n	<li><a href=\"http://localhost:8012/node/preview/bf4b0a08-7ee4-44d1-ba5a-e3565ee8f04a/yaffs-gpl\">Yaffs under GPL</a></li>\r\n	<li><a href=\"http://localhost:8012/node/preview/bf4b0a08-7ee4-44d1-ba5a-e3565ee8f04a/yaffs-licence-faqs\">Yaffs licensing FAQ</a></li>\r\n	<li><a href=\"http://localhost:8012/licences-more-background-and-detail\">Further licensing background and detail</a></li>\r\n	<li><a href=\"http://localhost:8012/yaffs-licence-sample\">Sample commercial licence</a></li>\r\n</ul>\r\n\r\n<p>If you have any questions, or would like to buy a commercial licence, please contact us either at&nbsp;+44 (0)1223 811679 or email&nbsp; sales@aleph1.co.uk&nbsp; or see our Contacts page:-&nbsp;&nbsp;<a href=\"http://www.aleph1.co.uk/contact\">http://www.aleph1.co.uk/contact</a></p>\r\n','','basic_html'),('page',0,499,616,'en',0,'<p>Yaffs is available under the GNU General Public Licence, v.2&nbsp; and under commercial terms.</p>\r\n\r\n<p>For testing and experiment you can grab Yaffs under the GPL free of charge right now&nbsp;<strong><a href=\"/download-yaffs-using-git\">from our GIT repository</a>&nbsp;</strong>and we strongly recommend you also read <strong><a href=\"/documents/how-yaffs-works\">How Yaffs Works</a></strong>.</p>\r\n\r\n<p>The GIT summary page shows <strong>the <a href=\"http://aleph1.co.uk/gitweb?p=yaffs2.git;a=summary\">changes that have been made over time</a> </strong>in the base code.</p>\r\n\r\n<h3>LICENSES FOR YAFFS</h3>\r\n\r\n<p>Yaffs is the property of Aleph One Limited.</p>\r\n\r\n<p>Yaffs is available free of charge under the terms of the GNU General Public&nbsp;License version 2, GNU GPL2 &nbsp; given at:-&nbsp;<a href=\"http://www.gnu.org/licenses/gpl-2.0.html\">http://www.gnu.org/licenses/gpl-2.0.html</a></p>\r\n\r\n<p>See especially Sections 3.a and 3.b.&nbsp; These and the following sections describe the&nbsp;obligations placed on those who distribute source and/or object code&nbsp;embodying or associated with GPL code, and therefore <strong>apply to all who&nbsp;use Yaffs under GPL</strong>.</p>\r\n\r\n<p>Linking Yaffs to other software creates a derived work and our&nbsp;interpretation of linking includes dynamic and runtime linking.&nbsp; The&nbsp;derived work has the usual GPL obligation to release source code to&nbsp;anyone who asks. This remains true if you use Yaffs with another, or&nbsp;no, OS.</p>\r\n\r\n<h4>Commercial licensing</h4>\r\n\r\n<p>Aleph One, as owners of Yaffs, sell commercial Licences for the use of Yaffs which&nbsp;do <em>NOT</em> carry the obligations of GPL.</p>\r\n\r\n<p>Contributing modifications of Yaffs code to the mainline code does not&nbsp;alter its Licence status.</p>\r\n\r\n<p>Commercial Yaffs licences are non-exclusive, perpetual, world-wide, royalty-free and paid for with a single fee for one product. A commercial Licence entitles you to most further development and improvement of the Yaffs code.</p>\r\n\r\n<p>The base price for a Licence for a single Product is GB£10,000. Sterling</p>\r\n\r\n<p>You can find further information about Licences in these documents:</p>\r\n\r\n<ul>\r\n	<li><a href=\"yaffs-gpl\">Yaffs under GPL</a></li>\r\n	<li><a href=\"yaffs-licence-faqs\">Yaffs licensing FAQ</a></li>\r\n	<li><a href=\"/licences-more-background-and-detail\">Further licensing background and detail</a></li>\r\n	<li><a href=\"/yaffs-licence-sample\">Sample commercial licence</a></li>\r\n</ul>\r\n\r\n<p>If you have any questions, or would like to buy a commercial licence, please contact us either at&nbsp;+44 (0)1223 811679 or email&nbsp; sales@aleph1.co.uk&nbsp; or see our Contacts page:-&nbsp; <a href=\"http://www.aleph1.co.uk/contact\">http://www.aleph1.co.uk/contact</a></p>\r\n','','basic_html'),('page',0,500,621,'en',0,'<p>Android phones were early adopters of Yaffs, providing a huge international test-bed, increasing exposure and confidence in the robustness of Yaffs. In turn, this attracted many customers who particularly value robustness, and now Yaffs is used in many high-reliability areas such as aerospace and critical infrastructure.</p>\r\n\r\n<p>It wouldn\'t be surprising if Yaffs hadn\'t already been part of your day today...</p>\r\n\r\n<p>Making a cup of coffee? Yaffs is used in the process controllers that pump and refine the water and the electricity or gas used to heat the water.</p>\r\n\r\n<p>Using the internet? Many of the routers and other equipment&nbsp;use Yaffs. If they stopped working you\'d probably not be reading this page.</p>\r\n\r\n<p>Used a phone? Well some phones use Yaffs. Yaffs is also used in cell towers, telephone exchanges, video phones, video codecs,... Without Yaffs you wouldn\'t even get a dial tone.</p>\r\n\r\n<p>Flying somewhere? Yaffs is used in planes: both pilot information systems and cabin systems. It is also used in point of sale equipment and public information systems (eg. passenger information systems).</p>\r\n\r\n<p>Watching a movie on TV? Well first off, Yaffs is used in the movie production equipment (cameras and monitors) as well as synthesizers and digital musical instruments used to make the soundtrack. Yaffs is used in TV broadcast equipment and set top boxes that get the movie to your TV, then lastly, Yaffs is used in some TVs or sound systems.</p>\r\n\r\n<p>Driving on a road? Lots of data was needed to build that road and Yaffs gets involved all the way. Yaffs is used in the GPSs, laser scanners and total stations (modern day theodolites) used to gather the data. This data then goes back to the office for design, then gets sent back out to automated Yaffs-powered construction equipment (laser and GPS guided graders, pavers etc) to make accurately built roads which are safer and last longer.</p>\r\n\r\n<p>It\'s used in keeping you safe: in building security and in&nbsp;building monitoring; in food security and safety systems; and, in the provision of the emergency services. People and companies trust Yaffs to be reliable.</p>\r\n\r\n<p>&nbsp;</p>\r\n','','basic_html');
