Atmel website | ARM Community | AVR freaks | Technical Support
Banner
 FAQ •  Search •  Register •  Login 

All times are UTC + 1 hour [ DST ]




Post new topic Reply to topic  [ 7 posts ] 
Author Message
 Post subject: Problems booting from NAND/Dataflash AT91SAM
PostPosted: Mon Nov 22, 2010 8:37 am 
Offline

Joined: Mon Nov 22, 2010 1:28 am
Posts: 4
Hey all,

Just want to share my experience with getting the bootloader to work on the NAND flash with our AT91SAM9261.

I had to compile the bootloader from source to customize it. I could boot fine from the SD card, but when I transferred the bootloader to 0x0 of the NAND flash it just would not boot.

I checked the output binary with arm-none-eabi-objdump and noticed the 7th exception vector was NOT as required by the datasheet. This vector is supposed to be the size of the bootloader to be copied to sram. Mine was just showing 'b ReservedVector'.

I solved this by modifying the file board_cstartup.s as follows:

reservedVector:
// b reservedVector /* Reserved for future use */
.byte 0x00, 0x64, 0x00, 0x00 /* 0x6400 bytes represents size of bootloader */

In my case, the binary was 24,952 bytes = 0x6178, so I used 0x6400 to allow some headroom for possible changes.

Hope this helps someone else out there - took me hours to figure it out!


Top
 Profile  
 
 Post subject: Re: Problems booting from NAND/Dataflash AT91SAM
PostPosted: Mon Nov 22, 2010 2:56 pm 
Offline

Joined: Sat Oct 30, 2010 6:04 pm
Posts: 574
SAM-BA provides a NAND "Execute" menu option "Send Boot File" which does this automatically.

It does it so you don't end up bricking the device. RomBoot is checking for valid E5/E9 instructions at the vector table and the length to validate the data as a boot image.


Top
 Profile  
 
 Post subject: Re: Problems booting from NAND/Dataflash AT91SAM
PostPosted: Mon Nov 22, 2010 8:56 pm 
Offline
User avatar

Joined: Mon Jul 19, 2010 8:47 pm
Posts: 59
Hi,

Just to clarify-- do you mean that the Send Boot File script in SAM-BA takes a binary that is missing the size vector, adds the correct size, and then copies it to location 0x0?

I'm somewhat embarrassed to say that I ran into the same problem and have been editing my binaries by hand with a hex editor to make the size correct. I heard mention of the Send Boot File option, but I hadn't noticed that the Scripts dropdown menu was, in fact, a dropdown menu.

_________________
Brandon Stafford
Rascal Micro


Top
 Profile  
 
 Post subject: Re: Problems booting from NAND/Dataflash AT91SAM
PostPosted: Mon Nov 22, 2010 9:30 pm 
Offline

Joined: Sat Oct 30, 2010 6:04 pm
Posts: 574
Yes, it does exactly that.

"Send Boot File" "GENERIC::SendBootFileGUI"

Within GENERIC::Write

# If this is a boot file modify 6th vector with file size
if {[expr ($isBootFile == 1) && ($offset == 0)]} {
TCL_Write_Int $target(handle) $sizeToWrite [expr $bufferAddress + (5 * 4)] dummy_err
}

Now the GCC builds for AT91BootStrap normally puts the ADDRESS of the last byte in the vector location. For the 9260/9G20 this is 0x200000 + length, based on the location of the internal SRAM bank. This bank also limits the total size that RomBoot accepts. The secondary SRAM bank (0x300000/0x301000 in my example) is used for stack space.




How it gets there. I'd use BBcode tags, but the dumb forum has them disabled

#===============================================================================
# proc GENERIC::SendBootFileGUI
#-------------------------------------------------------------------------------
proc GENERIC::SendBootFileGUI {} {
global softwareStatusLabelVariable
global backupDirPath
global conWindows


set fileName [tk_getOpenFile -parent $conWindows -initialdir $backupDirPath -defaultextension ".bin" -filetypes {{"Bin Files" {.bin}} {"All Files" {*.*}}}]
if {$fileName == ""} {
puts stderr "-E- No File Selected"
return
}

if { [catch {set size [file size $fileName]}] } {
puts stderr "-E- Can't open file $fileName"
return
}

if { $size > $BOARD::maxBootSize } {
puts stderr "-E- Unauthorized Boot File Size"
return
}

set softwareStatusLabelVariable "Sending data ..."

# Send the file to the target (modifying the 6th vector)
GENERIC::SendFile $fileName 0x0 1

#Close the wait window
set softwareStatusLabelVariable ""

# Store the current dir
set backupDirPath [file dirname $fileName]
}

#===============================================================================
# proc GENERIC::SendBootFile
#-------------------------------------------------------------------------------
proc GENERIC::SendBootFile {name} {
GENERIC::SendFile $name 0x0 1
}

#===============================================================================
# proc GENERIC::SendFile
#-------------------------------------------------------------------------------
proc GENERIC::SendFile {name addr {isBootFile 0}} {

puts "GENERIC::SendFile $name at address [format "0x%X" $addr]"

if { [catch {set f [open $name r]}] } {
puts stderr "-E- Can't open file $name"
return
}

fconfigure $f -translation binary

set size [file size $name]
puts "-I- File size : [format "0x%X" $size] byte(s)"

if {[catch {GENERIC::Write $addr $size $f $isBootFile} dummy_err]} {
puts stderr "-E- Can't send data ($dummy_err)"
}
close $f
}


#===============================================================================
# proc GENERIC::Write
#-------------------------------------------------------------------------------
proc GENERIC::Write {offset sizeToWrite File isBootFile} {
global target
variable appletArg
variable appletCmd
variable appletAddr
variable appletBufferAddress

global target
set dummy_err 0

set appletAddrCmd [expr $appletAddr + 0x04]
set appletAddrArgv0 [expr $appletAddr + 0x0c]
set appletAddrArgv1 [expr $appletAddr + 0x10]
set appletAddrArgv2 [expr $appletAddr + 0x14]

set maxBufferSize [expr $GENERIC::appletBufferSize]

# Sanity check: buffer to write should not exceed the whole memory size
if { [expr $offset + $sizeToWrite] > $GENERIC::memorySize } {
error "File size exceed memory capacity ([format "0x%X" $GENERIC::memorySize] bytes)"
}

# Init the ping pong algorithm: the buffer is active
set bufferAddress $GENERIC::appletBufferAddress

# Write data page after page...
while {$sizeToWrite > 0} {
# Adjust the packet size to be sent
if {$sizeToWrite < $maxBufferSize} {
set bufferSize $sizeToWrite
} else {
set bufferSize $maxBufferSize
}

# Read Data From Input File
set rawData [read $File $bufferSize]

puts "-I- \tWriting: [format "0x%X" $bufferSize] bytes at [format "0x%X" $offset] (buffer addr : [format "0x%X" $bufferAddress])"

# Copy in RAM the content of the page to be written
TCL_Write_Data $target(handle) $bufferAddress rawData $bufferSize dummy_err

# If this is a boot file modify 6th vector with file size
if {[expr ($isBootFile == 1) && ($offset == 0)]} {
TCL_Write_Int $target(handle) $sizeToWrite [expr $bufferAddress + (5 * 4)] dummy_err
}

# Write the Cmd op code in the argument area
if {[catch {TCL_Write_Int $target(handle) $appletCmd(write) $appletAddrCmd} dummy_err] } {
error "[format "0x%08x" $dummy_err]"
}
# Write the buffer address in the argument area
if {[catch {TCL_Write_Int $target(handle) $bufferAddress $appletAddrArgv0} dummy_err] } {
error "[format "0x%08x" $dummy_err]"
}
# Write the buffer size in the argument area
if {[catch {TCL_Write_Int $target(handle) $bufferSize $appletAddrArgv1} dummy_err] } {
error "[format "0x%08x" $dummy_err]"
}
# Write the memory offset in the argument area
if {[catch {TCL_Write_Int $target(handle) $offset $appletAddrArgv2} dummy_err] } {
error "[format "0x%08x" $dummy_err]"
}

# Launch the applet Jumping to the appletAddr
if {[catch {set result [GENERIC::Run $appletCmd(write)]} dummy_err]} {
error "[format "0x%08x" $dummy_err]"
}
switch $result {
0 {
# APPLET_SUCCESS
# Retrieve how many bytes have been written
set sizeWritten [TCL_Read_Int $target(handle) $appletAddrArgv0]

puts "-I- \t[format "0x%X" $sizeWritten] bytes written by applet"

# If all the buffer has not been written, move back to the first un-written byte offset
if {$sizeWritten < $bufferSize} {
seek $File [expr $sizeWritten - $bufferSize] current
}

incr sizeToWrite [expr -$sizeWritten]
incr offset $sizeWritten
}

1 {
# APPLET_DEV_UNKNOWN
error "[format "0x%08x" $result]"
}

9 {
# APPLET_BAD_BLOCK
# BAD block strategy : block is skipped and we write the next block with same data

# Retrieve how many bytes have been written (must be 0)
set sizeWritten [TCL_Read_Int $target(handle) $appletAddrArgv0]

puts "-I- \t[format "0x%X" $sizeWritten] bytes written by applet"

# If all the buffer has not been written, move back to the first un-written byte offset
seek $File [expr -$bufferSize] current

incr offset $bufferSize
}

default {
# All other errors
error "[format "0x%08x" $result]"
}
}
}

return 1
}


Top
 Profile  
 
 Post subject: Re: Problems booting from NAND/Dataflash AT91SAM
PostPosted: Fri Nov 26, 2010 1:21 am 
Offline

Joined: Fri Jul 30, 2010 4:34 am
Posts: 19
I've had the same problem and was editing the binary by hand as well. Another easier/fool proof way I've found is to just compile your own image and use the SendBootFile to write it and then read it back again using Sam-BA if you want to include the bootloader.bin in your filesystem image.


Top
 Profile  
 
 Post subject: Re: Problems booting from NAND/Dataflash AT91SAM
PostPosted: Wed Aug 31, 2011 2:41 pm 
Offline

Joined: Wed Aug 31, 2011 2:30 pm
Posts: 7
[quote="CptTitanic"]SAM-BA provides a NAND "Execute" menu option "Send Boot File" which does this automatically.

It does it so you don't end up bricking the device. RomBoot is checking for valid E5/E9 instructions at the vector table and the length to validate the data as a boot image.[/quote]

Does not work. Compiled a redboot image (reboot.bin) and using your suggestion to upload it I still get the error message above.


Top
 Profile  
 
 Post subject: Re: Problems booting from NAND/Dataflash AT91SAM
PostPosted: Wed Aug 31, 2011 10:43 pm 
Offline

Joined: Sat Oct 30, 2010 6:04 pm
Posts: 574
>>Does not work. Compiled a redboot image (reboot.bin) and using your suggestion to upload it I still get the error message above.

What error message, on what processor?

How large is your image? The AT91SAM9xxx parts have some small SRAM into which ROMBoot loads code from the first sector of NAND. This is typically AT91BootStrap, which initializes the clocks and SDRAM, and then straps in u-Boot or whatever into SDRAM and runs that. A limit of 4 or 16KB is typical for a large number of parts for the initial boot code.

If your code fails to follow some basic rules, ROMBoot will reject it. If it passes those tests, there's no guarantee you've coded it correctly.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 7 posts ] 

All times are UTC + 1 hour [ DST ]


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: