Unbricking a TP-Link TL-WR1043ND

A while ago one of the people that use my OpenWRT builds managed to brick his TP-Link TL-WR1043ND. So of course I wanted to know what happened, what went wrong? It seems he did a “sysupgrade” but was short on time, so he did it a bit quick. For those familiar with Murphy’s law, that one always manages to ruin your day when you want something technical done quickly…

My guess is either his download corrupted and he skipped checking the MD5 checksum or something went wrong with the flash. Whatever, went wrong… it doesn’t really matter anymore, his router would not boot any longer. When he plugged it in, all it did was flash it’s PWR LED on and that was it. It did not respond on it’s network interfaces nor was he able to use the OpenWRT fail-safe boot.

I had a hunch the rootfs of his router was corrupted in some way, and the boot-loader would still work. Because a sysupgrade procedure only touches the rootfs as far as I know. While doing some research on debricking I learned that it would be possible to reflash the rootfs from the boot-loader over TFTP. Next step: how to get in touch with the U-Boot boot-loader?

Serial Connection

Like lots of other routers, there is a Serial TTL interface on the board connected to the SoC. What needs to be done is solder some headers to the holes in the PCB, so you can hook up a serial console to it. Once that’s done it’s possible to talk to the U-Boot boot-loader.

On the PCs side you need something that can speak 3.3V TTL. Regular serial ports, the ones you used to find on PCs, use a higher voltage, so you cannot use those. And most PCs do not even offer a serial port anymore, perhaps some headers on the motherboard but that’s about it. To solve this I bought a USB-TTL converter from DealExtreme for about 7 Euros. It comes with a cable to connect it to the router as well.

For most people the CP2102 USB-TTL converter seems to work out-of-the-box or after instructing Windows to look for drivers on Windows Update. Linux should also support it out of the box. In case you run Windows, and need drivers to get it to recognize, here’s a link to the SiLabs CP201x USB to UART Bridge drivers.

On the software side you can use GNU Screen on Linux, or PuTTY on Windows, and there are plenty of alternatives if you need one.

Modifying the router

Inside the TL-WR1043ND are 4 holes for the TTL interface. You find these holes in a single row on the front right of the PCB, while looking at the router from the front, close to the openings for a JTAG port.

First act is to open the case. This is fairly straight-forward, but some instruction how to do it for the first time comes in handy. Have a look at OpenWRT Wiki - TL-WR1043ND - Opening/Closing the case

The pin-out can be found at OpenWRT Wiki - TL-WR1043ND - Serial and here’s the picture for reference.

Picture of TL-WR1043ND UART pin-out on the PCB

Soldering the header to it requires a good soldering iron with a small tip. The RX and TX headers are quite easy to solder, but the GND pin can dissipate the heat over a large area of the board. I had trouble with it, but eventually got it done with an extra pairs of hands and an extra soldering iron for some more heat. You don’t need VCC by the way.

Talking to the bootloader

So let’s hook up the USB-TTL converter to the router: Connect GND to the GND pin, RX to TX and TX to RX pin. And connect to the PC by plugging it in the USB port. Start your serial console of choice and configure it for a baud rate of 115200 (8 data bits, No parity, 1 stop bit, no flow control, all are often defaults). I have used PuTTY in this case because I happened to be on my Windows box at the time. Set it to Serial mode and told it to use COM3 as the communication device. You should check under what device name your USB-TTL converter presents itself to your OS.

Once your serial console it running, power up your router and watch the console for output. On my first attempt I got no output. I needed to reverse my RX and TX connectors, once I did that and re-powered the router it worked immediately. As soon as you see the message Autobooting in 1 seconds type “tpl” quickly. It will interrupt the boot process and give you a minimal shell in the U-Boot boot-loader to send it commands. I had this on my console:

U-Boot 1.1.4 (Mar 31 2012 - 10:40:21)

AP83 (ar9100) U-boot 0.0.11
32 MB
id read 0x100000ff
flash size 8MB, sector count = 128
Flash:  8 MB
Using default environment

In:    serial
Out:   serial
Err:   serial
Net:   ag7100_enet_initialize...
No valid address in Flash. Using fixed address
: cfg1 0xf cfg2 0x7114
eth0: 00:03:7f:09:0b:ad
eth0 up
Autobooting in 1 secondsar7100>

If you get something similar, its time for the next step.

TFTP server

I used a Linux box I had laying around for this. You can use the machine you are working on if you like.

Download firmware

Download the factory image of my OpenWRT Regular build for the TL-WR1043ND and save it as code.bin to an appropriate directory:

# mkdir /srv/tftpd
# wget -O /srv/tftpd/code.bin http://openwrt.sjoosten.nl/files/attitude_adjustment/12.09/r36655/ultrawrt-regular/ar71xx/openwrt-ar71xx-generic-tl-wr1043nd-v1-squashfs-factory.bin
# md5sum /run/shm/tftpd/code.bin 
fe26aa331c8a48ab41683086f9bea7be  /run/shm/tftpd/code.bin

And of course check it’s MD5 hash to make sure it’s proper.

Just in case, you should check the IP address of the machine you are using as TFTP server, so we can later instruct U-Boot where to look. Use ip addr or ifconfig for this. The IP of my TFTP server is

Next, install dnsmasq or tftpd-hpa to serve the file over TFTP. I used dnsmasq.

# apt-get install dnsmasq
# /etc/init.d/dnsmasq stop          # Debian automatically starts it as a daemon, so I stop it
# dnsmasq --enable-tftp --tftp-root=/srv/tftp/

Flashing the router

If you still have your serial console open from testing if it worked or not, you can continue where we left off. If not, open it again, power up the router and interrupt to boot process by typing ‘tpl’ quickly after the Autobooting in 1 seconds message.

Configure networking

First off I configured the IP address of the router (default: and the IP of the TFTP (default: it will look for. I’ve set the IP address to a range my DHCP server does not issue, and the TFTP server IP to the one of the spare Linux box running DNSMasq as TFTP server. Adjust these for your situation:

ar7100> setenv ipaddr
ar7100> setenv serverip

Confirm the settings have been accepted correctly by entering printenv :

ar7100> printenv
bootargs=console=ttyS0,115200 root=31:02 rootfstype=jffs2 init=/sbin/init mtdparts=ar9100-nor0:128k(u-boot),1024k(kernel),4096k(rootfs),64k(art)
bootcmd=bootm 0xbf020000

Erase the corrupt firmware

Now it’s time to erase the corrupted firmware so it’s all nice and clean before flashing:

ar7100> erase 0xbf020000 +7c0000

First 0x2 last 0x7d sector size 0x10000                                                                            125
Erased 124 sectors

Load new firmware over TFTP to memory

ar7100> tftpboot 0x81000000 code.bin
Using eth0 device
TFTP from server; our IP address is
Filename 'code.bin'.
Load address: 0x81000000
Loading: #################################################################
[..I've cut some lines here..]
Bytes transferred = 8126464 (7c0000 hex)

Flash the new firmware

ar7100> cp.b 0x81000000 0xbf020000 0x7c0000
Copy to Flash... write addr: bf020000

Boot the new firmware

ar7100> bootm 0xbf020000
## Booting image at bf020000 ...
Uncompressing Kernel Image ... OK

Starting kernel ...

OpenWrt kernel loader for AR7XXX/AR9XXX
Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org>
Looking for OpenWrt image... found at 0xbf022000
Decompressing kernel... done!
Starting kernel at 80060000...

[    0.000000] Linux version 3.3.8 (stefan@bacchus) (gcc version 4.6.3 20120201 (prerelease) (Linaro GCC 4.6-2012.02) ) #1 Fri May 17 19:36:54 CEST 2013

Yay! It’s working again. Enjoy!


Some resources I came across and benefited from: