]> git.sur5r.net Git - openocd/blob - tcl/tools/firmware-recovery.tcl
tools: add firmware recovery helpers
[openocd] / tcl / tools / firmware-recovery.tcl
1 echo "\n\nFirmware recovery helpers"
2 echo "Use -c firmware_help to get help\n"
3
4 set known_boards {
5     "asus-rt-n16                ASUS RT-N16"
6     "linksys-wrt54gl            Linksys WRT54GL v1.1"
7 }
8
9 proc firmware_help { } {
10     echo "
11 Your OpenOCD command should look like this:
12 openocd -f interface/<jtag adapter>.cfg -f tools/firmware-recovery.tcl -c \"<commands>*; shutdown\"
13
14 Where:
15 <jtag adapter> is one of the supported devices, e.g. ftdi/jtagkey2
16 <commands> are firmware-recovery commands separated by semicolon
17
18 Supported commands:
19 firmware_help                   get this help
20 list_boards                     list known boards and exit
21 board <name>                    select board you work with
22 list_partitions                 list partitions of the currently selected board
23 dump_part <name> <filename>     save partition's contents to a file
24 erase_part <name>               erase the given partition
25 flash_part <name> <filename>    erase, flash and verify the given partition
26 ram_boot <filename>             load binary file to RAM and run it
27 adapter_khz <freq>              set JTAG clock frequency in kHz
28
29 For example, to clear nvram and reflash CFE on an RT-N16 using TUMPA, run:
30 openocd -f interface/ftdi/tumpa.cfg -f tools/firmware-recovery.tcl \\
31         -c \"board asus-rt-n16; erase_part nvram; flash_part CFE cfe-n16.bin; shutdown\"
32 \n\n"
33     shutdown
34 }
35
36 # set default, can be overriden later
37 adapter_khz 1000
38
39 proc get_partition { name } {
40     global partition_list
41     dict get $partition_list $name
42 }
43
44 proc partition_desc { name } { lindex [get_partition $name] 0 }
45 proc partition_start { name } { lindex [get_partition $name] 1 }
46 proc partition_size { name } { lindex [get_partition $name] 2 }
47
48 proc list_boards { } {
49     global known_boards
50     echo "List of the supported boards:\n"
51     echo "Board name\t\tDescription"
52     echo "-----------------------------------"
53     foreach i $known_boards {
54         echo $i
55     }
56     echo "\n\n"
57 }
58
59 proc board { name } {
60     script [find board/$name.cfg]
61 }
62
63 proc list_partitions { } {
64     global partition_list
65     set fstr "%-16s%-14s%-14s%s"
66     echo "\nThe currently selected board is known to have these partitions:\n"
67     echo [format $fstr Name Start Size Description]
68     echo "-------------------------------------------------------"
69     for {set i 0} {$i < [llength $partition_list]} {incr i 2} {
70         set key [lindex $partition_list $i]
71         echo [format $fstr $key [partition_start $key] [partition_size $key] [partition_desc $key]]
72     }
73     echo "\n\n"
74 }
75
76 # Magic to work with any targets, including semi-functional
77 proc prepare_target { } {
78     init
79     catch {halt}
80     catch {reset init}
81     catch {halt}
82 }
83
84 proc dump_part { name filename } {
85     prepare_target
86     dump_image $filename [partition_start $name] [partition_size $name]
87 }
88
89 proc erase_part { name } {
90     prepare_target
91     flash erase_address [partition_start $name] [partition_size $name]
92 }
93
94 proc flash_part { name filename } {
95     prepare_target
96     flash write_image erase $filename [partition_start $name] bin
97     echo "Verifying:"
98     verify_image $filename [partition_start $name]
99 }
100
101 proc ram_boot { filename } {
102     global ram_boot_address
103     prepare_target
104     load_image $filename $ram_boot_address bin
105     resume $ram_boot_address
106 }
107
108 echo ""