RAW NAND reverse engineering on an i.MX6S SABRE AI

Document created by vincent.aubineau Employee on Nov 13, 2015Last modified by vincent.aubineau Employee on Sep 29, 2017
Version 11Show Document
  • View in full screen mode

Hi,

 

RAW is still often used in automotive applications.

If you are doing bare metal code and if you use OS (QNX, GreenHills integrity), it is often a pain to boot from NAND.

On SABRE AI, you have a NAND socket, this document will present you the basics command to reverse engineer the NAND boot setup of a SABRE AI.

 

KOBS-NG

What you can do first is understand kobs-ng application, and try to understand it...sources are available on freescale's GIT:

http://sw-git.freescale.net/cgi-bin/gitweb.cgi?p=linux-kobs.git;a=summary

Anyway, the sequencing is not obvious...

 

Modified MFGtool (see enclosed archive)

What you can do also it to program a NAND flash on a SABRE board for instance and read back the NAND flash.

First configure your SABRE AI board:

S2: 0001

S1: 0001100000  (I use 8 BBT and FCB to be more secure)

BOOT_MODE: 0010 (if your NAND flash is not already programmed, otherwise 0100)

Copy my mfgtool (Works only with i.MX6 Solo part), and unzip it.

Plug  a micro USB cable and a RS232 cable, configure your hyperterminal as usual.

Launch mfgtool and press start:

Wait the end of programmation:

Note: I did modify ucl2.xml file to have 8 BBT and FCB (see S1 configuration above, and "--search_exponent=3" --> 2^3=8 instead of default 2^2=4 ) and I did add the "-v" option in ucl2.xml file to have the verbose mode (thus memory addresses of FCB, BBT and more are displayed) ---> you have to go on the extreme right of the lines below... depending of the witdth of your screen):

 

<!--burn the uboot to NAND: -->    
<CMD   state = "Updater"   type = "push"   body = "send"   file = "files/u-boot-mx6solo-sabreauto-nand.bin" > Sending U-Boot </CMD>  
<CMD   state = "Updater"   type = "push"   body = "$ kobs-ng init -v --search_exponent=3 --chip_0_device_path=/dev/mtd0 $FILE" > Flashing Bootloader </CMD>

Set BOOT_MODE switches: 0010 and press reset. After u-boot startup press a key in the terminal to stop execution.

Now you can explore your NAND!

have a look in the enclosed "mx6Solo_RAW_NAND_SABRE_AI_programming_verbose.txt" file, you have all the adressses of BBT, FCB, etc...:

Firmware: image #0 @ 0x400000 size 0x2a000 - available 0x600000 
Firmware: image #1 @ 0xa00000 size 0x2a000 - available 0x600000

-------------- Start to write the [ FCB ] -----
mtd: erasing @0:0x0-0x80000
mtd: Writing FCB0 [ @0:0x0 ] (10e0) *
mtd: Writing FCB1 [ @0:0x40000 ] (10e0) *
mtd: erasing @0:0x80000-0x100000 mtd:
Writing FCB2 [ @0:0x80000 ] (10e0) *
mtd: Writing FCB3 [ @0:0xc0000 ] (10e0) *
mtd: erasing @0:0x100000-0x180000
mtd: Writing FCB4 [ @0:0x100000 ] (10e0) *
mtd: Writing FCB5 [ @0:0x140000 ] (10e0) *
mtd: erasing @0:0x180000-0x200000
mtd: Writing FCB6 [ @0:0x180000 ] (10e0) *
mtd: Writing FCB7 [ @0:0x1c0000 ] (10e0) *
mtd_commit_bcb(FCB): status 0  

-------------- Start to write the [ DBBT ] -----
mtd: erasing @0:0x200000-0x280000
mtd: Writing DBBT0 [ @0:0x200000 ] (1000) *
mtd: Writing DBBT1 [ @0:0x240000 ] (1000) *
mtd: erasing @0:0x280000-0x300000
mtd: Writing DBBT2 [ @0:0x280000 ] (1000) *
mtd: Writing DBBT3 [ @0:0x2c0000 ] (1000) *
mtd: erasing @0:0x300000-0x380000
mtd: Writing DBBT4 [ @0:0x300000 ] (1000) *
mtd: Writing DBBT5 [ @0:0x340000 ] (1000) *
mtd: erasing @0:0x380000-0x400000
mtd: Writing DBBT6 [ @0:0x380000 ] (1000) *
mtd: Writing DBBT7 [ @0:0x3c0000 ] (1000) *
mtd_commit_bcb(DBBT): status 0

 

to read the NAND, I read it in internal OCRAM ( address is 0x918000 for i.MX6DL and Solo) and then I display it):

You can read the DCD of one of the boot image (first one is at address 0x400000 as you can see in the enclosed text file):

Firmware: image #0 @ 0x400000 size 0x2a000 - available 0x600000 
Firmware: image #1 @ 0xa00000 size 0x2a000 - available 0x600000

So, let's read the begenning of the image... at offset 0x400, you'll see the barker code of the DCD: 0x402000D1:

MX6SOLO SABREAUTO U-Boot > nand read 0x918000 0x400000 0x800
NAND read: device 0 offset 0x400000, size 0x800

2048 bytes read: OK
MX6SOLO SABREAUTO U-Boot > md 0x918000 0x500
00918000: ea000186 00000000 00000000 00000000 ................
00918010: 00000000 00000000 00000000 00000000 ................
00918020: 00000000 00000000 00000000 00000000 ................
00918030: 00000000 00000000 00000000 00000000 ................
00918040: 00000000 00000000 00000000 00000000 ................
00918050: 00000000 00000000 00000000 00000000 ................
00918060: 00000000 00000000 00000000 00000000 ................
00918070: 00000000 00000000 00000000 00000000 ................
00918080: 00000000 00000000 00000000 00000000 ................
00918090: 00000000 00000000 00000000 00000000 ................
009180a0: 00000000 00000000 00000000 00000000 ................
009180b0: 00000000 00000000 00000000 00000000 ................
009180c0: 00000000 00000000 00000000 00000000 ................
009180d0: 00000000 00000000 00000000 00000000 ................
009180e0: 00000000 00000000 00000000 00000000 ................
009180f0: 00000000 00000000 00000000 00000000 ................
00918100: 00000000 00000000 00000000 00000000 ................
00918110: 00000000 00000000 00000000 00000000 ................
00918120: 00000000 00000000 00000000 00000000 ................
00918130: 00000000 00000000 00000000 00000000 ................
00918140: 00000000 00000000 00000000 00000000 ................
00918150: 00000000 00000000 00000000 00000000 ................
00918160: 00000000 00000000 00000000 00000000 ................
00918170: 00000000 00000000 00000000 00000000 ................
00918180: 00000000 00000000 00000000 00000000 ................
00918190: 00000000 00000000 00000000 00000000 ................
009181a0: 00000000 00000000 00000000 00000000 ................
009181b0: 00000000 00000000 00000000 00000000 ................
009181c0: 00000000 00000000 00000000 00000000 ................
009181d0: 00000000 00000000 00000000 00000000 ................
009181e0: 00000000 00000000 00000000 00000000 ................
009181f0: 00000000 00000000 00000000 00000000 ................
00918200: 00000000 00000000 00000000 00000000 ................
00918210: 00000000 00000000 00000000 00000000 ................
00918220: 00000000 00000000 00000000 00000000 ................
00918230: 00000000 00000000 00000000 00000000 ................
00918240: 00000000 00000000 00000000 00000000 ................
00918250: 00000000 00000000 00000000 00000000 ................
00918260: 00000000 00000000 00000000 00000000 ................
00918270: 00000000 00000000 00000000 00000000 ................
00918280: 00000000 00000000 00000000 00000000 ................
00918290: 00000000 00000000 00000000 00000000 ................
009182a0: 00000000 00000000 00000000 00000000 ................
009182b0: 00000000 00000000 00000000 00000000 ................
009182c0: 00000000 00000000 00000000 00000000 ................
009182d0: 00000000 00000000 00000000 00000000 ................
009182e0: 00000000 00000000 00000000 00000000 ................
009182f0: 00000000 00000000 00000000 00000000 ................
00918300: 00000000 00000000 00000000 00000000 ................
00918310: 00000000 00000000 00000000 00000000 ................
00918320: 00000000 00000000 00000000 00000000 ................
00918330: 00000000 00000000 00000000 00000000 ................
00918340: 00000000 00000000 00000000 00000000 ................
00918350: 00000000 00000000 00000000 00000000 ................
00918360: 00000000 00000000 00000000 00000000 ................
00918370: 00000000 00000000 00000000 00000000 ................
00918380: 00000000 00000000 00000000 00000000 ................
00918390: 00000000 00000000 00000000 00000000 ................
009183a0: 00000000 00000000 00000000 00000000 ................
009183b0: 00000000 00000000 00000000 00000000 ................
009183c0: 00000000 00000000 00000000 00000000 ................
009183d0: 00000000 00000000 00000000 00000000 ................
009183e0: 00000000 00000000 00000000 00000000 ................
009183f0: 00000000 00000000 00000000 00000000 ................
00918400: 402000d1 27800620 00000000 2780042c .. @ ..'....,..'
00918410: 27800420 27800400 00000000 00000000 ..'...'........
00918420: 27800000 0002a0a4 00000000 40e001d2 ...'...........@
00918430: 04dc01cc 74070e02 00000c00 54070e02 .......t.......T
00918440: 00000000 ac040e02 30000000 b0040e02 ...........0....
00918450: 30000000 64040e02 30000000 90040e02 ...0...d...0....
00918460: 30000000 4c070e02 30000000 94040e02 ...0...L...0....
00918470: 30000000 a0040e02 00000000 b4040e02 ...0............
00918480: 30000000 b8040e02 30000000 6c070e02 ...0.......0...l
00918490: 30000000 50070e02 00000200 bc040e02 ...0...P........
009184a0: 28000000 c0040e02 28000000 c4040e02 ...(.......(....
009184b0: 28000000 c8040e02 28000000 60070e02 ...(.......(...`
009184c0: 00000200 64070e02 28000000 70070e02 .......d...(...p
009184d0: 28000000 78070e02 28000000 7c070e02 ...(...x...(...|
009184e0: 28000000 70040e02 28000000 74040e02 ...(...p...(...t
009184f0: 28000000 78040e02 28000000 7c040e02 ...(...x...(...|
00918500: 28000000 00081b02 030039a1 0c081b02 ...(.....9......
00918510: 1f001f00 10081b02 1f001f00 3c081b02 ...............<
00918520: 16021c42 40081b02 7a017b01 48081b02 B......@.{.z...H
00918530: 4c4e4a4b 50081b02 34333f3f 1c081b02 KJNL...P??34....
00918540: 33333333 20081b02 33333333 24081b02 3333... 3333...$
00918550: 33333333 28081b02 33333333 b8081b02 3333...(3333....
00918560: 00080000 04001b02 25000200 08001b02 ...........%....
00918570: 30303300 0c001b02 13536b67 10001b02 .300....gkS.....
00918580: 638b6eb6 14001b02 db00ff01 18001b02 .n.c............
00918590: 40170000 1c001b02 00800000 2c001b02 ...@...........,
009185a0: d2260000 30001b02 23106b00 40001b02 ..&....0.k.#...@
009185b0: 27000000 00001b02 00001984 1c001b02 ...'............
009185c0: 32800004 1c001b02 33800000 1c001b02 ...2.......3....
[ETC....]
MX6SOLO SABREAUTO U-Boot >

 

Let's check the persistent bit (i.MX6S or DL) PERSIST_SECONDARY_BOOT, reflecting from which image you boot:

MX6SOLO SABREAUTO U-Boot > md 0x20D8044 1 
020d8044: 40000000    ...@
MX6SOLO SABREAUTO U-Boot >

Bit 30 is 0, meaning you boot from first image

 

Let's erase one boot image to see it it still boot (you have 2 boot images)

MX6SOLO SABREAUTO U-Boot > nand erase 0x400000 0x512
NAND erase: device 0 offset 0x400000, size 0x512
Warning: Erase size 0x00000512 smaller than one erase block 0x00080000
Erasing 0x00080000 instead
Erasing at 0x400000 -- 100% complete.
OK
MX6SOLO SABREAUTO U-Boot >

 

Presss the reset button of your board to see if the board still start.

If you read the PERSIST_SECONDARY_BOOT persistent bit, you'll see you boot from the second image as bit 30 is active:

MX6SOLO SABREAUTO U-Boot > md 0x20D8044 1 
020d8044: 40000000    ...@
MX6SOLO SABREAUTO U-Boot >

 

If you erase the second image (address 0xa00000, board will not boot as you only have 2 images).

 

What you can do thenis read your FCB (flash configuration) with the following commands in u-boot prompt (sometimes the first read fails! so try again):

WARNING: this was for a 2009 u-boot, in newer version (2016 for instance) you have to do a "nand dump" otherwise it will return an error (FAIL -74), see [Uboot] Nand read from offset xxx failed -74 

MX6SOLO SABREAUTO U-Boot > nand read 0x918000 0x40000 0x800
NAND read: device 0 offset 0x40000, size 0x800
NAND read from offset 40000 failed -74
0 bytes read: ERROR
MX6SOLO SABREAUTO U-Boot > nand read 0x918000 0x40000 0x800
NAND read: device 0 offset 0x40000, size 0x800
2048 bytes read: OK
MX6SOLO SABREAUTO U-Boot > md 0x918000 0x100
00918000: fc000000 4346ffff 00002042 3c500100 ......FCB ....P<
00918010: 00000619 10000000 10e00000 00800000 ................
00918020: 00000000 00000000 00000000 00080000 ................
00918030: 02000000 02000000 00080000 000a0000 ................
00918040: 00070000 00000000 00000000 00000000 ................
00918050: 00000000 00000000 00000000 00000000 ................
00918060: 00000000 00000000 04000000 0a000000 ................
00918070: 002a0000 002a0000 02000000 0f400000 ..*...*.......@.
00918080: 00000000 10000000 00000000 00000000 ................
00918090: 00000000 00000000 00000000 00000000 ................
009180a0: 00000000 00000000 00000000 00000000 ................
009180b0: 00000000 00000000 00000000 00000000 ................
009180c0: 00000000 00000000 00000000 00000000 ................
009180d0: 00000000 00000000 00000000 00000000 ................
009180e0: 00000000 00000000 00000000 00000000 ................
009180f0: 00000000 00000000 00000000 00000000 ................
00918100: 00000000 00000000 00000000 00000000 ................
00918110: 00000000 00000000 00000000 00000000 ................
00918120: 00000000 00000000 00000000 00000000 ................
00918130: 00000000 00000000 00000000 00000000 ................
00918140: 00000000 00000000 00000000 00000000 ................
00918150: 00000000 00000000 00000000 00000000 ................
00918160: 00000000 00000000 00000000 00000000 ................
00918170: 00000000 00000000 00000000 00000000 ................
00918180: 00000000 00000000 00000000 00000000 ................
00918190: 00000000 00000000 00000000 00000000 ................
009181a0: 00000000 00000000 00000000 00000000 ................
009181b0: 00000000 00000000 00000000 00000000 ................
009181c0: 00000000 00000000 00000000 00000000 ................
009181d0: 00000000 00000000 00000000 00000000 ................
009181e0: 00000000 00000000 00000000 00000000 ................
009181f0: 00000000 00000000 00000000 00000000 ................
00918200: 00001a1c 0000000e 00000000 00000000 ................
00918210: 00000000 00000019 00001600 00001600 ................
00918220: 00000019 0000000f 00000019 00000000 ................
00918230: 00000000 00000000 00000000 00000000 ................
00918240: 00000000 00000000 00000000 00000000 ................
00918250: 00001300 00000f00 00000008 00000008 ................
00918260: 00001600 00000015 00000000 00001a00 ................
00918270: 00000000 00000000 00000000 00000000 ................
00918280: 00000000 00000000 00000000 00000000 ................
00918290: 00000000 00000000 00000000 00000000 ................
009182a0: 00000000 00000000 00000000 00000000 ................
009182b0: 00000000 00000000 00000000 00000000 ................
009182c0: 00000000 00000000 00000000 00000000 ................
009182d0: 00000000 00000000 00000000 00000000 ................
009182e0: 00000000 00000000 00000000 00000000 ................
009182f0: 00000000 00000000 00000000 00000000 ................
00918300: 00000000 00000000 00000000 00000000 ................
00918310: 00000000 00000000 00000000 00000000 ................
00918320: 00000000 00000000 00000000 00000000 ................
00918330: 00000000 00000000 00000000 00000000 ................
00918340: 00000000 00000000 00000000 00000000 ................
00918350: 00000000 00000000 00000000 00000000 ................
00918360: 00000000 00000000 00000000 00000000 ................
00918370: 00000000 00000000 00000000 00000000 ................
00918380: 00000000 00000000 00000000 00000000 ................
00918390: 00000000 00000000 00000000 00000000 ................
009183a0: 00000000 00000000 00000000 00000000 ................
009183b0: 00000000 00000000 00000000 00000000 ................
009183c0: 00000000 00000000 00000000 00000000 ................
009183d0: 00000000 00000000 00000000 00000000 ................
009183e0: 00000000 00000000 00000000 00000000 ................
009183f0: 00000000 00000000 00000000 00000000 ................
MX6SOLO SABREAUTO U-Boot >

 

If you read the addresses 0x000000, 0x40000, 0x80000, 0xc0000, 0x100000, 0x140000 or 0x180000 or 0x1c0000 you'll have a copy of the FCB in OCRAM (internal RAM) and then read the OCRAM.

You can now try that the replication is working. Thus try to erase FCBs (in my case, with Micron MT29F16G08ABABAWP the minimum I can erase is 2 FCBs due to sector size of 0x80000, check it on your side), for u-boot after 2009 use "nand dump", see [Uboot] Nand read from offset xxx failed -74  :

MX6SOLO SABREAUTO U-Boot > nand erase 0x0 0x512
NAND erase: device 0 offset 0x0, size 0x512
Warning: Erase size 0x00000512 smaller than one erase block 0x00080000
Erasing 0x00080000 instead
Erasing at 0x0 -- 100% complete.
OK
MX6SOLO SABREAUTO U-Boot > nand erase 0x80000 0x512
NAND erase: device 0 offset 0x80000, size 0x512
Warning: Erase size 0x00000512 smaller than one erase block 0x00080000
Erasing 0x00080000 instead
Erasing at 0x80000 -- 100% complete.
OK
MX6SOLO SABREAUTO U-Boot > nand erase 0x100000 0x512
NAND erase: device 0 offset 0x100000, size 0x512
Warning: Erase size 0x00000512 smaller than one erase block 0x00080000
Erasing 0x00080000 instead
Erasing at 0x100000 -- 100% complete.
OK
MX6SOLO SABREAUTO U-Boot >

 

You have erase 6 FCB. If you press reset, you normallystill can boot the device (checkswitch S1 is configured like that: 0001100000).

You can also read the bad block table. In enclosed "mx6Solo_RAW_NAND_SABRE_AI_programming_verbose.txt" you have addresses of the DBBT: 0x200000, 0x240000, 0x280000, 0x2c0000, 0x300000, 0x340000, 0x380000 and 0x3c0000:

-------------- Start to write the [ DBBT ] -----
mtd: erasing @0:0x200000-0x280000
mtd: Writing DBBT0 [ @0:0x200000 ] (1000) *
mtd: Writing DBBT1 [ @0:0x240000 ] (1000) *
mtd: erasing @0:0x280000-0x300000
mtd: Writing DBBT2 [ @0:0x280000 ] (1000) *
mtd: Writing DBBT3 [ @0:0x2c0000 ] (1000) *
mtd: erasing
mtd: Writing DBBT4 [ @0:0x300000 ] (1000) *
mtd: Writing DBBT5 [ @0:0x340000 ] (1000) *
mtd: erasing @0:0x380000-0x400000
mtd: Writing DBBT6 [ @0:0x380000 ] (1000) *
mtd: Writing DBBT7 [ @0:0x3c0000 ] (1000) *
mtd_commit_bcb(DBBT): status 0

 

now read a DBBT in u-boot (as already mentionned, sometimes nand read failed, so try again!):

MX6SOLO SABREAUTO U-Boot > nand read 0x918000 0x280000 0x800
NAND read: device 0 offset 0x280000, size 0x800
2048 bytes read: OK
MX6SOLO SABREAUTO U-Boot > md 0x918000 0x80
00918000: 00000000 54424244 01000000 00000000 ....DBBT........
00918010: 00000000 00000000 00000000 00000000 ................
00918020: 00000000 00000000 00000000 00000000 ................
00918030: 00000000 00000000 00000000 00000000 ................
00918040: 00000000 00000000 00000000 00000000 ................
00918050: 00000000 00000000 00000000 00000000 ................
00918060: 00000000 00000000 00000000 00000000 ................
00918070: 00000000 00000000 00000000 00000000 ................
00918080: 00000000 00000000 00000000 00000000 ................
00918090: 00000000 00000000 00000000 00000000 ................
009180a0: 00000000 00000000 00000000 00000000 ................
009180b0: 00000000 00000000 00000000 00000000 ................
009180c0: 00000000 00000000 00000000 00000000 ................
009180d0: 00000000 00000000 00000000 00000000 ................
009180e0: 00000000 00000000 00000000 00000000 ................
009180f0: 00000000 00000000 00000000 00000000 ................
00918100: 00000000 00000000 00000000 00000000 ................
00918110: 00000000 00000000 00000000 00000000 ................
00918120: 00000000 00000000 00000000 00000000 ................
00918130: 00000000 00000000 00000000 00000000 ................
00918140: 00000000 00000000 00000000 00000000 ................
00918150: 00000000 00000000 00000000 00000000 ................
00918160: 00000000 00000000 00000000 00000000 ................
00918170: 00000000 00000000 00000000 00000000 ................
00918180: 00000000 00000000 00000000 00000000 ................
00918190: 00000000 00000000 00000000 00000000 ................
009181a0: 00000000 00000000 00000000 00000000 ................
009181b0: 00000000 00000000 00000000 00000000 ................
009181c0: 00000000 00000000 00000000 00000000 ................
009181d0: 00000000 00000000 00000000 00000000 ................
009181e0: 00000000 00000000 00000000 00000000 ................
009181f0: 00000000 00000000 00000000 00000000 ................
MX6SOLO SABREAUTO U-Boot >

 

Here I have no bad block (it is a SLC RAW NAND flash..).

 

To be sure I have effectively erased 6 FCB, I will erase the 2 last one... thus I will not boot as all FCB tables will be erased(remove the usb cable otherwise mfgtool will restart):

MX6SOLO SABREAUTO U-Boot > nand erase 0x180000 0x512

NAND erase: device 0 offset 0x180000, size 0x512
Warning: Erase size 0x00000512 smaller than one erase block 0x00080000
Erasing 0x00080000 instead
Erasing at 0x180000 -- 100% complete.
OK
MX6SOLO SABREAUTO U-Boot >

 

Reset the board... and it will not start as you have erased all the 8 FCB tables... you have to reprogram your board if you want to start again.

1 person found this helpful

Outcomes