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):

Netgear N600 WNDR3700v3 serial pins

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:

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 2.6.22.19 (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 5.110.27.20012
wl_module_init: passivemode set to 0x0
eth1: Broadcom BCM4329 802.11 Wireless Controller 5.110.27.20012
PCI: Enabling device 0000:01:01.0 (0000 -> 0002)
eth2: Broadcom BCM4331 802.11 Wireless Controller 5.110.27.20012
/ #

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.

I was about to give up, but this page shows the trick: during boot, you can quickly press Ctrl+C and get to a Common Firmware Enviroment CFE> prompt:

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!