Christian Ulrich ~ Flashing OpenWrt on my VDSL2 router

After my previous DSL router (a Fritzbox) lost its modem due to a lightning strike, I decided to buy a cheaper replacement: The TP-Link W9980B. Currently it's available for around 50 €. The B indicates that it's the Annex B version, which is relevant if you want to use ADSL from German providers, for VDSL it's not relevant.

It's running OpenWrt, in the manufacturer's flavour, that is you can't login via SSH and you can't install or upgrade software packages. Luckily the OpenWrt wiki has good instructions on how to flash your own firmware image. I started with the prebuilt image linked on the wiki page, but I'm planning to compile my own image soon.

The procedure is like this:

  1. start a TFTP server on your PC (see below)
  2. get access to the UART serial console using a UART interface device (see below)
  3. temporarily pull the solder pad (specified in the wiki) to GND while resetting the router; the bootloader will enter UART mode which allows transferring a new bootloader image
  4. transfer the bootloader (u-boot) image and wait for the router to restart
  5. enter the TFTP console by pressing 't'
  6. transfer the firmware image from the TFTP server, and flash it

The instructions on the wiki page are straightforward, some confusion might occur about the pinout, which differs between the Annex A and the Annex B version. What is missing in the article is detailed instructions on how to start the TFTP server (step 1) and how to access the serial console (step 2).

The TFTP server

I used atftp which requires a world-readable and -writable directory, e.g. /tftproot, where the firmware image is kept:

mkdir /tftproot
chmod 0777 /tftproot
cp ~/Downloads/openwrt-15.05.1-lantiq-xrx200-TDW8970-sysupgrade.image /tftproot/sysupgrade.image

The TFTP server can then be started as root using

atftpd --daemon --user nobody --group nobody /tftproot

or by using an init script shipped with the software package, e.g.

/etc/init.d/atftp start

Now test if the TFTP works by using atftp locally:

atftp localhost
tftp> get sysupgrade.image
# no error message means you downloaded the file successfully; exit with CTRL-d

The UART interface

Many devices that can be used as interface between the router's serial console and the PC's USB port are listed in the OpenWrt wiki. I am a happy owner of a Bus Pirate in version 3.6 which can do many things and also act as a UART interface. There are two different versions of the cable shipped with the Bus Pirate, having an opposite wire order. For my version I had to connect it to the router's pins like this:

Bus Pirate pin W9980B pin (see wiki)
MISO (black) RX
MOSI (grey) TX
GND (brown) GND
+3V3 (red) VCC

When connecting the Bus Pirate to the PC via USB we can check with dmesg whether a device file was created sucessfully.

dmesg | grep -i usb
[22680.323076] usb 1-1.2: new full-speed USB device number 4 using ehci-pci
[22680.415645] usb 1-1.2: New USB device found, idVendor=0403, idProduct=6001
[22680.415651] usb 1-1.2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[22680.415655] usb 1-1.2: Product: FT232R USB UART
[22680.415659] usb 1-1.2: Manufacturer: FTDI
[22680.415662] usb 1-1.2: SerialNumber: A901LRU4
[22680.564751] usbcore: registered new interface driver ftdi_sio
[22680.564772] usbserial: USB Serial support registered for FTDI USB Serial Device
[22680.564824] ftdi_sio 1-1.2:1.0: FTDI USB Serial Device converter detected
[22680.564866] usb 1-1.2: Detected FT232RL
[22680.565760] usb 1-1.2: FTDI USB Serial Device converter now attached to ttyUSB0

We can see that the device file /dev/ttyUSB0 was created which can be used to talk to the Bus Pirate. If this output is not there the kernel may be missing an FTDI driver. In this case see the Gentoo wiki for instructions.

Furthermore a user needs to be in the uucp group for being able to access the device file:

usermod -a -G uucp christian # logout and login required

Now we can use a terminal emulator like picocom to talk to the bus pirate:

picocom -b 115200 /dev/ttyUSB0 # exit picocom by holding CTRL and typing a, x

Type 'm' to see the Bus Pirate's menu and choose 3, 9, 1, 1, 1, 2 to configure the UART mode. That is

The Bus Pirate console supports macros for common tasks. These can be displayed by typing '(0)':

 0.Macro menu
 1.Transparent bridge
 2.Live monitor
 3.Bridge with flow control
 4.Auto Baud Detection

What we need is the transparent bridge which allows transparent interaction with the router's serial console. Type '(1)' and 'y' to start the transparent bridge. It can only be exited by resetting the Bus Pirate.

Now when we reset the router we should see the serial console output in picocom and can continue with the steps 3 to 6 mentioned above.


The TP-Link W9980B is an affordable VDSL2 router which allows installing an own OpenWrt image almost painlessly. One downside is that no open source driver is available for the 5GHz Wifi chip, so only the 2.4 GHz Wifi can be used. For me that's ok.

Now I'm able to install security patches and my own software on the router. The next step will be compiling my own OpenWrt image instead of using the prebuilt one.