The router was fine. That is the part I keep coming back to. It worked, it had been working for two years, and nobody had complained about it once. So naturally I decided to reflash it with OpenWrt on a Saturday afternoon, for no better reason than that I could and it would be tidier. There is a particular kind of engineer who cannot leave a working thing alone, and I am writing this post to confirm that I am one of them.
The flash itself went badly in the most ordinary way. I had the right model, or I thought I did, but the hardware revision underneath the case was a later one with a different flash chip, and the image I wrote did not match. The router took the firmware, rebooted, and then did nothing at all. No lights in any sequence I recognised, no DHCP, no web interface, no ping. A brick, in the proper sense, and entirely self-inflicted.
The console nobody advertises
Here is the thing that saved it. Almost every router of this class has an unpopulated serial header on the board, sitting there quietly waiting for exactly this situation. It is how the engineers who built it talked to it, and it does not care whether the firmware is good. If you can find it, get a USB-to-TTL adapter onto it, and catch the bootloader before it hands off, you can almost always recover.
Finding it meant opening the case and looking for four pads in a row, then working out which was ground, which was transmit and which was receive. A multimeter and patience handle the first, and for the rest you can usually swap two wires and try again because the worst case is that you see nothing. The one rule worth shouting: do not touch the voltage pad. These run at 3.3 volts and putting five volts down a transmit line is how you turn a recoverable brick into a real one.
With the adapter wired and a terminal open at the usual speed, I rebooted the router and there it was, the bootloader spilling its log out over serial like nothing was wrong. I interrupted it before it tried to load the broken firmware, dropped into its little command environment, and from there I could point it at a TFTP server on my laptop and have it pull down a correct image over the network.
tftpboot 0x80000000 openwrt-correct.bin
erase 0x9f020000 +0x7c0000
cp.b 0x80000000 0x9f020000 0x7c0000
bootm
A nervous minute or two while it wrote, a reboot, and the lights came up in the right order. Recovered. The router now runs the OpenWrt I wanted, and it is genuinely nicer than the stock firmware, which is the small mercy that lets me pretend the afternoon was well spent.
The lesson is not "do not flash routers", because flashing routers is great and OpenWrt is worth having. The lesson is to know your recovery path before you break the working thing, not after. I got lucky that this board had an accessible header and a sane bootloader. Plenty do not. Next time I will read the hardware revision off the actual board rather than trusting the sticker, and I will have the serial adapter clipped on and a terminal open before I write a single byte, so that the recovery is already in place when I inevitably need it.