mtd/html/tech nand.html,1.4,1.5

gleixner at infradead.org gleixner at infradead.org
Sat Aug 10 19:08:17 EDT 2002


Update of /home/cvs/mtd/html/tech
In directory phoenix.infradead.org:/tmp/cvs-serv19122

Modified Files:
	nand.html 
Log Message:
added some more faq, hardware ecc support and other details

Index: nand.html
===================================================================
RCS file: /home/cvs/mtd/html/tech/nand.html,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- nand.html	1 Aug 2002 09:36:15 -0000	1.4
+++ nand.html	10 Aug 2002 23:08:15 -0000	1.5
@@ -1,3 +1,11 @@
+<html>
+<head>
+	<meta http-equiv="content-type" content="text/html;charset=iso-8859-1">
+	<title>Linux-MTD NAND FLASH</title>
+</head>
+
+<body>
+	
 <h1>NAND FLASH</h1>
 
 <h2>NAND vs. NOR</h2>
@@ -135,17 +143,18 @@
     <td>R/B  </td>
     <td>Ready / Busy Output  </td>
   </tr>
-</table><br><br>
-
+</table><br>
 <p>As it is recommended to use the spare area, the /SE (Spare area Enable) pin should be tied to GND.
  /CE, CLE and ALE should be GPIO pins or latched signals. It's possible to use address lines for ALE and CLE,
- but you have to take care about the timing restrictions of the chip ! /RE and /WE can be tied to the corresponding lines of the CPU.
- I/O 0-7 are connected to the databus D0-D7. The /WP pin can be used for write protection or connected to VCC to enable writes unconditionally.
- As NAND flash uses a command driven programming and erasing, an accidential write or erase is not likely to happen.
- The Ready / Busy output is not neccecary for operation, but it can be tied to a GPIO or an interrupt line.
-</p>
-
-
+  but you have to take care about the timing restrictions of the chip ! </p>
+<p>/RE and /WE can be tied to the corresponding lines of the CPU. Make sure, that they are logicaly 
+combined with the corresponding chipselect. You can also use two different chipselects for /RE and /WE, 
+but be aware of data hold time constraints of your NAND chip. Data hold time after rising edge of /WE 
+is different to data hold after rising edge of chipselect lines!</p>
+<p>I/O 0-7 are connected to the databus D0-D7. The /WP pin can be used for write protection or connected 
+to VCC to enable writes unconditionally. As NAND flash uses a command driven programming and erasing, an
+ accidential write or erase is not likely to happen. The Ready / Busy output is not neccecary for operation, 
+ but it can be tied to a GPIO or an interrupt line. </p>
 <hr>
 <h2>Filesystems supporting NAND</h2>
 
@@ -160,30 +169,26 @@
   <li>NTFL for DiskOnChip devices </li>
   <li>TRUEFFS from M-Systems for DiskOnChip devices</li>
   <li>SmartMedia DOS-FAT as defined by the SSFDC Forum</li>
-</ul>
-
+</ul>
 <p>JFFS2 and NTFL are Open Source, while TRUEFFS is a proprietary solution. SmartMedia DOS-Fat is a specification from
 SSFDC forum. It is somewhat open under a non disclosure agreement with Toshiba, who owns all rights on this specifications.
 NTFL is designed for the usage of DiskOnChip devices. JFFS2 supports raw NAND chips and SmartMediaCards at the moment. A JFFS2 support for
 DiskOnChip devices, based on the NAND code, is planned.
-There are some other Open Source projects for NAND filesystem support, but there's no other working solution than JFFS2 at the moment of this writing.
-One of them is <a href=http://www.aleph1.co.uk/armlinux/projects/yaffs>YAFFS</a>, which is available in a beta version.</p>
-</p>
-<p>There is currently no support for the wide spread SmartMedia DOS-FAT filesystem, mainly because it's not a reliable filesystem
+There are some other Open Source projects for NAND filesystem support, but there's no other working solution 
+than JFFS2 at the moment of this writing. One of them is <a href=http://www.aleph1.co.uk/armlinux/projects/yaffs>YAFFS</a>,
+ which is available in a beta version.</p>
+<p> There is currently no support for the wide spread SmartMedia DOS-FAT filesystem, 
+ mainly because it's not a reliable filesystem
 for industrial usage. It's ok for multimedia applications. The hardware support layer is designed to support a implementation of SmartMedia
 DOS-FAT, but nobody has made an attempt to implement it really. There are a couple of SmartMedia Card adaptors 
-for USB, PCMCIA, FireWire ... with Linux drivers available, which support the SmartMedia DOS-FAT. 
-</p>
-
-<p>JFFS2 includes bad block management, wear leveling, error correction and provides a reliable filesystem on top of NAND Flash</p>
-
-
+for USB, PCMCIA, FireWire ... with Linux drivers available, which support the SmartMedia DOS-FAT. 
</p>
+<p>JFFS2 includes bad block management, wear leveling, error correction and provides a reliable filesystem on top of NAND Flash</p>
 <hr>
 <h2>HOWTO implement NAND support</h2>
 
 <h3>Where can you get the code ?</h3>
-<p>The changes to JFFS2 and the underlying NAND code are not in the kernel code at the moment. The latest code is available from
-<a href=http://www.linux-mtd.infradead.org>CVS and daily snapshots</a></p>
+<p>The latest changes to JFFS2 and the underlying NAND code are not in the kernel code at the moment. 
+The latest code is available from <a href=http://www.linux-mtd.infradead.org>CVS and daily snapshots</a></p>
 
 <p>There are four layers of software</p>
 <ol>
@@ -226,8 +231,7 @@
 }<br>
 If your hardware interface does not have access to the ready busy pin, you can delete this
 function and set the function pointer this->dev_ready to NULL.
-</p>
-
+</p>
 <p>
 <b>int __init yourboard_init (void)</b><br>
 {<br>
@@ -237,23 +241,65 @@
         SNIP<br>
 	/* map physical adress */<br>
 	yourboard_fio_base=(unsigned long)ioremap(yourboard_fio_pbase,SZ_1K);<br>
-        SNIP<br>
-	/* Set address of NAND IO lines */<br>
-	this->IO_ADDR_R = yourboard_fio_base; <i>The address to read from the chip </i><br>
-	this->IO_ADDR_W = yourboard_fio_base; <i>The address to write to the chip </i><br>
-	this->hwcontrol = yourboard_hwcontrol;<i>Your function for accessing the controllines</i><br>
-	this->dev_ready = yourboard_device_ready; <i>Your function for accessing the ready/busy line or NULL, if you don't have one</i><br>
-	this->chip_delay = 20;<i>The delay time (µs), after writing a command to the chip, according to datasheet</i><br>
-        SNIP<br>
-}<br>
-If you have a different access scheme to the chip for writing commands, due to your hardware, you can supply a own
-command write function by setting this->cmdfunc. The same applies for a own wait function, which could utilize an interrupt
-driven by the ready/busy pin. In this case set this->waitfunc to your own function. This must be done before calling nand_scan.
-<p>
-
-<h3>Supported chips</h3>
-<p>Most NAND chips actually available from 2 to 128MB should be supported by the current code. If you have a chip, which is not supported,
-it can easily be added by extending the chiplist in include/linux/mtd/nand_ids.h
+        SNIP<br>
+	
+	/* Set address of NAND IO lines */<br>
+	
+	this->IO_ADDR_R = yourboard_fio_base; <i>The address to read from the chip </i><br>
+	
+	this->IO_ADDR_W = yourboard_fio_base; <i>The address to write to the chip </i><br>
+	
+	this->hwcontrol = yourboard_hwcontrol;<i>Your function for accessing the controllines</i><br>
+	
+	this->dev_ready = yourboard_device_ready; <i>Your function for accessing the ready/busy 
+	line or NULL, if you don't have one</i><br>
+	
+	this->chip_delay = 20;<i>The delay time (us), after writing a command to the chip, according to datasheet (tR)</i><br>
+	
+        SNIP<br>
+	
+}<br>
+<p>Make sure that you allocate memory for the page cache. 
+<h4>Hardware specific command function</h4>
+<p>Some new CPU's like Samsungs ARM based S3SC2410 provide a hardware based NAND interface. For them and ugly 
+designed hardware interfaces it may be neccecary to have a customized command write function. You can supply 
+such a function by setting </p>
+<p>this-&gt;cmdfunc = yourboard_cmdfunc;</p>
+<p>This must be done in yourboard_init before calling nand_scan.</p>
+<h4>Hardware specific wait function</h4>
+<p>The same applies for a own wait function, which could utilize an interrupt driven by the ready/busy pin. 
+In this case set</p>
+<p>this-&gt;waitfunc = yourboard_waitfunction; </p>
+<p>Please take care of the functionality, which is in standard nand driver wait function (nand_wait).</p>
+<p>This must be done in yourboard_init before calling nand_scan.</p>
+<h4>Hardware based ECC</h4>
+<p>If your hardware supplies a hardware based ECC&nbsp;generator, then fill out the following. If not, skip this topic.</p>
+<p>this-&gt;eccmode =&nbsp;NAND_ECC_HW3_256; <br>
+	or <br>
+	this-&gt;eccmode = NAND_ECC_HW3_512;</p>
+<p>NAND_ECC_HW3_256 is a hardware based ECC generator, which generates 3 byte ECC&nbsp;code for 256 byte of data. 
+Such a generator can be found on DOC devices and on passive SmartMedia adaptors.<br>
+	NAND_ECC_HW3_512 is a hardware based ECC&nbsp;generator, which generates 3 byte ECC&nbsp;code for 512 
+	byte of data. Such a generator can be found e.g. on Samsungs ARM based S3SC2410 CPU.</p>
+<p>You have also to provide following functions:</p>
+<p>this-&gt;enable_hwecc =&nbsp;yourboard_enahwecc;&nbsp;<i>Your function to enable (reset) the hardware ECC 
+generator. This function is called from the generic nand driver before reading or writing data from/to the
+ chip. The function is called with NAND_ECC_READ&nbsp;or NAND_ECC_WRITE as argument.</i></p>
+<p>this-&gt;calculate_ecc =&nbsp;yourboard_readecc;&nbsp;<i>Your function to read back the ECC
+ bytes from your hardware ECC&nbsp;generator. Fill the data into the ecc_code array, which is 
+ given as argument. Ingore the first argument of this function, which is neccecary for software ecc only.</i></p>
+<p>this-&gt;correct_data =&nbsp;xxxx_datacorrection; <i>A function which implements  error 
+detection and data correction corresponding to your hardware ECC&nbsp;algorithm. This function
+ should be incorporated into nand_ecc.c with an appropriate function name, to make it public
+  available for similar hardware drivers. Maybe the function you need is already there. If you 
+  implement a new one, please contact NAND driver maintainer to include it in the public source tree. 
+   Please consult current implementations in nand_ecc.c to provide a compatible solution.</i></p>
+<p>This must be done in yourboard_init before calling nand_scan.</p>
+<h3>Supported chips</h3>
+<p>Most NAND chips actually available from 2 to 128MB should be supported by the current code. 
+If you have a chip, which is not supported,
+you can easily add it by extending the chiplist in include/linux/mtd/nand_ids.h.
+Please contact NAND driver maintainer to include it in the public source tree. 
 </p>
 
 <h3>Config settings</h3>
@@ -265,31 +311,28 @@
 CONFIG_MTD_NAND=y<br>
 CONFIG_MTD_NAND_ECC=y<br>
 CONFIG_MTD_NAND_ECC_JFFS2=y<br>
-CONFIG_MTD_NAND_YOURBOARD=y</p>
-
+CONFIG_MTD_NAND_YOURBOARD=y</p>
 <p>For JFFS2 usage set<br>
 CONFIG_JFFS2_FS=y<br>
 CONFIG_JFFS2_FS_DEBUG=0<br>
-CONFIG_JFFS2_FS_NAND=y</p>
-
-</p>Make sure that fs/Config.in contains the following lines:<br>
+CONFIG_JFFS2_FS_NAND=y</p>Make sure that fs/Config.in contains the following lines:<br>
 dep_tristate 'Journalling Flash File System v2 (JFFS2) support' CONFIG_JFFS2_FS $CONFIG_MTD<br>
 if [ "$CONFIG_JFFS2_FS" = "y" -o "$CONFIG_JFFS2_FS" = "m" ] ; then<br>
    int 'JFFS2 debugging verbosity (0 = quiet, 2 = noisy)' CONFIG_JFFS2_FS_DEBUG 0<br>
    bool 'JFFS2 support for NAND chips' CONFIG_JFFS2_FS_NAND<br>
-fi<br></p>
-
-<hr>
+fi<br>
+<hr>
 <h2>FAQ</h2>
 <h4>Can I boot from NAND Flash?</h4>
 <p>Not from a bare NAND chip. You need a glue logic around, which gives you memory access to the
 chip on bootup, like the DiskOnChip devices do. This will be a quite complex CPLD. An alternative
 is to use a small e.g. 1MB NOR Flash, which contains the boot code and maybe a compressed kernel
-image. Then you can use JFFS2 on NAND as your root filesystem</p>
+image. Then you can use JFFS2 on NAND as your root filesystem</p>
 <p>Some newer chips make the first page available for reading after power up. This could be
 helpful for starting a small 256/512 byte bootcode. At the time of this writing there is no
-tested implementation of this.</p>
-<h4>Is there support for 16/32bit wide NAND Flash ?</h4>
+tested implementation of this.</p>
+<p>Samsungs S3C2410 ARM based SOC-CPU provides a mechanism to boot from NAND flash.</p>
+<h4>Is there support for 16/32bit wide NAND Flash ?</h4>
 <p>No. The generic NAND driver supports 8 bit wide NAND Flash only. 16 or 32 bit NAND Flash can
 be built by using 2 or 4 chips and connect them to D0-7, D8-D15, D16-D23 and D24-D31 on the data bus.
 You can tie all corresponding control signals together. But you have to build a new nand16 or nand32 driver,
@@ -300,17 +343,49 @@
 driver. The JFFS2 code, which handles the writebuffer and the out of band (spare) area of NAND doesn't support
 16 / 32 bit neither.</p>
 <h4>How is ensured, that data is written to flash ?</h4>
-<p>As we have to handle a writebuffer for writing only full pages to the chips, there could be a loss of
-data, when the writebuffer is not flushed before power down. There are some mechanisms to ensure,
-that the writebuffer is flushed. You can force the flush of the writebuffer by using fsync() or sync()
-in your application. JFFS2 has a timed flush of the write buffer, which forces the flush of the buffer to flash,
-if there are no writes to the filesystem for more than 2 seconds. When you unmount the filesystem the buffer
-is flushed too.</p>
-<h4>Can I copy a JFFS2 Image to NAND</h4>
-<p>Yes, as long as your chip does not contain bad blocks. Make sure, that the erasesize you set to mkfs.jffs2
-is the same as the erasesize of your chip</p>
-
-<hr>
+<p>As we have to handle a writebuffer for writing only full pages to the chips, there could be a loss of data, 
+when the writebuffer is not flushed before power down. There are some mechanisms to ensure, that the writebuffer 
+is flushed. You can force the flush of the writebuffer by using fsync() or sync() in your application. 
+JFFS2 has a timed flush of the write buffer, which forces the flush of the buffer to flash, if there are no 
+writes to the filesystem for more than 2 seconds. When you unmount the filesystem the buffer is flushed too.</p>
+<h4>Can I copy a JFFS2 Image to NAND via /dev/mtdX ?</h4>
+<p>Yes, as long as your chip does not contain bad blocks. Make sure, that the erasesize you set to mkfs.jffs2 
+is the same as the erasesize of your chip. If  your kernel is set for JFFS2 on NAND and ECC is enabled, the 
+data will be written with ECC. </p>
+<h4>Can I use mtdutils erase / eraseall</h4>
+<p>Yes, the latest nand driver code forces the protection of bad block information. It's safe to erase a 
+NAND&nbsp;flash with erase(all) /dev/mtdX.</p>
+<h4>Must my bootloader be aware of NAND FLASH&nbsp;?</h4>
+<p>Yes, if you use your bootloader to erase the FLASH chip and copy a filesystem image to it. 
+For erase make sure, that you don't erase factory-marked bad blocks. They are marked in the 6th
+ byte (offset 0x5) of out of band area. The block is bad, if any bit in this byte is zero. 
+ If you erase such a block, the bad block information is erased too and lost. </p>
+<p>After the erase it's recommended to programm the JFFS2 erased marker into the out of band area
+ of the first page in each erased block. Do not program it into the data area of the page !</p>
+<p>For 256 byte pagesize devices program the following data into the out of band area:</p>
+<table border="1" cellpadding="5" cellspacing="0">
+	<tr>
+		<td>Offset</td>
<td>0x06</td>
<td>0x07</td>
+	</tr>
+	<tr>
+		<td>Data</td><td>0x85</td>

<td>0x19</td>
+	</tr>
+</table>
+<p>For 512 byte pagesize devices program the following data into the out of band area:</p>
+<table border="1" cellpadding="5" cellspacing="0">
+	<tr>
+		<td>Offset</td>
<td>0x08</td>
<td>0x09</td>


<td>0x0a</td><td>0x0b</td>

<td>0x0c</td><td>0x0d</td>

<td>0x0e</td><td>0x0f</td>
+	</tr>
+	<tr>
+		<td>Data</td><td>0x85</td>

<td>0x19</td>
<td>0x03</td>
<td>0x20</td><td>0x08</td>

<td>0x00</td>
<td>0x00</td>
<td>0x00</td>
+	</tr>
+</table>
+<p>If you copy a filesystem image to the chip, it's recommended to write it with ECC. You can use 
+the ECC code in the nand driver to do this. If you don't use ECC the nand driver will detect this, 
+as long as you leave the eccvalid byte (offset 0x04) in the out of band area in the erased state (0xff).
+ If you have a bad block on your chip, just skip this block and copy the data to the next block. 
+ JFFS2 is able to handle this gap.</p>
+<hr>
 <h2>References:</h2>
 <h3>Open Source</h3>
 <p>JFFS2 and NTFL are located on this <a href=http://www.linux-mtd.infradead.org> website</a></p>
@@ -331,4 +406,6 @@
 
 <hr>
 <address><a href="mailto:tglx at linutronix.de">Thomas Gleixner</a></address>
-$Id$
+$Id$
+</body>
+</html>
\ No newline at end of file





More information about the linux-mtd-cvs mailing list