From c8161b013c9d3c454365b31b129213572909ec33 Mon Sep 17 00:00:00 2001 From: Paul Fertser Date: Mon, 30 Dec 2013 22:33:43 +0400 Subject: [PATCH] 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 Reviewed-on: http://openocd.zylin.com/1850 Tested-by: jenkins Reviewed-by: Spencer Oliver --- doc/openocd.texi | 11 ++++ tcl/tools/firmware-recovery.tcl | 108 ++++++++++++++++++++++++++++++++ 2 files changed, 119 insertions(+) create mode 100644 tcl/tools/firmware-recovery.tcl diff --git a/doc/openocd.texi b/doc/openocd.texi index d2a22596..59b5b7d6 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -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 diff --git a/tcl/tools/firmware-recovery.tcl b/tcl/tools/firmware-recovery.tcl new file mode 100644 index 00000000..718de0bd --- /dev/null +++ b/tcl/tools/firmware-recovery.tcl @@ -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/.cfg -f tools/firmware-recovery.tcl -c \"*; shutdown\" + +Where: + is one of the supported devices, e.g. ftdi/jtagkey2 + are firmware-recovery commands separated by semicolon + +Supported commands: +firmware_help get this help +list_boards list known boards and exit +board select board you work with +list_partitions list partitions of the currently selected board +dump_part save partition's contents to a file +erase_part erase the given partition +flash_part erase, flash and verify the given partition +ram_boot load binary file to RAM and run it +adapter_khz 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 "" -- 2.39.5