📄 mtdnand.tmpl
字号:
</para> </listitem> <listitem><para>NAND_ECC_HW8_512</para><para> Hardware ECC generator providing 6 bytes ECC per 512 byte. </para> </listitem> </itemizedlist> If your hardware generator has a different functionality add it at the appropriate place in nand_base.c </para> <para> The board driver must provide following functions: <itemizedlist> <listitem><para>enable_hwecc</para><para> This function is called before reading / writing to the chip. Reset or initialize the hardware generator in this function. The function is called with an argument which let you distinguish between read and write operations. </para> </listitem> <listitem><para>calculate_ecc</para><para> This function is called after read / write from / to the chip. Transfer the ECC from the hardware to the buffer. If the option NAND_HWECC_SYNDROME is set then the function is only called on write. See below. </para> </listitem> <listitem><para>correct_data</para><para> In case of an ECC error this function is called for error detection and correction. Return 1 respectively 2 in case the error can be corrected. If the error is not correctable return -1. If your hardware generator matches the default algorithm of the nand_ecc software generator then use the correction function provided by nand_ecc instead of implementing duplicated code. </para> </listitem> </itemizedlist> </para> </sect2> <sect2> <title>Hardware ECC with syndrome calculation</title> <para> Many hardware ECC implementations provide Reed-Solomon codes and calculate an error syndrome on read. The syndrome must be converted to a standard Reed-Solomon syndrome before calling the error correction code in the generic Reed-Solomon library. </para> <para> The ECC bytes must be placed immidiately after the data bytes in order to make the syndrome generator work. This is contrary to the usual layout used by software ECC. The seperation of data and out of band area is not longer possible. The nand driver code handles this layout and the remaining free bytes in the oob area are managed by the autoplacement code. Provide a matching oob-layout in this case. See rts_from4.c and diskonchip.c for implementation reference. In those cases we must also use bad block tables on FLASH, because the ECC layout is interferring with the bad block marker positions. See bad block table support for details. </para> </sect2> </sect1> <sect1> <title>Bad block table support</title> <para> Most NAND chips mark the bad blocks at a defined position in the spare area. Those blocks must not be erased under any circumstances as the bad block information would be lost. It is possible to check the bad block mark each time when the blocks are accessed by reading the spare area of the first page in the block. This is time consuming so a bad block table is used. </para> <para> The nand driver supports various types of bad block tables. <itemizedlist> <listitem><para>Per device</para><para> The bad block table contains all bad block information of the device which can consist of multiple chips. </para> </listitem> <listitem><para>Per chip</para><para> A bad block table is used per chip and contains the bad block information for this particular chip. </para> </listitem> <listitem><para>Fixed offset</para><para> The bad block table is located at a fixed offset in the chip (device). This applies to various DiskOnChip devices. </para> </listitem> <listitem><para>Automatic placed</para><para> The bad block table is automatically placed and detected either at the end or at the beginning of a chip (device) </para> </listitem> <listitem><para>Mirrored tables</para><para> The bad block table is mirrored on the chip (device) to allow updates of the bad block table without data loss. </para> </listitem> </itemizedlist> </para> <para> nand_scan() calls the function nand_default_bbt(). nand_default_bbt() selects appropriate default bad block table desriptors depending on the chip information which was retrieved by nand_scan(). </para> <para> The standard policy is scanning the device for bad blocks and build a ram based bad block table which allows faster access than always checking the bad block information on the flash chip itself. </para> <sect2> <title>Flash based tables</title> <para> It may be desired or neccecary to keep a bad block table in FLASH. For AG-AND chips this is mandatory, as they have no factory marked bad blocks. They have factory marked good blocks. The marker pattern is erased when the block is erased to be reused. So in case of powerloss before writing the pattern back to the chip this block would be lost and added to the bad blocks. Therefor we scan the chip(s) when we detect them the first time for good blocks and store this information in a bad block table before erasing any of the blocks. </para> <para> The blocks in which the tables are stored are procteted against accidental access by marking them bad in the memory bad block table. The bad block table managment functions are allowed to circumvernt this protection. </para> <para> The simplest way to activate the FLASH based bad block table support is to set the option NAND_USE_FLASH_BBT in the option field of the nand chip structure before calling nand_scan(). For AG-AND chips is this done by default. This activates the default FLASH based bad block table functionality of the NAND driver. The default bad block table options are <itemizedlist> <listitem><para>Store bad block table per chip</para></listitem> <listitem><para>Use 2 bits per block</para></listitem> <listitem><para>Automatic placement at the end of the chip</para></listitem> <listitem><para>Use mirrored tables with version numbers</para></listitem> <listitem><para>Reserve 4 blocks at the end of the chip</para></listitem> </itemizedlist> </para> </sect2> <sect2> <title>User defined tables</title> <para> User defined tables are created by filling out a nand_bbt_descr structure and storing the pointer in the nand_chip structure member bbt_td before calling nand_scan(). If a mirror table is neccecary a second structure must be created and a pointer to this structure must be stored in bbt_md inside the nand_chip structure. If the bbt_md member is set to NULL then only the main table is used and no scan for the mirrored table is performed. </para> <para> The most important field in the nand_bbt_descr structure is the options field. The options define most of the table properties. Use the predefined constants from nand.h to define the options. <itemizedlist> <listitem><para>Number of bits per block</para> <para>The supported number of bits is 1, 2, 4, 8.</para></listitem> <listitem><para>Table per chip</para> <para>Setting the constant NAND_BBT_PERCHIP selects that a bad block table is managed for each chip in a chip array. If this option is not set then a per device bad block table is used.</para></listitem> <listitem><para>Table location is absolute</para> <para>Use the option constant NAND_BBT_ABSPAGE and define the absolute page number where the bad block table starts in the field pages. If you have selected bad block tables per chip and you have a multi chip array then the start page must be given for each chip in the chip array. Note: there is no scan for a table ident pattern performed, so the fields pattern, veroffs, offs, len can be left uninitialized</para></listitem> <listitem><para>Table location is automatically detected</para> <para>The table can either be located in the first or the last good blocks of the chip (device). Set NAND_BBT_LASTBLOCK to place the bad block table at the end of the chip (device). The bad block tables are marked and identified by a pattern which is stored in the spare area of the first page in the block which holds the bad block table. Store a pointer to the pattern in the pattern field. Further the length of the pattern has to be stored in len and the offset in the spare area must be given in the offs member of the nand_bbt_descr stucture. For mirrored bad block tables different patterns are mandatory.</para></listitem> <listitem><para>Table creation</para> <para>Set the option NAND_BBT_CREATE to enable the table creation if no table can be found during the scan. Usually this is done only once if a new chip is found. </para></listitem> <listitem><para>Table write support</para> <para>Set the option NAND_BBT_WRITE to enable the table write support. This allows the update of the bad block table(s) in case a block has to be marked bad due to wear. The MTD interface function block_markbad is calling the update function of the bad block table. If the write support is enabled then the table is updated on FLASH.</para> <para> Note: Write support should only be enabled for mirrored tables with version control. </para></listitem> <listitem><para>Table version control</para> <para>Set the option NAND_BBT_VERSION to enable the table version control. It's highly recommended to enable this for mirrored tables with write support. It makes sure that the risk of loosing the bad block table information is reduced to the loss of the information about the one worn out block which should be marked bad. The version is stored in 4 consecutive bytes in the spare area of the device. The position of the version number is defined by the member veroffs in the bad block table descriptor.</para></listitem> <listitem><para>Save block contents on write</para> <para> In case that the block which holds the bad block table does contain other useful information, set the option NAND_BBT_SAVECONTENT. When the bad block table is written then the whole block is read the bad block table is updated and the block is erased and everything is written back. If this option is not set only the bad block table is written and everything else in the block is ignored and erased. </para></listitem> <listitem><para>Number of reserved blocks</para> <para> For automatic placement some blocks must be reserved for bad block table storage. The number of reserved blocks is defined in the maxblocks member of the babd block table description structure. Reserving 4 blocks for mirrored tables should be a reasonable number. This also limits the number of blocks which are scanned for the bad block table ident pattern. </para></listitem> </itemizedlist> </para> </sect2> </sect1> <sect1> <title>Spare area (auto)placement</title> <para> The nand driver implements different possibilities for placement of filesystem data in the spare area, <itemizedlist> <listitem><para>Placement defined by fs driver</para></listitem> <listitem><para>Automatic placement</para></listitem> </itemizedlist> The default placement function is automatic placement. The nand driver has built in default placement schemes for the various chiptypes. If due to hardware ECC functionality the default placement does not fit then the board driver can provide a own placement scheme. </para> <para> File system drivers can provide a own placement scheme which is used instead of the default placement scheme. </para> <para> Placement schemes are defined by a nand_oobinfo structure <programlisting>struct nand_oobinfo { int useecc; int eccbytes; int eccpos[24]; int oobfree[8][2];}; </programlisting> <itemizedlist> <listitem><para>useecc</para><para> The useecc member controls the ecc and placement function. The header file include/mtd/mtd-abi.h contains constants to select ecc and placement. MTD_NANDECC_OFF switches off the ecc complete. This is not recommended and available for testing and diagnosis only. MTD_NANDECC_PLACE selects caller defined placement, MTD_NANDECC_AUTOPLACE selects automatic placement. </para></listitem> <listitem><para>eccbytes</para><para> The eccbytes member defines the number of ecc bytes per page. </para></listitem> <listitem><para>eccpos</para><para> The eccpos array holds the byte offsets in the spare area where the ecc codes are placed. </para></listitem> <listitem><para>oobfree</para><para> The oobfree array defines the areas in the spare area which can be used for automatic placement. The information is given in the format {offset, size}. offset defines the start of the usable area, size the length in bytes. More than one area can be defined. The list is terminated by an {0, 0} entry. </para></listitem> </itemizedlist> </para> <sect2> <title>Placement defined by fs driver</title> <para> The calling function provides a pointer to a nand_oobinfo structure which defines the ecc placement. For writes the caller must provide a spare area buffer along with the data buffer. The spare area buffer size is (number of pages) * (size of spare area). For reads the buffer size is (number of pages) * ((size of spare area) + (number of ecc steps per page) * sizeof (int)). The driver stores the result of the ecc check for each tuple in the spare buffer. The storage sequence is </para> <para> <spare data page 0><ecc result 0>...<ecc result n> </para> <para> ... </para> <para> <spare data page n><ecc result 0>...<ecc result n> </para> <para> This is a legacy mode used by YAFFS1. </para> <para> If the spare area buffer is NULL then only the ECC placement is done according to the given scheme in the nand_oobinfo structure. </para> </sect2> <sect2> <title>Automatic placement</title> <para> Automatic placement uses the built in defaults to place the ecc bytes in the spare area. If filesystem data have to be stored / read into the spare area then the calling function must provide a buffer. The buffer size per page is determined by the oobfree array in the nand_oobinfo structure. </para> <para> If the spare area buffer is NULL then only the ECC placement is done according to the default builtin scheme. </para> </sect2> <sect2> <title>User space placement selection</title> <para> All non ecc functions like mtd->read and mtd->write use an internal structure, which can be set by an ioctl. This structure is preset to the autoplacement default. <programlisting> ioctl (fd, MEMSETOOBSEL, oobsel); </programlisting> oobsel is a pointer to a user supplied structure of type nand_oobconfig. The contents of this structure must match the criteria of the filesystem, which will be used. See an example in utils/nandwrite.c. </para> </sect2> </sect1> <sect1> <title>Spare area autoplacement default schemes</title> <sect2> <title>256 byte pagesize</title><informaltable><tgroup cols="3"><tbody><row><entry>Offset</entry><entry>Content</entry><entry>Comment</entry></row><row><entry>0x00</entry><entry>ECC byte 0</entry><entry>Error correction code byte 0</entry></row><row><entry>0x01</entry><entry>ECC byte 1</entry><entry>Error correction code byte 1</entry></row><row><entry>0x02</entry><entry>ECC byte 2</entry><entry>Error correction code byte 2</entry></row><row><entry>0x03</entry><entry>Autoplace 0</entry><entry></entry></row><row><entry>0x04</entry><entry>Autoplace 1</entry><entry></entry></row><row><entry>0x05</entry><entry>Bad block marker</entry><entry>If any bit in this byte is zero, then this block is bad.This applies only to the first page in a block. In the remainingpages this byte is reserved</entry></row><row><entry>0x06</entry><entry>Autoplace 2</entry><entry></entry></row><row><entry>0x07</entry><entry>Autoplace 3</entry><entry></entry></row></tbody></tgroup></informaltable> </sect2> <sect2> <title>512 byte pagesize</title><informaltable><tgroup cols="3"><tbody><row><entry>Offset</entry><entry>Content</entry><entry>Comment</entry></row><row><entry>0x00</entry><entry>ECC byte 0</entry><entry>Error correction code byte 0 of the lower 256 Byte data inthis page</entry></row><row><entry>0x01</entry><entry>ECC byte 1</entry><entry>Error correction code byte 1 of the lower 256 Bytes of datain this page</entry></row><row><entry>0x02</entry><entry>ECC byte 2</entry><entry>Error correction code byte 2 of the lower 256 Bytes of datain this page</entry></row><row><entry>0x03</entry><entry>ECC byte 3</entry><entry>Error correction code byte 0 of the upper 256 Bytes of datain this page</entry></row><row><entry>0x04</entry><entry>reserved</entry>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -