One day I decided to install an alternative firmware on my NETGEAR N600 in order to tweak lower-level settings and try to minimize frequent (and very frustrating) disconnections on Splatoon. But the setup failed, effectively bricking the router.
“No sweat”, I thought, “let me just put it into some sort of recovery mode and flash the original firmware into it”. For this router, the idea would be to transfer the firmware via TFTP - which works by setting up a computer with fixed TCP/IP configs and starting the transfer at the right time during the boot process.
That didn’t work either.
At that point, I realized this fix would require some physical hacking.
The idea was to connect a computer to the router via serial port and run some lower-level commands to restore the old firmware. But there was a catch: almost any decent router has a serial port, but very few have a serial port connector. To make the connection, I’d have to open the device and hook the computer’s serial port to the router motherboard pins that contain the serial port signals (TX/RX/GND).
To make things even worse, mine doesn’t have the pins, but just the holes on the board where they should be. Gee, thanks, Netgear! Tried soldering a header, but there was some gunk in one of the pins that I could not melt (they really don’t want to make it easy), so I had to precariously keep them in place with a soldering “third hand”.
Since each revision of the board has a slightly different pinout, I needed some multimeter peeking + trial-and-error to find the correct pin layout. Mine is the v3 and here is the setup that worked (green/6 = GND, blue/5 = RX, brown/2 = TX):
Router connection solved, now to the computer side. Computers these days don’t have serial ports - and even if they did, traditional (RS232) serial connectors are electrically incompatible with onboard serial circuits (TTL). Here are two possible workarounds:
- Use a Raspberry Pi by configuring a pair of GPIO pins to operate as a TTL serial device;
- Get a cheap TTL-level USB-to-serial converter and plug it into any computer.
In any case, once you set up your terminal emulaton software with the proper parameters (115200/8/N/1), it should operate as a console to the router, so when you turn it on, you will see the boot messages of its Linux-based operating system:
Decompressing..........done Decompressing..........done CFE for WNDR3700v3 version: v1.0.6 Build Date: Wed May 18 17:25:10 CST 2011 Init Arena Init Devs. Boot partition size = 262144(0x40000) Found an ST compatible serial flash with 128 64KB blocks; total size 8MB et0: Broadcom BCM47XX 10/100/1000 Mbps Ethernet Controller 2010.09.30.0 CPU type 0x19740: 480MHz Tot mem: 65536 KBytes Device eth0: hwaddr 2C-B0-5D-44-1A-1C, ipaddr 192.168.1.1, mask 255.255.255.0 gateway not set, nameserver not set Loader:raw Filesys:tftp Dev:eth0 File:192.168.1.2:vmlinuz Options:(null) Loading: Failed. Could not load 192.168.1.2:vmlinuz: Timeout occured too long file. LZMA boot failed Loader:raw Filesys:raw Dev:flash0.os File: Options:(null) Loading: .. 5192 bytes read Entry at 0x80001000 Closing network. Starting program at 0x80001000 Linux version 18.104.22.168 (root@tomato) (gcc version 4.2.4) #22 Mon Dec 5 07:45:34 CET 2016 CPU revision is: 00019740
(snipped - full output here)
eth0: Broadcom BCM47XX 10/100/1000 Mbps Ethernet Controller 22.214.171.12412 wl_module_init: passivemode set to 0x0 eth1: Broadcom BCM4329 802.11 Wireless Controller 126.96.36.19912 PCI: Enabling device 0000:01:01.0 (0000 -> 0002) eth2: Broadcom BCM4331 802.11 Wireless Controller 188.8.131.5212 / #
This shows Tomato (the custom firmware) is booting up (and possibly failing at some point), and we can see the TFTP daemon starting as well. I tried to use the output as guidance to do the timed TFTP trick, yet with no result. Having a root-y
# prompt at the end allowed me to fool around a bit, but not to properly start the tftp daemon or change anything much useful.
Decompressing..........done Decompressing..........done CFE for WNDR3700v3 version: v1.0.6 Build Date: Wed May 18 17:25:10 CST 2011 Init Arena Init Devs. Boot partition size = 262144(0x40000) Found an ST compatible serial flash with 128 64KB blocks; total size 8MB et0: Broadcom BCM47XX 10/100/1000 Mbps Ethernet Controller 2010.09.30.0 CPU type 0x19740: 480MHz Tot mem: 65536 KBytes Device eth0: hwaddr 2C-B0-5D-44-1A-1C, ipaddr 192.168.1.1, mask 255.255.255.0 gateway not set, nameserver not set Startup canceled CFE> ^C CFE> ^C CFE> ^C CFE> ^C CFE>
That shell allowed me to start
tftpd manually. That instance would not time out, allowing the proper transfer of the firmware:
CFE> tftpd Start TFTP server Reading :: Done. 7258170 bytes read Programming...done. 7258170 bytes written Write len/chksum offset @ 0x006FFFF8...done. Decompressing..........done
Once that process was finished, a reboot brought my router back to life, with the original system’s boot message:
Linux version 2.6.22 (lawrence@foxconncpe2) (gcc version 4.2.3) #8 Sat Dec 14 13 :13:11 CST 2013
The full output of the original firmware suggests the CFE is not overwritten when a new firmware is flashed - meaning it will always be there as a last resource.
Of course, figuring all this took me a very long time. In the meantime, I had to get a new router, and I picked the LinkSys WRT3200ACM - a spiritual descendant of the WRT54G series that started the custom router firmware frenzy. Its beefed-up wireless specs guarantee consistent Splatoon matches. But it was quite fun to get “old” router back in working shape - and I learned a ton on the process!