i.MX6Q NAND boot issues

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

i.MX6Q NAND boot issues

6,627 Views
timharvey
Contributor IV

Greetings,

I'm trying to get a custom i.MX6Q board to boot from NAND without any luck.

The NAND is a Micron MT29F2G08ABAEA:

- ONFI 1.0 compliant (async)

- SLC

- x8 device

- Page size: 2112 bytes (2048 + 64 oob)

- Block size: 64 pages (128K + 4K)

- Plane size: 2 planes x 1024 blocks per plane

- Device size: 2Gb: 2048 blocks (256MB)

We have the following pads from the i.MX6Q connected to the IO signals on the NAND:

  IMX6Q_NANDF_D[0:7]  <-> IO[0:7]

  IMX6Q_NANDF_CS0 <-> CE#

  IMX6Q_NANDF_ALE <-> ALE

  IMX6Q_NANDF_CLE <-> CLE

  IMX6Q_NANDF_R/B <-> R/B

  IMX6Q_NANDF_WP <-> WP

  IMX6Q_NANDF_SD4_CMD <-> RE#

  IMX6Q_NANDF_SD4_CLK  <-> WE#

(As this is an asynchronous NAND there is no DQS signal connected)

The am able to boot via USB/OTG read/write the NAND from my bootloader as well as my Linux kernel/rootfs and have successfully run 1000's of iterations of the linux nandtest app without any failures and am using the kobs-ng (v1.3) utility from the Freescale SDK to program my uboot to a 10MB /dev/mtd0 partition.  I am usbing the uboot 'bmode' command to change the boot mode and soft-reset the device to successfully boot to usdhc3 and SATA yet the same method is not working for booting to NAND.  I did find that I needed to blow the BT_FUSE_SEL eFUSE in order to use uboot's bmode command (otherwise the boot ROM would always boot to the serial downloader).  I believe the correct setting for BOOT_CFG[1:4] for my configuations (64 pages per block, 5 addr cycles) is 0x82020000 however I have also tried other various BOOT_CFG's without success.

Looking at the signals with a scope I find that when I boot my uboot (which has NAND support) over USB/OTG serial-downloader I see a flurry of NAND_CS0 activity as expected when the nand driver is identifying the device.  Yet when I attempt to boot to NAND I only see 2 sets of 4 CS0 assertions over a 10ms period.  I then notice that while I still see the 0x15a2:0x0054 Freescale device on my host PC connected to the i.MX6 USB OTG I can not boot over it, which makes me think the i.MX6 boot ROM is 'hung'.  Because I'm seeing so little chip-select activity I can't believe this has anything to do with the contents of my NAND device but rather something to do with how the boot ROM is configured.

Does anyone have any advice as to what can be going wrong here?

Thanks,

Tim

9 Replies

1,770 Views
VladanJovanovic
NXP Employee
NXP Employee

ROM address 0x000000d0 contains pointer to internal RAM location where boot log buffer is stored. Can you send first 256 bytes of that buffer for check?


Also hexdump of the NAND device would be interesting to see.

0 Kudos

1,770 Views
timharvey
Contributor IV

Here is a dump of the memory regions from OpenOCD:

> mdw 0xd0
0x000000d0: 00902190 
> mdb 0x902190 256
0x00902190: 00 00 01 00 f0 00 02 00 00 00 03 00 01 00 04 00 01 00 05 00 00 00 06 00 00 00 07 00 f0 00 07 00 
0x009021b0: 00 00 08 00 00 11 00 00 f0 00 08 00 00 00 09 00 33 05 0a 00 ff 1f 06 00 00 00 0c 00 00 00 00 00 
0x009021d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
0x009021f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
0x00902210: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
0x00902230: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
0x00902250: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
0x00902270: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 

This is taken after halting the cpu following booting via serial downloader and issuing a 'bmode nand' which writes:

0x020d8040=0x00000880

0x020d8044=0x10000000

TIm

0 Kudos

1,770 Views
VladanJovanovic
NXP Employee
NXP Employee

OK, so steps at the end go like:

- internal ROM loads page number 0x1100, which according to my calculation translates to addr. 0x880000 where, according to kobs-ng output, you have a backup (second) copy of u-boot.imx stored.

- read goes OK

- authentication process is started

- authentication fails due to invalid IVT

- internal ROM jumps to serial downloader code

So first thing would be to check 0x880000 in NAND to see whether u-boot binary is stored well there. Then check if IVT table is well formed. Also, do you have HAB security enabled on these protos or not?

1,770 Views
TonyRiederer
Contributor III

Is there any documentation available on interpreting the ROM log buffer contents?

0 Kudos

1,770 Views
timharvey
Contributor IV

No - I'm not using HAB.


Your analysis of the boot ROM data told me that I was wrong about so few NAND_CS0 transitions telling me that the boot ROM wasn't even loading my data.  I found on another thread here https://community.freescale.com/message/303710#303710 that the boot ROM puts your boot data at 0x907400 and when I dumped that I realized it 'did' contain my bootloader data and not the IVT.  Then I recalled the magic 1K offset and realized I am supposed to be putting my u-boot.imx at 0x400 within /dev/mtd0 and sure enough there is a '-x' option in kobs-ng that does that.


So once I use the following I can boot from NAND successfully:

root@imx6q:~# flash_eraseall /dev/mtd0

flash_eraseall has been replaced by `flash_erase0 0`; please use it

Erasing 128 Kibyte @ fe0000 -- 100 % complete

root@imx6q:~# kobs-ng init -x -v u-boot.imx


Is there some documentation that explains more about how to debug the boot ROM using these memory addresses?


Thank you for your help!

Tim

1,770 Views
timharvey
Contributor IV

before I blow eFuses, I want to make sure I have selected the correct settings for the NAND device I've described above.

I see that Table 5-9 (NAND Boot Fusemap) and Table-11 (NAND Boot eFUSE Descriptions) in the i.MX6QRM contradict each other in one case and don't offer much description in others.

BOOT_CFG1[1:0] - For the NAND device I have detailed above, there appear to me to be 3 address bytes - what should the correct value be (the two tables contradict each other)


BOOT_CFG2[7:5] - I assume for raw NAND the value here is a don't care?


BOOT_CFG2[4:3] - What are the recommendations for BOOT_SEARCH_COUNT?  I assume the more you specify the more robust your boot will be allowing for more bad block failures.  I also assume that the value here must dictate the value given to the --search_exponent specified in kobs-ng?  For example If you choose the default of 2 retires (BOOT_CFG2[4:3] = 00) would you use --search_exponent=1 (2^1=2) which writes 2 sets of FCB/DBBT headers to NAND and if you chose BOOT_CFG2[4:3] = 11 for 8 retries would you use --search_exponent=3 (2^3=8)?

BOOT_CFG2[2:1] - Pages In Block - is this somehow used to calculate 'search stride' and if so how?

Thanks,

Tim

0 Kudos

1,770 Views
VladanJovanovic
NXP Employee
NXP Employee

For BOOT_CFG1[1:0] , correct values seem to be 3,2,4,5, but I'll need to verify that first.

BOOT_CFG2[7:5] you should leave at default. Used for toggle mode DDR NAND only.

For BOOT_CFG2[4:3] I'm not entirely sure how it is supported in kobs-ng, so I'd leave it as such. In theory it would allow for more reliable boot, true. As kobs-ng above writes 4 copies of DBBT, it seems to be safe to put this to 10 (4).

BOOT_CFG2[2:1] - this is defined by NAND device and is 64 for device you chose. Yes, this is used to calculate search stride as, for example, two copies of DBBT can't be stored in same block (entire block is erased during erase operation for NAND). You can see that kobs-ng in your case stores FCBx and DBBTx at 0x20000 (128k) offsets, which is block size for your NAND.

1,770 Views
VladanJovanovic
NXP Employee
NXP Employee

Took some time but here's correct answer for BOOT_CFG[1:0] :

ROM maps 00 01 10 11 to 3 2 4 5.

So Table 8-11 in reference manual is correct.

Vladan

0 Kudos

1,770 Views
timharvey
Contributor IV

Vladan,

I'm still working on getting a JTAG adapter on the board to pull the boot ROM buffer for you.

here is a log showing how I'm putting my bootloader on NAND and the hexdump:

root@imx6q:~# cat /proc/mtd
dev:    size   erasesize  name
mtd0: 01000000 00020000 "u-boot"
mtd1: 00020000 00020000 "env"
mtd2: 00200000 00020000 "kernel"
mtd3: 0ede0000 00020000 "rootfs"
root@imx6q:~# flash_eraseall /dev/mtd0
flash_eraseall has been replaced by `flash_erase0 0`; please use it
Erasing 128 Kibyte @ fe0000 -- 100 % complete 
root@imx6q:~# kobs-ng | head -n1
kobs-ng version : [ 1.3 ] git hash (3.0.35-4.0.0)
root@imx6q:~# kobs-ng init -v u-boot.imx 
MTD CONFIG:
  chip_0_device_path = "/dev/mtd0"
  chip_1_device_path = "(null)"
  search_exponent = 2
  data_setup_time = 80
  data_hold_time = 60
  address_setup_time = 25
  data_sample_time = 6
  row_address_size = 3
  column_address_size = 2
  read_command_code1 = 0
  read_command_code2 = 48
  boot_stream_major_version = 1
  boot_stream_minor_version = 0
  boot_stream_sub_version = 0
  ncb_version = 3
  boot_stream_1_address = 0
  boot_stream_2_address = 0
u-boot.imx: verifying using key '00000000000000000000000000000000'
u-boot.imx: is a valid bootstream for key '00000000000000000000000000000000'
mtd: opening: "/dev/mtd0"
NFC geometry :
        ECC Strength       : 8
        Page Size in Bytes : 2112
        Metadata size      : 10
        ECC Chunk Size in byte : 512
        ECC Chunk count        : 4
        Block Mark Byte Offset : 1999
        Block Mark Bit Offset  : 0
====================================================
mtd: opened '/dev/mtd0' - '(null)'
mtd: max_boot_stream_size_in_bytes = 7864320
mtd: boot_stream_size_in_bytes = 425236
mtd: boot_stream_size_in_pages = 208
mtd: #1 0x00100000 - 0x00880000 (0x00167d14)
mtd: #2 0x00880000 - 0x01000000 (0x008e7d14)
FCB
  m_u32Checksum = 0x00000000
  m_u32FingerPrint = 0x20424346
  m_u32Version = 0x01000000
  m_NANDTiming.m_u8DataSetup = 80
  m_NANDTiming.m_u8DataHold = 60
  m_NANDTiming.m_u8AddressSetup = 25
  m_NANDTiming.m_u8DSAMPLE_TIME = 6
  m_u32PageDataSize = 2048
  m_u32TotalPageSize = 2112
  m_u32SectorsPerBlock = 64
  m_u32NumberOfNANDs = 0
  m_u32TotalInternalDie = 0
  m_u32CellType = 0
  m_u32EccBlockNEccType = 4
  m_u32EccBlock0Size = 512
  m_u32EccBlockNSize = 512
  m_u32EccBlock0EccType = 4
  m_u32MetadataBytes = 10
  m_u32NumEccBlocksPerPage = 3
  m_u32EccBlockNEccLevelSDK = 0
  m_u32EccBlock0SizeSDK = 0
  m_u32EccBlockNSizeSDK = 0
  m_u32EccBlock0EccLevelSDK = 0
  m_u32NumEccBlocksPerPageSDK = 0
  m_u32MetadataBytesSDK = 0
  m_u32EraseThreshold = 0
  m_u32Firmware1_startingPage = 512
  m_u32Firmware2_startingPage = 4352
  m_u32PagesInFirmware1 = 208
  m_u32PagesInFirmware2 = 208
  m_u32DBBTSearchAreaStartAddress = 256
  m_u32BadBlockMarkerByte = 1999
  m_u32BadBlockMarkerStartBit = 0
  m_u32BBMarkerPhysicalOffset = 2048
  m_u32BCHType = 0
  m_NANDTMTiming.m_u32TMTiming2_ReadLatency = 0
  m_NANDTMTiming.m_u32TMTiming2_PreambleDelay = 0
  m_NANDTMTiming.m_u32TMTiming2_CEDelay = 0
  m_NANDTMTiming.m_u32TMTiming2_PostambleDelay = 0
  m_NANDTMTiming.m_u32TMTiming2_CmdAddPause = 0
  m_NANDTMTiming.m_u32TMTiming2_DataPause = 0
  m_NANDTMTiming.m_u32TMSpeed = 0
  m_NANDTMTiming.m_u32TMTiming1_BusyTimeout = 0
  m_u32DISBBM = 0
DBBT
  m_u32Checksum = 0x00000000
  m_u32FingerPrint = 0x54424244
  m_u32Version = 0x01000000
  m_u32DBBTNumOfPages = 0
Firmware: image #0 @ 0x100000 size 0x68000 - available 0x780000
Firmware: image #1 @ 0x880000 size 0x68000 - available 0x780000
-------------- Start to write the [ FCB ] -----
mtd: erasing @0:0x0-0x20000
mtd: Writing FCB0 [ @0:0x0 ] (840) *
mtd: erasing @0:0x20000-0x40000
mtd: Writing FCB1 [ @0:0x20000 ] (840) *
mtd: erasing @0:0x40000-0x60000
mtd: Writing FCB2 [ @0:0x40000 ] (840) *
mtd: erasing @0:0x60000-0x80000
mtd: Writing FCB3 [ @0:0x60000 ] (840) *
mtd_commit_bcb(FCB): status 0

-------------- Start to write the [ DBBT ] -----
mtd: erasing @0:0x80000-0xa0000
mtd: Writing DBBT0 [ @0:0x80000 ] (800) *
mtd: erasing @0:0xa0000-0xc0000
mtd: Writing DBBT1 [ @0:0xa0000 ] (800) *
mtd: erasing @0:0xc0000-0xe0000
mtd: Writing DBBT2 [ @0:0xc0000 ] (800) *
mtd: erasing @0:0xe0000-0x100000
mtd: Writing DBBT3 [ @0:0xe0000 ] (800) *
mtd_commit_bcb(DBBT): status 0

---------- Start to write the [ u-boot.imx ]----
mtd: Writting u-boot.imx: #0 @0: 0x00100000 - 0x00168000
mtd: erasing @0:0x100000-0x120000
mtd: erasing @0:0x120000-0x140000
mtd: erasing @0:0x140000-0x160000
mtd: erasing @0:0x160000-0x180000
mtd: The last page is not full : 1300
mtd: We write one page for save guard. *
mtd: Writting u-boot.imx: #1 @0: 0x00880000 - 0x008e8000
mtd: erasing @0:0x880000-0x8a0000
mtd: erasing @0:0x8a0000-0x8c0000
mtd: erasing @0:0x8c0000-0x8e0000
mtd: erasing @0:0x8e0000-0x900000
mtd: The last page is not full : 1300
mtd: We write one page for save guard. *
root@imx6q:~# hexdump -C /dev/mtd0
00000000  00 00 2d fb ff ff 46 43  42 20 00 00 00 01 50 3c  |..-...FCB ....P

As I see so few NAND_CS0# assertions at boot, I'm thinking my issue is something other than the content of the NAND.  My understanding is that the boot ROM reads 4K of data before it even starts to look at its contents?

Thanks,

Tim

0 Kudos