Search code examples
clinuxgccu-boot

Why u-boot always mark writed block as bad?


I'm developing an nand flash driver of u-boot. I think it works well but the environment of u-boot doesn't work properly. Here is what i have done for testing:

  1. Erase the whole nand flash by code purely coded by myself, these codes are not related to u-boot. And no bad blocks found. (Is it possible for a nand flash to have no bad block?). Here is the code

    void nand_erase(u32 addr)
    {   
        if (addr & (BLOCK_SIZE - 1))
        {
            printf("not block align\n");
            return;
        }
        u32 row = addr / 2048;
    
        nand_select_chip();
        nand_cmd(0x60);
    
        NFADDR = row & 0xFF;            
        NFADDR = (row >> 8) & 0xFF;
        NFADDR = (row >> 16) & 0x07;
    
        nand_cmd(0xD0);
        nand_wait_ready();
    
        nand_cmd(0x70);
        u8 status = nand_read();
        if (status & 0x01)
        {
            printf("block 0x%x is bad", addr);
        }
    
        nand_deselect_chip();
    }
    
  2. Start u-boot, it prompt"bad CRC ,using default environment".

  3. Now i use "setenv test 100" and "printenv test", it works well, and "saveenv", it prompt "OK" as well.

  4. And i use "nand bad", it shows nothing.

  5. Restart the board and u-boot

  6. Now it says that "readenv() failed, using default environment".

  7. And i "printenv test", it fails. Then i chekced "nand bad", it shows a bad block exactly at "CONFIG_ENV_OFFSET"

  8. Then i changed CONFIG_ENV_OFFSET to another value. and repeat step 1-7. It will shows a bad block again at the new CONFIG_ENV_OFFSET.

I've checked my driver, the write operation and read operation are good i think. The steps are here:

  1. "nand dump 0" , and it shows all 0xff

  2. "nand write 20000000 0 800" to write memory into nand flash.

  3. Then "nand dump 0", it shows the same values as "md 20000000 100" does.

So, you can see that after saveenv, the block at CONFIG_ENV_OFFSET will be marked as bad, I really don't know why


Solution

  • Now i figure out. I set ecc.mode = NAND_ECC_HW_SYNDROME, But XXX_syndrome function doesn't maintain ecc layout. It just simply write ecc after main data. Finally it will override the first and second bytes of oob area in each page , but u-boot check these two bytes as bad block marker, so here is the answer.