TFTP download from TP-Link Archer C2 does not work properly

I have been able to successfully flash OpenWrt on the TP-Link Archer C2 device whose TFTP recovery does not work properly. I have used the device's serial console to transfer the OpenWrt firmware to the router's memory. Then I have manually copied the transferred firmware from memory to flash.

In more detail

I have used the following steps:

  1. Connect the device's serial console to a terminal emulator on a host computer.
  2. Power on the device. Keep pressing the "t" key during the early boot stage. This will stop the boot process and launch the U-Boot prompt.
  3. Load an OpenWrt sysupgrade image for this device, e.g. this one, to the router's memory over serial console. Use the Kermit program on the host computer to transfer the file.
MT7620 # loadb
## Ready for binary (kermit) download to 0x80100000 at 115200 bps...
## Total Size      = 0x003f0110 = 4129040 Bytes  
## Start Addr      = 0x80100000
  1. Erase the flash memory used for the "firmware" mtd partition while keeping the flash memory used for the bootloader unchanged. The correct offset and size can be obtained and calculated e.g. from the flash layout section of the device's Table of Hardware page. This step might be optional but I am not fully sure.
MT7620 # erase tplink 0x20000 0x7a0000

 Erase flash !!
From 0x20000 length 0x7A0000
raspi_erase: offs:20000 len:7a0000
..........................................................................................................................
  1. Double check whether the new firmware has indeed been correctly loaded to the device's memory at the expected address.
MT7620 # md 0x80100000
80100000: 00000003 2e726576 302e3220 ffffff00    ....ver. 2.0....
80100010: ffffffff ffffffff ffffffff ffffffff    ................
80100020: ffffffff ffffffff ffffffff ffffffff    ................
80100030: ffffffff 010050c7 32000000 00000000    .....P.....2....
80100040: 7d5d75d5 d5cf2041 8bbcb69d 6fdae3c8    .u]}A .........o
80100050: 00000000 ffffffff ffffffff ffffffff    ................
80100060: ffffffff ffffffff 80000000 80000000    ................
80100070: 00007a00 00020000 f4de1700 f4e01700    .z..............
80100080: 40ef2600 00000000 00000000 0001aa55    .&.@........U...
80100090: 000000a5 ffffffff ffffffff ffffffff    ................
801000a0: ffffffff ffffffff ffffffff ffffffff    ................
801000b0: ffffffff ffffffff ffffffff ffffffff    ................
801000c0: ffffffff ffffffff ffffffff ffffffff    ................
801000d0: ffffffff ffffffff ffffffff ffffffff    ................
801000e0: ffffffff ffffffff ffffffff ffffffff    ................
801000f0: ffffffff ffffffff ffffffff ffffffff    ................
  1. Copy the newly loaded firmware from memory to the beginning of the "firmware" mtd partition in flash mentioned earlier while keeping the part of the flash occupied by the bootloader unchanged.
MT7620 # cp.b 0x80100000 0x20000 0x3f0110

 Copy 0x80100000 to 0x00020000, count 0x3F0110....
raspi_write: to:20000 len:3f0110
..........................................................................................................................
  1. Reboot the router.
MT7620 # reset

These steps have been inspired by this message in the old OpenWrt forum by user bd03E about adding early support for TP-Link Archer C2.

When using this approach, it is important to not overwrite the bootloader so that in case of a failure, the device will still remain bootable and the entire process could be repeated.

The erase and cp U-Boot commands have several custom variations:

MT7620 # help erase
erase
erase all
    - erase all FLASH banks
erase uboot
    - erase uboot block
erase linux
    - erase linux kernel block
erase tplink
   - erase blocks at addr with length
MT7620 # help cp
cp
cp.uboot
    - copy uboot block
cp.linux
    - copy linux kernel block
cp.b
    - src dst count.copy binary from source to target with count length.

which have been most likely designed to work well with the TFTP upgrade. However, they probably erase or copy data from hardcoded memory locations so I would avoid using them and only use those commands where the source and destination address can be explicitly specified.

Regarding the process of actually sending the firmware to the device over a serial console, it is described in general e.g. here. I have used the C-Kermit program with configuration as described in the U-Boot manual. It takes ~10 minutes to transfer ~5 MiB of data to this device using these settings.

Other approaches

I have also tried several other approaches which turned out to be unsuccessful, at least in my case. I will list them here for reference.

  1. Using the original TP-Link firmware to flash a new firmware manually.
    Despite the fact that it is possible log in as root to the device's original firmware (username: admin, password: 1234) both over the serial console and over ssh or telnet, I was not able to flash a new firmware from there because I could not figure out how to read and write the /dev/mtd* files. Perhaps some external binary could be used for this purpose but I did not look into that.
  2. Using a different version of U-Boot.
    I was able to load the same version of U-Boot into memory and then use the U-Boot's go command to run it. It worked well but I did not have a different version of U-Boot to try. I have, however, compared the U-Boot versions on the router whose TFTP download works with the one on which it does not work properly. They turned out to be exactly the same. So I assume that the issues with the TFTP download are caused by some subtle hardware differences between the two routers. Those differences then perhaps might cause U-Boot's TFTP download to work on one device but not on the other.
  3. Using the U-Boot bootloader to load a new firmware into memory and boot from it directly without having to write it to the flash memory first.
    As described above, I was able to load the firmware into the memory over the serial console. But I was not able to boot the Linux kernel directly from memory because of LZMA errors. The same kernel, however, works well when copied to flash. I am not sure why.
MT7620 # bootm
do_bootm:argc=1, addr=0x80100000
## Booting image at 80100000 ...
   Uncompressing Kernel Image ... LZMA ERROR 1 - must RESET board to recover

To summarize, the router works well with OpenWrt now. The issue with TFTP download does not affect the router's ability to erase flash or copy new data to it from within the U-Boot. So, the described work-around is based on replacing the TFTP download step with the download over the serial console.

2 Likes