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.

Linux/OMAP-L138: Linux/OMAP-L138: How to flash Linux kernel into NAND-Flash partition from Linux

Part Number: OMAP-L138
Other Parts Discussed in Thread: OMAP-L132

Tool/software: Linux

I have to update (write) a new Linux kernel into NAND-Flash partition from a running Linux system.

To write into partition 2 of NAND-Flash I use the program "nandwrite" with option "-p":

nandwrite /dev/mtd -p <Image>

But after that my board does not start up; the bootloader "u-boot" the bootloader complains about CRC error loading the kernel.

I'm using the "4 Bit HW ECC correction" for the NAND-Flash in the bootloader and in the Linux kernel.

For bootloader "u-boot" there are defined:

#undef CONFIG_SYS_NAND_HW_ECC
#define CONFIG_SYS_NAND_4BIT_HW_ECC_OOBFIRST
#define CONFIG_SYS_NAND_USE_FLASH_BBT

For Linux kernel (in board specific file) there are defined:

static struct davinci_aemif_timing gins_qmonixx_nand_timing = {
    // All timings in nanoseconds
    .wsetup = 10,
    .wstrobe = 20,
    .whold = 0,
    .rsetup = 10,
    .rstrobe = 20,
    .rhold = 20, // For reliable 16-bit NAND operations R_HOLD must be set to 1 to ensure 2 clock cycles for ECC calculation
    .ta = 60,
};

static struct davinci_nand_pdata gins_qmonixx_nand_pdata = {
    .parts = gins_qmonixx_nand_parts,
    .nr_parts = ARRAY_SIZE(gins_qmonixx_nand_parts),
    .options = NAND_BUSWIDTH_16,
    .timing = &gins_qmonixx_nand_timing,
    
    // Configuration for ECC
    // See also configuration for U-Boot: CONFIG_SYS_NAND_4BIT_HW_ECC_OOBFIRST, CONFIG_SYS_NAND_USE_FLASH_BBT
    .ecc_mode = NAND_ECC_HW,    // do not use NAND_ECC_HW_OOB_FIRST here!
    .ecc_bits = 4,
    .bbt_options = NAND_BBT_USE_FLASH,
};

What could be the problem?

Remark:
If I write the Linux kernel with help of the bootloader "u-boot" into the NAND flash, then the system is started successfully!

Thanks for your help in advance!
Jan-Marc.

  • Hi Jan-Mark,

    The MTDUtils, which you use are the recommended tool for writing to nand flash partitions. Have a look at the wiki:
    processors.wiki.ti.com/.../Mtdutils
    Maybe you're using the wrong command. Check the above link.

    Best Regards,
    Yordan
  • Hi Yordan,

    thank you for your quick answer; but that did not really help me.

    I've double checked the initialisation for the NAND-Flash on EMIF CS3 in the bootloader "u-boot" and the Linux kernel:
    - the timing settings (here EMIF register "A2CR" respectively "CE3CFG")
    - the settings for the ECC mode in "drivers/mtd/nand/davinci_nand.c"

    I have also taken note of the following:

    "For reliable 16-bit NAND operations R_HOLD must be set to 1 to ensure 2 clock cycles for ECC calculation!"

    I have inserted messages in the source code and I get the following during Linux kernel startup:

    ...
    EMIFA CS3, A2CR = 0x0010009d
        SS = 0
        EW = 0
        W_SETUP = 0
        W_STROBE = 1
        W_HOLD = 0
        R_SETUP = 0
        R_STROBE = 1
        R_HOLD = 1
        TA = 3
        ASIZE = 1
    ...
    nand: device found, Manufacturer ID: 0x2c, Chip ID: 0xcc
    nand: Micron MT29F4G16ABADAH4
    nand: 512 MiB, SLC, erase size: 128 KiB, page size: 2048, OOB size: 64
    davinci_nand davinci_nand.1: chip.ecc.mode = NAND_ECC_HW_OOB_FIRST
    davinci_nand davinci_nand.1: chip.ecc.strength = 4Bit
    davinci_nand davinci_nand.1: chip.ecc.size = 512
    davinci_nand davinci_nand.1: chip.ecc.bytes = 10
    davinci_nand davinci_nand.1: chip.ecc.layout.eccbytes = 40
    davinci_nand davinci_nand.1: chip.ecc.layout.eccpos = 24, ..., 63
    davinci_nand davinci_nand.1: chip.ecc.layout.oobavail = 0
    ...

    I've also used the test program from "mtd-utils" (e.g. "nandbiterrs" or "nandpagetest" or "flash_readtest").
    I 'm always getting error messages; for example:

    root@qmonixx:~# /usr/libexec/mtd-utils/flash_readtest /dev/mtd0
    testing page read
    libmtd: error!: Cannot write 64 OOB bytes to address 512 (OOB offset 512) - mtd0 OOB size is only 64 bytes
    Error reading OOB in block 0, page 1

    I urge for help.
    I would be grateful for any hint!

    Best regards,
    Jan-Marc.

     

  • Hi Jan-Marc,

    Are you using the latest Processor SDK Linux:
    www.ti.com/.../processor-sdk-omapl138

    Best Regards,
    Yordan
  • Hi Yordan!

    Thank you for your reply.

    We do not use the TI SDK.
    We create the BSP (bootloader "u-boot", Linux kernel and root filesystem) using "YoctoProject".

    The current version of bootloader "u-boot" is "2017.07"
    The current version of the kernel is "4.4.25"
    We are using a "mainline linux kernel" from "kernel.org".

    There must be a difference in the handling of NAND flash between the bootloder and the Linux kernel.
    Maybe the difference can be found in the file "drivers/mtd/nand/davinci_nand.c".
    Unfortunately, I have no idea how to solve the problem.

    I know that TI maintains its own version of the Linux kernel ("ti-linux") and of the bootloader "u-boot" ("ti-uboot").
    Has the problem been handled in these versions?
    Can you tell me in which version of "ti-linux" or "ti-u-boot" the problem was solved?

    I would be grateful for any advice!

    Best regards,
    Jan-Marc.
  • Hi Jan-Marc,

    Has the problem been handled in these versions?
    Can you tell me in which version of "ti-linux" or "ti-u-boot" the problem was solved?


    I've not received a complain about such behaviour and cannot tell you if TI release will experience it. What you can do is compare the kernel/u-boot drivers, but they should be the same. In my opinion the problem is with the nand configuration in your dts file.

    You can see how the nand is set in da850-lcdk.dts:
    &aemif {
    pinctrl-names = "default";
    pinctrl-0 = <&nand_pins>;
    status = "okay";
    cs3 {
    #address-cells = <2>;
    #size-cells = <1>;
    clock-ranges;
    ranges;

    ti,cs-chipselect = <3>;

    nand@2000000,0 {
    compatible = "ti,davinci-nand";
    #address-cells = <1>;
    #size-cells = <1>;
    reg = <0 0x02000000 0x02000000
    1 0x00000000 0x00008000>;

    ti,davinci-chipselect = <1>;
    ti,davinci-mask-ale = <0>;
    ti,davinci-mask-cle = <0>;
    ti,davinci-mask-chipsel = <0>;

    ti,davinci-nand-buswidth = <16>;
    ti,davinci-ecc-mode = "hw";
    ti,davinci-ecc-bits = <4>;
    ti,davinci-nand-use-bbt;

    /*
    * The OMAP-L132/L138 Bootloader doc SPRAB41E reads:
    * "To boot from NAND Flash, the AIS should be written
    * to NAND block 1 (NAND block 0 is not used by default)".
    * The same doc mentions that for ROM "Silicon Revision 2.1",
    * "Updated NAND boot mode to offer boot from block 0 or block 1".
    * However the limitaion is left here by default for compatibility
    * with older silicon and because it needs new boot pin settings
    * not possible in stock LCDK.
    */
    partitions {
    compatible = "fixed-partitions";
    #address-cells = <1>;
    #size-cells = <1>;

    partition@0 {
    label = "u-boot env";
    reg = <0 0x020000>;
    };
    partition@0x020000 {
    /* The LCDK defaults to booting from this partition */
    label = "u-boot";
    reg = <0x020000 0x080000>;
    };
    partition@0x0a0000 {
    label = "free space";
    reg = <0x0a0000 0>;
    };
    };
    };
    };
    };

    Make sure you use the same settings in your kernel.

    Best Regards,
    Yordan