tools: add firmware recovery helpers
This adds a set of helper functions with the aim to make it possible to flash mass-market devices without RTFMing altogether (i.e. to obsolete GPL-violating proprietary tjtag and other similar software). Real-life tested on an RT-N16 and WRT54GL. Change-Id: I197a9b28a5f386803f081057c4b4ebf2f9c447b1 Signed-off-by: Paul Fertser <fercerpav@gmail.com> Reviewed-on: http://openocd.zylin.com/1850 Tested-by: jenkins Reviewed-by: Spencer Oliver <spen@spen-soft.co.uk>__archive__
parent
302a3a8fed
commit
c8161b013c
|
@ -7973,6 +7973,17 @@ storage bit in the device is tested as zero and as one.
|
|||
Run all of the above tests over a specified memory region.
|
||||
@end deffn
|
||||
|
||||
@section Firmware recovery helpers
|
||||
@cindex Firmware recovery
|
||||
|
||||
OpenOCD includes an easy-to-use script to faciliate mass-market
|
||||
devices recovery with JTAG.
|
||||
|
||||
For quickstart instructions run:
|
||||
@example
|
||||
openocd -f tools/firmware-recovery.tcl -c firmware_help
|
||||
@end example
|
||||
|
||||
@node TFTP
|
||||
@chapter TFTP
|
||||
@cindex TFTP
|
||||
|
|
|
@ -0,0 +1,108 @@
|
|||
echo "\n\nFirmware recovery helpers"
|
||||
echo "Use -c firmware_help to get help\n"
|
||||
|
||||
set known_boards {
|
||||
"asus-rt-n16 ASUS RT-N16"
|
||||
"linksys-wrt54gl Linksys WRT54GL v1.1"
|
||||
}
|
||||
|
||||
proc firmware_help { } {
|
||||
echo "
|
||||
Your OpenOCD command should look like this:
|
||||
openocd -f interface/<jtag adapter>.cfg -f tools/firmware-recovery.tcl -c \"<commands>*; shutdown\"
|
||||
|
||||
Where:
|
||||
<jtag adapter> is one of the supported devices, e.g. ftdi/jtagkey2
|
||||
<commands> are firmware-recovery commands separated by semicolon
|
||||
|
||||
Supported commands:
|
||||
firmware_help get this help
|
||||
list_boards list known boards and exit
|
||||
board <name> select board you work with
|
||||
list_partitions list partitions of the currently selected board
|
||||
dump_part <name> <filename> save partition's contents to a file
|
||||
erase_part <name> erase the given partition
|
||||
flash_part <name> <filename> erase, flash and verify the given partition
|
||||
ram_boot <filename> load binary file to RAM and run it
|
||||
adapter_khz <freq> set JTAG clock frequency in kHz
|
||||
|
||||
For example, to clear nvram and reflash CFE on an RT-N16 using TUMPA, run:
|
||||
openocd -f interface/ftdi/tumpa.cfg -f tools/firmware-recovery.tcl \\
|
||||
-c \"board asus-rt-n16; erase_part nvram; flash_part CFE cfe-n16.bin; shutdown\"
|
||||
\n\n"
|
||||
shutdown
|
||||
}
|
||||
|
||||
# set default, can be overriden later
|
||||
adapter_khz 1000
|
||||
|
||||
proc get_partition { name } {
|
||||
global partition_list
|
||||
dict get $partition_list $name
|
||||
}
|
||||
|
||||
proc partition_desc { name } { lindex [get_partition $name] 0 }
|
||||
proc partition_start { name } { lindex [get_partition $name] 1 }
|
||||
proc partition_size { name } { lindex [get_partition $name] 2 }
|
||||
|
||||
proc list_boards { } {
|
||||
global known_boards
|
||||
echo "List of the supported boards:\n"
|
||||
echo "Board name\t\tDescription"
|
||||
echo "-----------------------------------"
|
||||
foreach i $known_boards {
|
||||
echo $i
|
||||
}
|
||||
echo "\n\n"
|
||||
}
|
||||
|
||||
proc board { name } {
|
||||
script [find board/$name.cfg]
|
||||
}
|
||||
|
||||
proc list_partitions { } {
|
||||
global partition_list
|
||||
set fstr "%-16s%-14s%-14s%s"
|
||||
echo "\nThe currently selected board is known to have these partitions:\n"
|
||||
echo [format $fstr Name Start Size Description]
|
||||
echo "-------------------------------------------------------"
|
||||
for {set i 0} {$i < [llength $partition_list]} {incr i 2} {
|
||||
set key [lindex $partition_list $i]
|
||||
echo [format $fstr $key [partition_start $key] [partition_size $key] [partition_desc $key]]
|
||||
}
|
||||
echo "\n\n"
|
||||
}
|
||||
|
||||
# Magic to work with any targets, including semi-functional
|
||||
proc prepare_target { } {
|
||||
init
|
||||
catch {halt}
|
||||
catch {reset init}
|
||||
catch {halt}
|
||||
}
|
||||
|
||||
proc dump_part { name filename } {
|
||||
prepare_target
|
||||
dump_image $filename [partition_start $name] [partition_size $name]
|
||||
}
|
||||
|
||||
proc erase_part { name } {
|
||||
prepare_target
|
||||
flash erase_address [partition_start $name] [partition_size $name]
|
||||
}
|
||||
|
||||
proc flash_part { name filename } {
|
||||
prepare_target
|
||||
flash write_image erase $filename [partition_start $name] bin
|
||||
echo "Verifying:"
|
||||
verify_image $filename [partition_start $name]
|
||||
}
|
||||
|
||||
proc ram_boot { filename } {
|
||||
global ram_boot_address
|
||||
prepare_target
|
||||
load_image $filename $ram_boot_address bin
|
||||
resume $ram_boot_address
|
||||
}
|
||||
|
||||
echo ""
|
Loading…
Reference in New Issue