Please note as of Wednesday, August 15th, 2018 this wiki has been set to read only. If you are a TI Employee and require Edit ability please contact x0211426 from the company directory.

DM355 DVEVM NAND Reloading

From Texas Instruments Wiki
Jump to: navigation, search
Alternatives
  • You can use similar techniques with cheap hardware and open-source OpenOCD, which can also directly read/write NAND flash over JTAG.
  • For a commercial standalone JTAG programmer look at the Ronetix PEEDI.

This article details how to reload the factory images to NAND flash on a DM355 EVM board with a BDI2000.

These instructions were developed on a PC running Ubuntu 7.10.

These instructions are specific to the versions of the binary images listed below as we'll be using the BDI2000 to set breakpoints at specific locations in memory to modify the behavior of the various boot loaders.

If you don't have these exact images, you can use these instructions in a general sense but should verify the breakpoint addresses in your images.

Materials

The following materials will be used to reload the NAND:

  • DM355 EVM
  • Abatron BDI2000
  • TFTP server
  • PC with:
    • telnet
    • serial port communication program
    • Linux server with the TI DVSDK installed

TI binaries images of the User Boot Loader (UBL) and of Das U-Boot.

Image Name MD5SUM Description
ublDM355-nand.bin dc0f3ecfcb107129e0f7d7255e90a988 User Boot Loader
u-boot-1.2.0-dm355_evm 77666515cf22c99cc6ac1e41b6bf7fb8 Das U-Boot, U-Boot 1.2.0 (Oct 17 2007 - 15:38:02)

These are found where the DVDSK was installed, the exact location will vary with the version of the DVSDK that is installed. For example, on my PC that location was:

/opt/dvsdk_1_30_00_23/PSP_01_20_00_004_1/bin/DM355/

Introduction

The current released version of the DM355 EVM, PCB Rev C2, uses NAND flash to store the boot loaders. There are three boot loaders involved in starting the system:

  1. ROM Boot Loader. The RBL is hard coded in the DaVinci. It's purpose is to load a UBL from NAND flash into internal ARM RAM.
  2. User Boot Loader. The UBL is a small program used to initialize the DDR and to load a secondary boot loader from NAND flash. It must be small as it has to fit entirely within the 32kB of internal ARM RAM.
  3. Application Boot Loader. The ABL is loaded into the system RAM and can do whatever it needs to start the system.

When the board is powered on the following steps occur:

First, the RBL in the DaVinci starts executing. It examines Page 0 of the first 24 blocks of NAND flash, starting at block 1 looking for the magic number of the UBL Descriptor. If a UBL Descriptor is found, the RBL loads the UBL into the internal ARM RAM and jumps to the entry point and starts execution of the UBL.

The UBL Descriptor block looks like:

Offset Default Value Description
0x0000 0000 0xa1ac ed00 Magic number of 0xa1ac edxx. The xx can be replaced by one of the following values for different types of boots:
  • 00 - Safe boot mode
  • 11 - DMA boot mode
  • 22 - I-Cache boot mode
  • 33 - Fast EMIF boot mode
  • 44 - DMA + I-Cache boot mode
  • 55 - DMA + I-Cache + Fast EMIF boot mode
0x0000 0004 0x0000 0020 Entry point of the UBL as an absolute address.
0x0000 0008 0x0000 0006 Number of NAND pages used to store the UBL.
0x0000 000c 0x0000 0001 Block number containing the first page of the UBL.
0x0000 0010 0x0000 0002 Starting page number of the UBL.

Next, the UBL starts scanning NAND looking for the magic number of an ABL Descriptor block. If a ABL Descriptor is found, the UBL loads the ABL into the DDR and jumps to the entry point and starts execution of the ABL. The TI UBL only scans two blocks, 8 and 9, for an ABL Descriptor. If your ABL is not in one of those two blocks, then you'll get a message that looks like:

Invalid ABL location
UBL: Failed to read app descriptor
UBL: NANDBoot() failed

The ABL Descriptor block looks like:

Offset Default Value Description
0x0000 0000 0xb1ac ed22 Magic number of 0xb1ac edxx. The xx can be replaced by one of the following values for different types of boots:
  • 00 - Safe boot mode
  • 11 - DMA boot mode
  • 22 - I-Cache boot mode
  • 33 - Fast EMIF boot mode
  • 44 - DMA + I-Cache boot mode
  • 55 - DMA + I-Cache + Fast EMIF boot mode
0x0000 0004 0x0000 000a Starting NAND block number that ABL is stored at.
0x0000 0008 0x8108 0000 Location to start copying the ABL to in DDR.
0x0000 000c 0x8108 0000 Application entry point.
0x0000 0010 0x0000 003f Number of NAND pages used to store the ABL.
0x0000 0014 0x0000 0000 Flag used to indicate that the application is compressed.

Theory

The BDI2000 doesn't support writing the NAND flash on the DM355 EVM board. To reload the NAND flash with a BDI200, we'll load U-Boot and use it to write itself back into NAND along will all supporting information. We'll follow these steps:

  1. Load the UBL into internal ARM RAM using the BDI2000.
  2. Set a breakpoint in the UBL after it has read a page from NAND but before it checks the data read for the ABL Descriptor magic number.
  3. When the breakpoint is hit, modify the memory location used to store the NAND page to insert a valid ABL Descriptor block.
  4. Set a breakpoint in the UBL just before it will jump into the ABL.
  5. When the breakpoint is hit, load the U-Boot image into the location described in the ABL.
  6. Boot U-Boot
  7. In U-Boot:
    1. Erase the NAND location used to store the ABL Descriptor.
    2. Write a new ABL Descriptor into NAND.
    3. Erase the NAND location used to store the ABL.
    4. Write a new ABL into NAND.
    5. Erase the NAND location used to store the UBL Descriptor and UBL.
    6. Write a new UBL Descriptor into NAND.
    7. Write a new UBL into NAND.

At this point we can power down the board, disconnect the BDI2000 and boot into U-Boot on the next power cycle.

Setup

Copy Files

Copy the TI image binaries to the TFTP server. You may want to rename them or create a soft link to the files with a shorter name to reduce typos.

ls -l /tftpboot
total 152
-rw-r--r-- 1 jeffc jeffc   1227 2008-02-03 13:03 dm355.cfg
-rw-r--r-- 1 jeffc jeffc   1202 2008-01-23 15:02 reg926e.def
lrwxrwxrwx 1 jeffc jeffc     17 2008-01-23 15:36 ubl -> ublDM355-nand.bin
-rwxr--r-- 1 jeffc jeffc  11776 2008-01-23 15:36 ublDM355-nand.bin
lrwxrwxrwx 1 jeffc jeffc     26 2008-02-03 13:04 u-boot -> u-boot-1.2.0-dm355_evm.bin
-rwxr--r-- 1 jeffc jeffc 128684 2008-02-03 13:05 u-boot-1.2.0-dm355_evm.bin

Copy a configuration file for the BDI2000 that will allow it to communicate with the DM355 to the TFTP server. A working example that I've used while creating these instructions is listed below.

File: dm355.cfg
[INIT]

[TARGET]
CPUTYPE			ARM926E
CLOCK			4			; JTAG clock : without adaptive clocking cable
TRST			PUSHPULL		; TRST driver type (OPENDRAIN | PUSHPULL)
RESET			HARD 500		; NONE | HARD <n> (ms)
ENDIAN			LITTLE			; memory model (LITTLE | BIG)
WAKEUP			100
SCANPRED		1 6			; count for ICEPick TAP
SCANSUCC		0 0 			; no device after ARM926e
BREAKMODE		HARD			; HARD = hardware, SOFT = software, go figure
VECTOR			CATCH 0x02

; Configure ICEPick module to make ARM926 TAP visible
SCANINIT		r1:w400000:r0		; toggle reset for 0.4 seconds
SCANINIT		t1:w1000:t0:w1000:	; toggle TRST
SCANINIT		i6=07:d8=89:i6=02:	; connect and select router
SCANINIT		d32=81000082:		; set IP control
SCANINIT		d32=a018206f:		; configure TAP0
SCANINIT		d32=a018216f:cl5:	; enable TAP0, clock 5 times in RTI
SCANINIT		d32=a018616f:cl5:	; enable TAP0, clock 5 times in RTI
SCANINIT		i10=ffff		; scan bypass

[HOST]
IP			10.0.5.199
PROMPT			DM355>

[REGS]
FILE			$reg926e.def


; Sample configuration line to paste into a telnet session to the BDI2000 to configure it
;        filename  Host IP    BDI IP    Gateway IP Mask
;        --------- ---------- --------- ---------- -------------
; config dm355.cfg 10.0.5.199 10.0.5.13 10.0.4.1   255.255.252.0


Copy the reg926e.def file to the TFTP server. This file came with the BDI2000.

Connect Cables

With everything powered down, connect the BDI2000 to the DM355 EVM board. Connect Ethernet cables to the BDI2000 and the DM355 EVM board. Connect a serial cable between the PC and the DM355 EVM.

Apply Power

Power on the BDI2000 and telnet into it. Next apply power on the DM355 EVM. If everything works successfully, you should see the following output on the telnet session:

Successful Start
- TARGET: processing reset request
- TARGET: BDI executes scan chain init string
- TARGET: Bypass check 0x00000001 => 0x00000002
- TARGET: JTAG exists check passed
- Core#0: ID code is 0x07926001
- TARGET: All ICEBreaker access checks passed
- TARGET: BDI removes RESET
- TARGET: BDI waits for RESET inactive
- TARGET: resetting target passed
- TARGET: processing target startup ....
- TARGET: processing target startup passed
DM355>

Some DM355 EVM boards seem to have trouble establishing a JTAG connection with a BDI2000. If you see output similar to the following:

Unable to start JTAG connection
- TARGET: processing reset request
- TARGET: BDI executes scan chain init string
- TARGET: Bypass check 0x00000001 => 0x00000004
- TARGET: JTAG exists check failed
- TARGET: Remove RESET and try again
- TARGET: BDI waits for RESET inactive
- TARGET: Bypass check 0x00000001 => 0x00000004
- TARGET: JTAG exists check failed
# TARGET: resetting target failed
# JTAG: communication with target failed
- TARGET: target will be restarted in 10 sec
DM355>

Try power cycling the BDI2000 while keeping the DM355 EVM board powered. That worked on the board that I had that had this issue.

If you don't see a
DM355>
prompt, it means that the BDI2000 can't find it's configuration file on the TFTP server. Check the IP address assigned to the BDI2000 and that the configuration file is in the root directory of the TFTP server.

Restore NAND

Load UBL

The first step in restoring the contents of the NAND flash is to load the UBL into the internal ARM RAM at address 0x0000 0020. The UBL is a binary file.

Load UBL
DM355>load 0x20 ubl bin
Loading ubl , please wait ....
Loading program file passed
DM355>

Break before magic number verification

Set a breakpoint at address 0x0000 1c70. This address was determined by examining a assembly listing of the UBL. This address corresponds with line 136 of nandboot.c:

Code: nandboot.c starting at line 136
136	magicNum = *(((Uint32 *)rxBuf));
137
138	/* Magic number found */
139	if((magicNum & 0xFFFFFF00) == validMagicNum){
140             UARTSendData((Uint8*)"UBL: detected valid U-Boot magic number\r\n", FALSE);
141		flag=1;
142		break;
143	}else
144		continue;
Break before ABL magic number is verified
DM355>bi 0x1c70
Breakpoint identification is 0
DM355>

By breaking here, we will allow the UBL to think it has found a valid ABL Descriptor and to do any setup indicated by that descriptor.

Run the UBL

Start the UBL by setting the program counter to the entry point of 0x0000 0020.

Start the UBL
DM355>go 0x20
- TARGET: core #0 has entered debug mode
DM355>

Create ABL Descriptor

At this point a serial terminal connected to the DM33 EVM board should have the following output on it:

Serial Terminal
this is MT29F16G08FAA device                                     

Next we'll create a ABL Descriptor in the memory location 0x8000 0000. This is the location that the UBL will write the pages read from NAND. The descriptor will be in the first six 32 bit words of a page.

We start by filling an area of memory, 0x8000 0000, with 0xffff ffff for the length of a NAND page. Then we'll make the modifications and dump out the block after we're done to verify it.

Creating an ABL Descriptor
DM355>mm 0x80000000 0x0 6
DM355>mm 0x80000000 0xb1aced22
DM355>mm 0x80000004 0xa
DM355>mm 0x80000008 0x81080000 
DM355>mm 0x8000000c 0x81080000
DM355>mm 0x80000010 0x3f
DM355>md 0x80000000
80000000 : b1aced22 0000000a 81080000 81080000  "...............
80000010 : 0000003f 00000000 ffffffff ffffffff  ?...............
80000020 : ffffffff ffffffff ffffffff ffffffff  ................

Alternatively, you can create a ABL Descriptor image with your favorite hex editor and store it on your TFTP server. Then all you have to do is load it in.

Loading an ABL Descriptor
DM355>load 0x80000000 ti.abl bin
Loading ti.abl , please wait ....
Loading program file passed
DM355>md 0x80000000
80000000 : b1aced22 0000000a 81080000 81080000  "...............
80000010 : 0000003f 00000000 ffffffff ffffffff  ?...............
80000020 : ffffffff ffffffff ffffffff ffffffff  ................

Break after ABL Load

Next we clear the current breakpoint and set a new one at 0x0000 00ac and allow the UBL to run again.

This address was determined by examining a assembly listing of the UBL. This address corresponds to the instruction after main() in armboot_main.c exits.

Break after main exits
DM355>ci 0
DM355>bi 0xac
Breakpoint identification is 0
DM355>go
- TARGET: core #0 has entered debug mode
DM355>

At this point a serial terminal connected to the DM33 EVM board should have the following output on it:

Serial Terminal
this is MT29F16G08FAA device                                     
UBL: detected valid U-Boot magic number                                         
UBL: booting to U-Boot  

Load ABL and boot U-Boot

At this point the UBL has loaded some data from NAND into the DDR and is prepared to jump into it and start executing it. We'll replace the contents in DDR with a known good Das U-Boot image and boot into that instead.

When we created the ABL Descriptor we specified a load address of 0x8108 0000 so that is where we'll load our image.

Loading U-Boot
DM355>load 0x81080000 u-boot bin
Loading u-boot , please wait ....
Loading program file passed
DM355>go
DM355>

The serial terminal should show that U-Boot is starting:

Staring U-Boot
U-Boot 1.2.0 (Oct 17 2007 - 15:38:02)                                           
                                                                                
DRAM:  128 MB                                                                   
NAND:  NAND device: Manufacturer ID: 0x2c, Chip ID: 0xd3 (Micron NAND 1GiB 3,3V)
Bad block table found at page 524224, version 0x01                              
Bad block table found at page 524160, version 0x01                              
nand_read_bbt: Bad block at 0x03f80000                                          
nand_read_bbt: Bad block at 0x0bec0000                                          
nand_read_bbt: Bad block at 0x14ae0000                                          
nand_read_bbt: Bad block at 0x15e60000                                          
nand_read_bbt: Bad block at 0x33340000                                          
nand_read_bbt: Bad block at 0x35c20000                                          
nand_read_bbt: Bad block at 0x3bd40000                                          
NAND device: Manufacturer ID: 0x2c, Chip ID: 0xd3 (Micron NAND 1GiB 3,3V 8-bit) 
Bad block table found at page 524224, version 0x01                              
Bad block table found at page 524160, version 0x01                              
nand_read_bbt: Bad block at 0x00b80000                                          
nand_read_bbt: Bad block at 0x03a00000                                          
nand_read_bbt: Bad block at 0x06e40000                                          
nand_read_bbt: Bad block at 0x08940000                                          
nand_read_bbt: Bad block at 0x090c0000                                          
nand_read_bbt: Bad block at 0x09580000                                          
nand_read_bbt: Bad block at 0x09940000                                          
nand_read_bbt: Bad block at 0x0c040000                                          
nand_read_bbt: Bad block at 0x0e4c0000                                          
nand_read_bbt: Bad block at 0x0ec80000                                          
nand_read_bbt: Bad block at 0x0ecc0000                                          
nand_read_bbt: Bad block at 0x0eec0000                                          
nand_read_bbt: Bad block at 0x0ef40000                                          
nand_read_bbt: Bad block at 0x0f040000                                          
nand_read_bbt: Bad block at 0x0f080000                                          
nand_read_bbt: Bad block at 0x0f0c0000                                          
nand_read_bbt: Bad block at 0x0f100000                                          
nand_read_bbt: Bad block at 0x0f140000                                          
nand_read_bbt: Bad block at 0x0f280000                                          
nand_read_bbt: Bad block at 0x0f2c0000                                          
nand_read_bbt: Bad block at 0x11a80000                                          
nand_read_bbt: Bad block at 0x173c0000                                          
nand_read_bbt: Bad block at 0x184c0000                                          
nand_read_bbt: Bad block at 0x18580000                                          
nand_read_bbt: Bad block at 0x18e40000                                          
nand_read_bbt: Bad block at 0x18fe0000                                          
nand_read_bbt: Bad block at 0x19480000                                          
nand_read_bbt: Bad block at 0x19780000                                          
nand_read_bbt: Bad block at 0x1c7c0000                                          
nand_read_bbt: Bad block at 0x1d400000                                          
nand_read_bbt: Bad block at 0x1d940000                                          
nand_read_bbt: Bad block at 0x1da00000                                          
nand_read_bbt: Bad block at 0x1dc20000                                          
nand_read_bbt: Bad block at 0x20180000                                          
nand_read_bbt: Bad block at 0x314c0000                                          
nand_read_bbt: Bad block at 0x36d80000                                          
nand_read_bbt: Bad block at 0x37b80000                                          
nand_read_bbt: Bad block at 0x37d80000                                          
nand_read_bbt: Bad block at 0x3c720000                                          
nand_read_bbt: Bad block at 0x3f7c0000                                          
2048 MiB                                                                        
*** Warning - bad CRC or NAND, using default environment                        
                                                                                
In:    serial                                                                   
Out:   serial                                                                   
Err:   serial                                                                   
ARM Clock :- 216MHz                                                             
DDR Clock :- 171MHz                                                             
Hit any key to stop autoboot:  0                                                
DM355 EVM # 

The bad CRC warning from U-Boot is normal if you're starting with a completely erased NAND flash. As soon as the U-Boot environment is saved, the error will go away.

Stop U-Boot from autobooting by hitting any key in the serial terminal. All commands will now be entered on the serial terminal.

Write ABL Descriptor

Next we'll erase the location in NAND where the UBL starts looking for a ABL Descriptor block and write our ABL Descriptor that we just used to boot U-Boot there. The ABL Descriptor is still loaded into DDR at 0x8000 0000.

Verify ABL Descriptor
DM355 EVM # md 0x80000000                                                       
80000000: b1aced22 0000000a 81080000 81080000    "...............               
80000010: 0000003f 00000000 ffffffff ffffffff    ?...............               
80000020: ffffffff ffffffff ffffffff ffffffff    ................               

The location in NAND that the ABL Descriptor is stored at depends on the NAND chip. On my DM355 EVM board, it is 0x0010 0000. We'll erase that location.

Warning: Make very sure that you don't forget the length argument to the erase command. If you do, U-Boot will erase the entire flash starting at the given offset without prompting!


Erase ABL Descriptor location in NAND
DM355 EVM # nand erase 0x00100000 0x1000                                        
                                                                                
NAND erase: device 0 offset 0x100000, size 0x1000                               
Erasing at 0x100000 -- 3200% complete.                                          
OK                                                                              
DM355 EVM # 

Finally, write the ABL Descriptor from memory to NAND.

Write ABL Descriptor
DM355 EVM # nand write 0x80000000 0x00100000 0x1000                             
                                                                                
NAND write: device 0 offset 0x100000, size 0x1000                               
 4096 bytes written: OK                                                         
DM355 EVM # 

Write UBL Descriptor

Next, we'll create a UBL Descriptor in memory and write that to NAND. Use the U-Boot command mm and press Ctrl-C to exit when the editing is complete. Use md to verify that the IBL Descriptor is correct.

Create UBL Descriptor
DM355 EVM # mm 0x80000000                                                       
80000000: b1aced22 ? a1aced00                                                   
80000004: 0000000a ? 20                                                         
80000008: 81080000 ? 6                                                          
8000000c: 81080000 ? 1                                                          
80000010: 0000003f ? 2                                                          
80000014: 00000000 ? ffffffff                                                   
80000018: ffffffff ? ^C
DM355 EVM # md 0x80000000                                  
80000000: a1aced00 00000020 00000006 00000001    .... ...........               
80000010: 00000002 ffffffff ffffffff ffffffff    ................               
80000020: ffffffff ffffffff ffffffff ffffffff    ................   

The location in NAND that the UBL Descriptor is stored at depends on the NAND chip and the location that you choose to store the UBL Descriptor into. On my DM355 EVM board, the first possible location is Block 1, Page 0, which is address 0x0002 0000. We'll erase that location for 0x4000 bytes, 0x1000 bytes for the UBL Descriptor and 0x3000 bytes for the UBL that will follow it.

Warning: Make very sure that you don't forget the length argument to the erase command. If you do, U-Boot will erase the entire flash starting at the given offset without prompting!


Erase UBL Descriptor location in NAND
DM355 EVM # nand erase 0x00020000 0x4000                                        
                                                                                
NAND erase: device 0 offset 0x20000, size 0x4000                                
Erasing at 0x20000 -- 800% complete.                                            
OK                                                                              
DM355 EVM # 

Finally, write the UBL Descriptor from memory to NAND.

Write UBL Descriptor
DM355 EVM # nand write 0x80000000 0x00020000 0x1000                             
                                                                                
NAND write: device 0 offset 0x20000, size 0x1000                                
 4096 bytes written: OK                                                         
DM355 EVM # 

Write U-Boot

Next, we'll load a copy of U-Boot to write into NAND. The version of U-Boot that we're currently running was loaded into DDR at 0x8108 0000, so we'll load the copy we're going to write into 0x8000 0000.

We'll have to setup network access for U-Boot to TFTP in a copy of U-Boot to write to NAND.

Troubleshooting network issues is beyond the scope of this document. If you have any issues getting the network access working in U-boot, Google is your friend.

Get an IP address with DHCP
DM355 EVM # dhcp                                                                
BOOTP broadcast 1                                                               
DHCP client bound to address 10.0.5.205                                         
TFTP from server 10.0.4.35; our IP address is 10.0.5.205                        
Filename '\OSChooser\i386\startrom.com'.                                        
Load address: 0x80700000                                                        
Loading: #####                                                                  
done                                                                            
Bytes transferred = 24482 (5fa2 hex)                                            
DM355 EVM #


Set the TFTP server address
                                           
DM355 EVM # set serverip 10.0.5.199                                             
DM355 EVM # 


TFTP in a copy of U-Boot
                                             
DM355 EVM # tftp 0x80000000 u-boot                                              
TFTP from server 10.0.5.199; our IP address is 10.0.5.205                       
Filename 'u-boot'.                                                              
Load address: 0x80000000                                                        
Loading: ##########################                                             
done                                                                            
Bytes transferred = 128684 (1f6ac hex)                                          
DM355 EVM # 

The location in NAND that the ABL Descriptor is stored at depends on the NAND chip. On my DM355 EVM board, it is 0x0014 0000. We'll erase that location for 0x20000 bytes.

Warning: Make very sure that you don't forget the length argument to the erase command. If you do, U-Boot will erase the entire flash starting at the given offset without prompting!


Erase ABL location in NAND
DM355 EVM # nand erase 0x00140000 0x20000                                       
                                                                                
NAND erase: device 0 offset 0x140000, size 0x20000                              
Erasing at 0x140000 -- 100% complete.                                           
OK                                                                              
DM355 EVM # 

Then, write U-boot from memory to NAND.

Write U-Boot
DM355 EVM # nand write 0x80000000 0x00140000 0x20000                            
                                                                                
NAND write: device 0 offset 0x140000, size 0x20000                              
 131072 bytes written: OK                                                       
DM355 EVM # 

Write UBL

The last step is to write a copy of the UBL from memory to NAND. The UBL was loaded into internal ARM RAM at 0x0000 0020.

The location in NAND that the UBL is stored at depends on the NAND chip and where you choose to write it. The UBL Descriptor that we just wrote was configured to start the UBL on Block 1, Page 2. This is NAND address 0x0002 1000. We don't need to erase this location as we did it on the previous step since we have to erase NAND in block sized chunks.

Write ABL Descriptor
DM355 EVM # nand write 0x00000020 0x00021000 0x3000                             
                                                                                
NAND write: device 0 offset 0x21000, size 0x3000                                
 12288 bytes written: OK                                                        
DM355 EVM # 

Power Cycle

At this point, you can power down the DM355 EVM board and disconnect the BDI2000. When you power it up again, it should boot to the U-Boot autoboot prompt.