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.

NAND FLASH & JFFS2 file system probem

Hi,

I made a custom board based on the ipnc solution. I change the NAND flash from 32MB to 512MB because the solution said it supports a nand up to 4Gbit.

I use a partition as data storge in linux system. When linux mount mtdblock4 as a jffs2 file system, the following information appears:

//////////////////////////////////////////////////////////////

jffs2: Erase block size too small (128KiB). Using virtual blocks size (256KiB) instead

ECC_STATE_TOO_MANY_ERRS

mtd->read(0x400 bytes from 0x0) returned ECC error

//////////////////////////////////////////////////////////////

When writing files to this partition, there are many ecc errors, often the data is corrupted randomly.

The NAND type is K9F4G08U0M, with a 2k page and a 128k block.

I can't determine whether it is a driver or file system problem.

In u-boot, nand works fine when writing uImage and ramdisk. I check the nand configuration in linux kernel, which is the same to that in u-boot.

Here's the nand configuration in linux kernel,I thought there's no need to modify for the flash chip I select. Looking forward to your suggestions. Thanks!

///////////////////////////////////////////////////////////////////////////////////////////////////
#define NAND_BLOCK_SIZE (SZ_16K)
static struct mtd_partition nand_partitions[] = {
/* bootloader (UBL, U-Boot, BBT) in sectors: 0 - 14 */
{
.name = "bootloader",
.offset = 0,
.size = 24*NAND_BLOCK_SIZE,
.mask_flags = MTD_WRITEABLE, /* force read-only */
},
/* bootloader params in the next sector 15 */
{
.name = "params",
.offset = MTDPART_OFS_APPEND,
.size = 104*NAND_BLOCK_SIZE,
.mask_flags = MTD_WRITEABLE, /* force read-only */
},
/* kernel starts in sector 16 */
{
.name = "kernel",
.offset = MTDPART_OFS_APPEND,
.size = SZ_2M,
.mask_flags = 0
},
{
.name = "filesystem",
.offset = MTDPART_OFS_APPEND,
.size = SZ_16M+SZ_4M,
.mask_flags = 0
},
{
.name = "data",
.offset = MTDPART_OFS_APPEND,
.size = MTDPART_SIZ_FULL,
.mask_flags = 0
},
};

/* flash bbt decriptors */
static uint8_t nand_davinci_bbt_pattern[] = { 'B', 'b', 't', '0' };
static uint8_t nand_davinci_mirror_pattern[] = { '1', 't', 'b', 'B' };

static struct nand_bbt_descr nand_davinci_bbt_main_descr = {
.options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
| NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
.offs = 0,
.len = 4,
.veroffs = 5,
.maxblocks = 4,
.pattern = nand_davinci_bbt_pattern
};

static struct nand_bbt_descr nand_davinci_bbt_mirror_descr = {
.options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
| NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
.offs = 0,
.len = 4,
.veroffs = 5,
.maxblocks = 4,
.pattern = nand_davinci_mirror_pattern
};

static struct nand_davinci_platform_data nand_data = {
.options = 0,
.eccmode = NAND_ECC_HW10_512,//NAND_ECC_NONE,//NAND_ECC_HW3_512,//NAND_ECC_SOFT,//NAND_ECC_HW10_512,
.cle_mask = 0x10,
.ale_mask = 0x08,
.bbt_td = &nand_davinci_bbt_main_descr,
.bbt_md = &nand_davinci_bbt_mirror_descr,
.parts = nand_partitions,
.nr_parts = ARRAY_SIZE(nand_partitions),
};


static struct resource nand_resources[] = {
[0] = { /* First memory resource is AEMIF control registers */
.start = DM355_ASYNC_EMIF_CNTRL_BASE,
.end = DM355_ASYNC_EMIF_CNTRL_BASE + SZ_4K - 1,
.flags = IORESOURCE_MEM,
},
[1] ={ /* Second memory resource is NAND I/O window */
.start = DAVINCI_ASYNC_EMIF_DATA_CE0_BASE,
.end = DAVINCI_ASYNC_EMIF_DATA_CE0_BASE + SZ_16K - 1,
.flags = IORESOURCE_MEM,
},
};

static struct platform_device nand_device = {
.name = "nand_davinci",
.id = 0,
.dev = {
.platform_data = &nand_data
},

.num_resources = ARRAY_SIZE(nand_resources),
.resource = nand_resources,
};
////////////////////////////////////////////////////////////////////////////////////////////

  • I am able to boot with a JFFS2 RFS in nand if I write the RFS using u-boot.  I get ECC errors when using the SD tool to write the RFS.  Are you sure the partition size and locations in your kernel match the partitions on the nand?

    John A

  • Hi John,

    Thanks for your suggestion. I'm new in this area. What does it mean by  "the partition size and locations in your kernel match the partitions on the nand"? I thought the partitions in nand is defined by linux and they mapped to mtd devices in linux. I put UBL and u-boot in partition 0, and parameters of u-boot in partition 1, uImage is put in partition 2, and root filesystem(ramdisk.gz )is in partition 3. All these data is write to nand in u-boot. After the boot of linux  I want to mount partition 4 as a jffs2 filesystem for application data storage.

    I tried the method suggested in the post "DM365: Error in JFFS2 file system" . Do not use -p option when making jffs2 image, and use -p with nandwrite. But the following message still displayed when mounting the filesystem:

    //////////////////////////////////////////////////////////////////////////////////  
    # flash_eraseall -j /dev/mtd4

    Erasing 128 Kibyte @ 1fe0000 -- 99 % complete. Cleanmarker written at 1fe0000.

    #mkfs.jffs2 -e 0x20000 -l -s 0x800 -n -d ./test -o testfs.jffs2

    #nandwrite -p /dev/mtdblock4 ./testfs.jffs2

    #mount -t jffs2 /dev/mtdblock4 /mnt/nand
    ECC_STATE_TOO_MANY_ERRS
    mtd->read(0x400 bytes from 0x0) returned ECC error
    Empty flash at 0x00000080 ends at 0x000007d0
    jffs2_scan_eraseblock(): Node at 0x000007d0 {0x1985, 0x2003, 0xffff0008) has inv
    alid CRC 0xffffffff (calculated 0xd55a3519)
    jffs2_scan_eraseblock(): Magic bitmask 0x1985 not found at 0x000007d4: 0x0008 in
    stead
    ECC_STATE_TOO_MANY_ERRS
    mtd->read(0x30 bytes from 0x0) returned ECC error

    ////////////////////////////////////////////////////////////////////////////////

  • I was just saying that the kernel partitions have to match the way the UBL, u-boot, kernel, and file systems are written to the nand.  You are using a block size of 16K but the block size of your nand is 128k.  This is confusing to me.  I have a block size of 128k, which matches the type of nand I have.

    Since the ubl, u-boot, and kernel are loaded before linux is even started I'm guessing that it's only important that the file system on the nand is at the location the kernel expects.  For example, on my board I assume that u-boot is in the second partition.  I'm not sure why the u-boot parameters need their own partition.

    I remember that I needed to set erase block (-e) and page size (-s) to get a proper jffs2 image.

    John A