This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

fw_printenv Bad CRC problem in dm6446+nand

I plan to use fw_printenv to modify u-boot envirioment variables like ethaddr,ipaddr, etc.
u-boot version: 1.3.4, kernel verion: 2.6.18 from lsp2.0
after fw_printenv tool was configed and builded, it says : Warning: "Bad CRC, using default environment" when running.
I failed to resovle the problem after reading the codes and gdb debugging in ccs5 for the whole afternoon.
I believe the result should be ok as long as the offset and size are correst.
offset in nand is 0 and size is 0x20000 in my configuration.

The offset can be verified in u-boot command line by following command:
nand read 0x80800000 0 0x20000
md 0x80800000
80800000: 2217238b 746f6f62 616c6564 00323d79 .#."bootdelay=2.
80800010: 64756162 65746172 3531313d 00303032 baudrate=115200.
80800020: 61687465 3d726464 303a3030 39393a45 ethaddr=00:0E:99
80800030: 3a46453a 323a4645 666e0032 736f6873 :EF:EF:22.nfshos
80800040: 39313d74 36312e32 2e302e38 6f620033 t=192.168.0.3.bo
.........

The length can read in the end of printenv command:
Environment size: 955/131068 bytes

GDB debuging fw_printenv in ccs, I found fw_printenv read first 4 bytes in environment.crc, and following 0x20000-4 in environment.data.
function crc32 run through environment.data,len = 0x20000-4=131068 bytes.

Why still got Bad CRC when both offset and length are correct?Did i miss some key point?

Following are configurations:

u-boot-1.3.4/include/configs/davinci_dvevm.h:
#define CFG_ENV_SECT_SIZE 2048 /* Env sector Size */
#define CFG_ENV_SIZE SZ_128K
#define CFG_NAND_BASE 0x02000000
#define CFG_ENV_OFFSET 0x0 /* Block 0--not used by bootcode */
 
u-boot-1.3.4/tools/env/fw_env.h:
//#define CONFIG_FILE     "/etc/fw_env.config"
//#define HAVE_REDUND /* For systems with 2 env sectors */
#define DEVICE1_NAME      "/dev/mtd0"
//#define DEVICE2_NAME      "/dev/mtd2"
#define DEVICE1_OFFSET    0x0000
#define ENV1_SIZE         0x20000
#define DEVICE1_ESIZE     0x20000
//#define DEVICE2_OFFSET    0x0000
//#define ENV2_SIZE         0x4000
//#define DEVICE2_ESIZE     0x4000
 
mtd partition defination in lsp-2.0/arch/arm/mach-davinci/board-evm.c
static struct mtd_partition davinci_nand_partitions[] = {
/* bootloader (U-Boot and paras) in first sector */
{
.name = "bootloader",
.offset = 0,
.size = SZ_1M,//SZ_256K,
.mask_flags = MTD_WRITEABLE, /* force read-only */
},
.....

 Best regards,

Zhang Jianjun

  • Problem resolved. It 's caused by ECC not CRC32. 

    nand dump the oob of first two pages which saving u-boot enviroments:

    after fw_setenv running in lsp2.0, the oob looks like this:

    ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
    ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
    ff ff ff ff ff ff ff ff b2 b2 ee 21 21 ff 9a 65
    1e 00 00 00 ff ff ff ff ff ff ff ff ff ff ff ff
     
    ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
    ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
    ff ff ff ff ff ff ff ff 00 00 00 00 00 00 00 00
    00 00 00 00 ff ff ff ff ff ff ff ff ff ff ff ff
     
    after saveenv in u-boot 1.3.4 from dvsdk2.1, the oob looks like this:
           ff ff ff ff ff ff ff ff        17 17 33 ff ff ff ff ff
            ff ff ff ff ff ff ff ff        00 00 00 ff ff ff ff ff
            ff ff ff ff ff ff ff ff        00 00 00 ff ff ff ff ff
            ff ff ff ff ff ff ff ff        00 00 00 ff ff ff ff ff

            ff ff ff ff ff ff ff ff        00 00 00 ff ff ff ff ff
            ff ff ff ff ff ff ff ff        00 00 00 ff ff ff ff ff
            ff ff ff ff ff ff ff ff        00 00 00 ff ff ff ff ff
            ff ff ff ff ff ff ff ff        00 00 00 ff ff ff ff ff

    after saveenv in u-boot 2009.03 from davinci-psp_3.x.0.0-r37 or u-boot 2013.10 from git.denx.de, oob look like this:

    ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
    ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
    ff ff ff ff ff ff ff ff 4d d1 14 de e0 0d 5f 01
    ea ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
     
    ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
    ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
    ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
    ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff

  • check drivers/mtd/nand/davinci_nand.c in u-boot 2013.10, following comments explains something:

    static int nand_davinci_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
    u_char *ecc_code)
    {
    u_int32_t tmp;

    tmp = nand_davinci_readecc(mtd);

    /* Squeeze 4 bytes ECC into 3 bytes by removing RESERVED bits
    * and shifting. RESERVED bits are 31 to 28 and 15 to 12. */
    tmp = (tmp & 0x00000fff) | ((tmp & 0x0fff0000) >> 4);

    /* Invert so that erased block ECC is correct */
    tmp = ~tmp;

    *ecc_code++ = tmp;
    *ecc_code++ = tmp >> 8;
    *ecc_code++ = tmp >> 16;

    /* NOTE: the above code matches mainline Linux:
    * .PQR.stu ==> ~PQRstu
    *
    * MontaVista/TI kernels encode those bytes differently, use
    * complicated (and allegedly sometimes-wrong) correction code,
    * and usually shipped with U-Boot that uses software ECC:
    * .PQR.stu ==> PsQRtu
    *
    * If you need MV/TI compatible NAND I/O in U-Boot, it should
    * be possible to (a) change the mangling above, (b) reverse
    * that mangling in nand_davinci_correct_data() below.
    */

    return 0;
    }

    check code from git://gitorious.org/linux-davinci/linux-davinci.git, 
    ECC alg in drivers/mtd/nand/davinci_drivers.c since 2.6.31 looks same above.

    my solutions:

    modify two functions in drivers/mtd/nand/davinci.c in lsp2.0 or davinci_nand.c in lsp2.1 according to u-boot 2013.10 or linux-davinci 2.6.32.1:
    nand_davinci_1bit_calculate_ecc()
    nand_davinci_1bit_correct_data()