ECC error correction algorithm

The full name of ECC is Error Checking and Correction, which is an error detection and correction algorithm for Nand. If there is no problem with the operation timing and the stability of the circuit, when the NAND Flash fails, it generally does not cause the entire Block or Page to be unreadable or all errors, but only one or a few bits in the entire Page (such as 512Bytes). . ECC can correct 1 bit error and detect 2 bit errors, and the calculation speed is very fast, but it cannot be corrected for errors of more than 1 bit, and errors of more than 2 bits cannot be detected.

Check code generation algorithm: ECC check operates on 256 bytes of data each time, including column check and row check. XOR the bit to be checked, if the result is 0, it means that there are even 1s; if the result is 1, it means that there are odd 1s. The column verification rules are shown in Table 1. 256 bytes of data form a matrix of 256 rows and 8 columns, and each element of the matrix represents a Bit.

Among them, CP0 ~ CP5 are six Bit bits, indicating Column Parity (column polarity),
CP0 is the polarity of columns 0, 2, 4, and 6, CP1 is the polarity of columns 1, 3, 5, and 7,
CP2 Is the polarity of columns 0, 1, 4, and 5, CP3 is the polarity of columns 2, 3, 6, and 7,
CP4 is the polarity of columns 0, 1, 2, and 3, and CP5 is the fourth, 5 , Polarity in columns 6 and 7.
It is expressed by the formula: CP0 = Bit0 ^ Bit2 ^ Bit4 ^ Bit6, which means that the 256 internal bit XOR of the 0th column is followed by the exclusive OR of the 256 Bit bits in the second column, and then each of the 4th and 6th columns XOR of one bit, so CP0 is actually the result of XOR of 256 * 4 = 1024 bits. CP1 ~ CP5 and so on.

Row verification is shown in the figure below

Among them, RP0 ~ RP15 are sixteen Bit bits, indicating Row Parity (row polarity),
RP0 is the polarity of the 0th, 2, 4, 6, .... 252, 254 bytes
RP1 ----- 1, 3, 5, 7 ... 
253, 255 RP2 ---- 0, 1, 4, 5, 8, 9 ... 252, 253 (processing 2 bytes, skipping 2 bytes)
RP3 ---- 2 , 3, 6, 7, 10, 11 ... 254, 255 (skip 2 bytes, process 2 bytes)
RP4 ---- process 4 bytes, skip 4 bytes;
RP5 ---- skip After 4 Bytes, process 4 Bytes;
RP6 ---- process 8 Bytes, skip 8 Bytes
RP7 ---- skip 8 Bytes, process 8 Bytes;
RP8 ---- process 16 Bytes , Skip 16 Byte
RP9 ---- Skip 16 Byte, process 16 Byte;
RP10 ---- Process 32 Byte, skip 32 Byte
RP11 ---- Skip 32 Byte, process 32 Bytes;
RP12 ---- Process 64 Bytes, skip 64 Bytes
RP13 ---- Skip 64 Bytes, process 64 Bytes;
RP14 ---- Process 128 Bytes, skip 128 Bytes
RP15 ---- Skip 128 Bytes and process 128 Bytes; it
can be seen that each bit of RP0 ~ RP15 is 128 bytes (that is, 128 lines), that is, the result of XOR of 128 * 8 = 1024 Bit .

In summary, a total of 6 Bit column check results and 16 Bit row check results are generated for a total of 22 Bits for 256 bytes of data. In Nand, 3 bytes are used to store the check result, and the extra two Bits are set to 1. The storage order is shown in the following table:

Taking K9F1208 as an example, each Page page contains a 512-byte data area and a 16-byte OOB area. The first 256 bytes of data generates a 3-byte ECC check code, and the last 256 bytes of data generates a 3-byte ECC check code. A total of 6 bytes of ECC check code is stored in the OOB area, and the storage position is the 0, 1, 2 and 3, 6, 7 bytes.

 

The C code of the check code generation algorithm is implemented

in the Linux kernel. The file where the ECC check algorithm is located is drivers / mtd / nand / nand_ecc.c. In fact, there are two new and old ones, in the kernel of 2.6.27 and earlier The program used has not been used since 2.6.28, and has been replaced with a more efficient program. A detailed introduction to the new program can be found in the Documentation / mtd / nand_ecc.txt file.

First analyze the ECC implementation in the 2.6.27 kernel. For the source code, see:
http://lxr.linux.no/linux+v2.6.27/drivers/mtd/nand/nand_ecc.c
43 / *
44  * Pre-calculated 256 -way 1 byte column parity
45  * /
46 static const  u_char
nand_ecc_precalc_table [] = {
47    0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x ,
48    0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
49   0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
50   0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
51   0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
52   0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
53   0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
54   0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
55   0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
56   0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
57   0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
58   0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
59   0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
60   0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
61   0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
62   0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00
63};

In order to speed up the calculation speed, a pre-calculated column polarity table is used in the program. Each element in this table is of type unsigned char, representing an 8-bit binary number. The meaning of each bit of the 8-bit binary number in the table:

The meaning of this table is: for the 256 numbers from 0 to 255, calculate and store the column check value and row check value of each number, and use the number as the array subscript. For example, nand_ecc_precalc_table [13] stores the column check value and row check value of 13, the binary representation of 13 is 00001101, which

CP0 = Bit0^Bit2^Bit4^Bit6 = 0;

CP1 = Bit1 ^ Bit3 ^ Bit5 ^ Bit7 = 1;
CP2 = Bit0 ^ Bit1 ^ Bit4 ^ Bit5 = 1;
CP3 = Bit2 ^ Bit3 ^ Bit6 ^ Bit7 = 0;
CP4 = Bit0 ^ Bit1 ^ Bit2 ^ Bit3 = 1;
CP5 = Bit4 ^ Bit5 ^ Bit6 ^ Bit7 = 0;
its row polarity RP = Bit0 ^ Bit1 ^ Bit2 ^ Bit3 ^ Bit4 ^ Bit5 ^ Bit6 ^ Bit7 = 1;
then the value stored at nand_ecc_precalc_table [13] should be 0101 0110, ie 0x56 .
Note that the array index nand_ecc_precalc_table is actually a byte of data we want to check.
Understand the meaning of this table, it is easy to write a program to generate this table. For the procedure, see the MakeEccTable.c file in the attachment.

With this table, for single-byte data dat, you can directly check the table nand_ecc_precalc_table [dat] to get the row check value and column check value of dat. However, ECC actually needs to check 256 bytes of data. It needs to perform 256 table lookups, and perform bitwise XOR on the obtained 256 table lookup results. The final result Bit0 ~ Bit5 is 256 byte data CP0 ~ CP5.
/ * Build up column parity * /
for ( i  = 0;  i  <256;  i ++) {
/ * Get CP0-CP5 from table * /
idx  =  nand_ecc_precalc_table [* dat ++];
reg1  ^ = ( idx  & 0x3f);
// Some omitted here, will be introduced later
}

reg1

Here, the process of calculating the column polarity is actually to calculate CP0 ~ CP5 within a byte of data. After each byte is calculated, it is XORed with the calculation results of other bytes. In Table 1, XOR is performed on a column of Bit0 first, and then a column of Bit2 is XORed. The two are different in the calculation order, and the results are consistent. Because the order of XOR operations is commutative.

 

 

The calculation of row polarity is more complicated.
nand_ecc_precalc_table [] Bit6 in the table has saved the row polarity value of each single-byte number. For the 256 bytes of data to be verified, look up the table separately. If the row polarity is 1, record the row index where the data is located (that is, the i value of the for loop). The row index here is very important because The calculation of RP0 ~ RP15 is closely related to the row index, such as RP0 only calculates even rows, RP1 only calculates odd rows, and so on.

 

 

       When writing data to the NAND Flash page, we generate an ECC checksum every 256 bytes, called the original ECC checksum, and save it in the OOB (out-of-band) data area of ​​PAGE.

   When reading data from NAND Flash, we generate an ECC checksum every 256 bytes, called the new ECC checksum.
       XOR the original ECC checksum and the new ECC checksum read from the OOB area, if the result is 0, it means that there is no error (or an error, an error that ECC cannot detect); if 3 words There are 11 bits in the XOR result as 1, indicating that there is a bit error, and it can be corrected; if there is only 1 bit in the 3 bytes XOR result as 1, indicating an error in the OOB area; all other cases indicate An uncorrectable error has occurred.

Suppose ecc_code_raw [3] saves the original ECC check code, ecc_code_new [3] saves the newly calculated ECC check code, the format is shown in the following table:

Bitwise XOR the ecc_code_raw [3] and ecc_code_new [3], and the resulting three bytes are stored in s0, s1, and s2, respectively. If there are 11 Bits in s0s1s2 as 1, it means that one bit has appeared. Errors can be corrected. The way to locate the bit in error is to first determine the row address (that is, which byte is wrong), and then determine the column address (that is, which Bit in the byte is wrong).

The method to determine the line address is:

Set the row address to unsigned char byteoffs, extract Bit7, Bit5, Bit3, Bit1 in s1 as the upper four bits of byteoffs, and extract Bit7, Bit5, Bit3, Bit1 in s0 as the lower four bits of byteoffs, then the value of byteoffs The line address of the error byte (range 0 ~ 255).

The method to determine the column address is:

Extract Bit7, Bit5, Bit3 in s2 as the lower three bits of bitnum, and the rest of bitnum is 0, then bitnum indicates the column address of the erroneous Bit bit (range 0 ~ 7).

An example is given at the end of the reference blog to help understanding.

Guess you like

Origin www.cnblogs.com/yysong8020/p/12751533.html