firmware-recovery.tcl 3.3 KB

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