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.

JFFS2 Nand File System / AM3874 NAND configuration

Other Parts Discussed in Thread: AM3874

Hi all.

I'm trying to run Linux with JFFS2 root fs on custom board based on AM3874. The board has Macronix MX30LF1208AA 512M-bit NAND Flash Memory.

NAND is working fine under u-boot.

I prepared JFFS2 rootfs image according to processors.wiki.ti.com/.../AM335x_JFFS2_Support_Guide 

According to boot logs kernel detects NAND device, but when it tries to mount file system it reports errors

mtd->read(0x800 bytes from 0x1f800) returned ECC error
jffs2_scan_eraseblock(): Magic bitmask 0x1985 not found at 0x00000000: 0x854a instead
jffs2_scan_eraseblock(): Magic bitmask 0x1985 not found at 0x00000004: 0x2be0 instead
jffs2_scan_eraseblock(): Magic bitmask 0x1985 not found at 0x00000008: 0xe600 instead
jffs2_scan_eraseblock(): Magic bitmask 0x1985 not found at 0x0000000c: 0x017d instead
jffs2_scan_eraseblock(): Magic bitmask 0x1985 not found at 0x00000014: 0x0200 instead

After digging in driver's code I discovered that during read operation one redundant byte is transferred in a read buffer before real data.

Roorfs partition starts with 85 19 01 e0, but read buffer is filled with 4a 85 19 01 (or ff 85 19 01).

I understand that this is probably related to some mistake in NAND configuration, but just can't find what is wrong.

I hope somebody can help me with this.

  • Anatoly,

    AM387x ROM Code, u-boot and linux kernel comes with BCH8 ECC by default. For using JFFS2 you should switch back to HW Hamming ECC.

    Anatoly Goldstein said:
    I prepared JFFS2 rootfs image according to processors.wiki.ti.com/.../AM335x_JFFS2_Support_Guide 

    This might be AM335x specific. Please check if you are aligned with the JFFS2 requirements from the below wiki pages. AM387x device corresponds to DM81xx/TI81xx, DM814x/TI814x

    P.S. Usage of UBIFS file system is recommended.

    Regards,
    Pavel

  • See also the below e2e thread:

    e2e.ti.com/.../1169771

    Regards,
    Pavel
  • Thanks, Pavel.

    I already saw these wikis. Today I also tried to use UBIFS instead of JFFS2 and I got the same result, on read operation one redundant byte appears at first place in read buffer.

    So now I think this issue is not related to file system, but to NAND operation.

    Thanks,

    Anatoly

  • Pavel,

    Thanks for additional links, I reviewed them all, but now I'm pretty confident that my problem is not file system related.

    As I mentioned above the problem is replicated both with JFFS2 and UBIFS.

    I see that in function void omap_read_buf_pref() in omap2.c the first byte that is read by ioread32_rep(info->nand.IO_ADDR_R, p, r_count) is incorrect.

    Anatoly

  • Anatoly,

    How exactly you invoke the omap_read_buf_pref() function, is it from linux kernel or from user space?

    You can check also your NAND Flash for its ability to perform write access, read access and data storing ability. Refer to the Mistral web page:

    www.mistralsolutions.com/.../support-downloads
    Available Downloads for TMDXEVM8148
    Software -> Diagnostic software -> Base Board -> Rev D -> CCS_Code_BB -> src -> CCS_Test_code -> Base_Board -> NAND

    Regards,
    Pavel
  • Pavel,

    omap_read_buf_pref() is invoked from linux kernel during file system mounting.

    Anatoly
  • Anatoly Goldstein said:
    I see that in function void omap_read_buf_pref() in omap2.c the first byte that is read by ioread32_rep(info->nand.IO_ADDR_R, p, r_count) is incorrect.

    Can you provide more details on this? What is the incorrect value of the first byte? What is the value of the second byte?


    Do you have the below console output when using UBIFS?

    omap2-nand driver initializing
    ONFI param page 0 valid
    ONFI flash detected
    NAND device: Manufacturer ID: 0x2c, Chip ID: 0xca (Micron NAND 256MiB 3,3V 16-bit)
    omap2-nand: detected x16 NAND flash
    Creating 6 MTD partitions on "omap2-nand.0":
    0x000000000000-0x000000020000 : "U-Boot-min"
    0x000000020000-0x000000260000 : "U-Boot"
    0x000000260000-0x000000280000 : "U-Boot Env"
    0x000000280000-0x0000006c0000 : "Kernel"
    0x0000006c0000-0x00000cee0000 : "File System"
    0x00000cee0000-0x000010000000 : "Reserved"
    UBI: attaching mtd9 to ubi0
    UBI: physical eraseblock size:   131072 bytes (128 KiB)
    UBI: logical eraseblock size:    126976 bytes
    UBI: smallest flash I/O unit:    2048
    UBI: sub-page size:              512
    UBI: VID header offset:          2048 (aligned 2048)
    UBI: data offset:                4096
    ata1: SATA link down (SStatus 0 SControl 300)
    UBI: max. sequence number:       10
    UBI: attached mtd9 to ubi0
    UBI: MTD device name:            "File System"
    UBI: MTD device size:            200 MiB
    UBI: number of good PEBs:        1599
    UBI: number of bad PEBs:         2
    UBI: number of corrupted PEBs:   0
    UBI: max. allowed volumes:       128
    UBI: wear-leveling threshold:    4096
    UBI: number of internal volumes: 1
    UBI: number of user volumes:     1
    UBI: available PEBs:             0
    UBI: total number of reserved PEBs: 1599
    UBI: number of PEBs reserved for bad PEB handling: 15
    UBI: max/mean erase counter: 1/0
    UBI: image sequence number:  525469625
    UBI: background thread "ubi_bgt0d" started, PID 50

    UBIFS: recovery needed
    UBIFS: recovery completed
    UBIFS: mounted UBI device 0, volume 0, name "rootfs"
    UBIFS: file system size:   199225344 bytes (194556 KiB, 189 MiB, 1569 LEBs)
    UBIFS: journal size:       9023488 bytes (8812 KiB, 8 MiB, 72 LEBs)
    UBIFS: media format:       w4/r0 (latest is w4/r0)
    UBIFS: default compressor: lzo
    UBIFS: reserved for root:  0 bytes (0 KiB)
    VFS: Mounted root (ubifs filesystem) on device 0:14.

    Regards,
    Pavel

  • Hi, Pavel.

    Yesterday I fixed the problem, please see the changes in drivers/mtd/nand/omap2.c in attached diff.
    At least these changes do work for me.

    Before applying these changes I didn't have correct console output of UBIFS mounting

    as because of incorrect readings from NAND the system couldn't synchronize on UBIFS (or JFFS2) contents.

    Regarding the incorrect byte value (if it is still interesting) I mentioned it in my first post in this thread, it was either 4A or FF, but I think its just a garbage value.

    The next bytes were as they should be for UBIFS 55 42 49 43 (or 85 19 01 e0 for JFFS2).

    I think this thread can be closed now.

    Thanks,

    Anatoly

    diff --git a/Core/kernel/drivers/mtd/nand/nand_base.c b/Core/kernel/drivers/mtd/nand/nand_base.c
    index a796dd7..41f31bf 100644
    --- a/Core/kernel/drivers/mtd/nand/nand_base.c
    +++ b/Core/kernel/drivers/mtd/nand/nand_base.c
    @@ -3133,7 +3133,8 @@ ident_done:
     				(*maf_id == NAND_MFR_SAMSUNG ||
     				 *maf_id == NAND_MFR_HYNIX ||
     				 *maf_id == NAND_MFR_TOSHIBA ||
    -				 *maf_id == NAND_MFR_AMD)) ||
    +				 *maf_id == NAND_MFR_AMD ||
    +				 *maf_id == NAND_MFR_MACRONIX)) ||
     			(mtd->writesize == 2048 &&
     			 *maf_id == NAND_MFR_MICRON))
     		chip->options |= NAND_BBT_SCAN2NDPAGE;
    diff --git a/Core/kernel/drivers/mtd/nand/nand_ids.c b/Core/kernel/drivers/mtd/nand/nand_ids.c
    index 00cf1b0..18f68f3 100644
    --- a/Core/kernel/drivers/mtd/nand/nand_ids.c
    +++ b/Core/kernel/drivers/mtd/nand/nand_ids.c
    @@ -78,6 +78,7 @@ struct nand_flash_dev nand_flash_ids[] = {
     	{"NAND 64MiB 1,8V 8-bit",	0xA0, 0,  64, 0, LP_OPTIONS},
     	{"NAND 64MiB 3,3V 8-bit",	0xF2, 0,  64, 0, LP_OPTIONS},
     	{"NAND 64MiB 3,3V 8-bit",	0xD0, 0,  64, 0, LP_OPTIONS},
    +	{"NAND 64MiB 3,3V 8-bit",   0xF0, 0,  64, 0, LP_OPTIONS},
     	{"NAND 64MiB 1,8V 16-bit",	0xB2, 0,  64, 0, LP_OPTIONS16},
     	{"NAND 64MiB 1,8V 16-bit",	0xB0, 0,  64, 0, LP_OPTIONS16},
     	{"NAND 64MiB 3,3V 16-bit",	0xC2, 0,  64, 0, LP_OPTIONS16},
    @@ -176,6 +177,7 @@ struct nand_manufacturers nand_manuf_ids[] = {
     	{NAND_MFR_HYNIX, "Hynix"},
     	{NAND_MFR_MICRON, "Micron"},
     	{NAND_MFR_AMD, "AMD"},
    +	{NAND_MFR_MACRONIX, "Macronix"},
     	{0x0, "Unknown"}
     };
     
    diff --git a/Core/kernel/drivers/mtd/nand/omap2.c b/Core/kernel/drivers/mtd/nand/omap2.c
    index 8633fea..9ceba8a 100644
    --- a/Core/kernel/drivers/mtd/nand/omap2.c
    +++ b/Core/kernel/drivers/mtd/nand/omap2.c
    @@ -833,15 +833,12 @@ static int omap_read_page_bch(struct mtd_info *mtd, struct nand_chip *chip,
     				oob += eccbytes) {
     		chip->ecc.hwctl(mtd, NAND_ECC_READ);
     		/* read data */
    -		chip->cmdfunc(mtd, NAND_CMD_RNDOUT, data_pos, page);
    +		chip->cmdfunc(mtd, NAND_CMD_RNDOUT, data_pos, -1);
     		chip->read_buf(mtd, p, eccsize);
     
     		/* read respective ecc from oob area */
    -		chip->cmdfunc(mtd, NAND_CMD_RNDOUT, oob_pos, page);
    -		if (info->ecc_opt == OMAP_ECC_BCH8_CODE_HW)
    -			chip->read_buf(mtd, oob, 13);
    -		else
    -			chip->read_buf(mtd, oob, eccbytes);
    +		chip->cmdfunc(mtd, NAND_CMD_RNDOUT, oob_pos, -1);
    +		chip->read_buf(mtd, oob, eccbytes);
     		/* read syndrome */
     		chip->ecc.calculate(mtd, p, &ecc_calc[i]);
     
    diff --git a/Core/kernel/include/linux/mtd/nand.h b/Core/kernel/include/linux/mtd/nand.h
    index 63e17d0..fc3f622 100644
    --- a/Core/kernel/include/linux/mtd/nand.h
    +++ b/Core/kernel/include/linux/mtd/nand.h
    @@ -554,6 +554,7 @@ struct nand_chip {
     #define NAND_MFR_HYNIX		0xad
     #define NAND_MFR_MICRON		0x2c
     #define NAND_MFR_AMD		0x01
    +#define NAND_MFR_MACRONIX   0xc2
     
     /**
      * struct nand_flash_dev - NAND Flash Device ID Structure