Disclaimer: This is a description of how I debricked my router with
a JTAG adapter. It's not a complete step by step guide but I try to include all
my links and resources which I used to gather the information and tools to
accomplish this. These may help you to find your own way to reanimate your
device.
Disclaimer 2: This happened to me last december, but
I haven't found the time to finish this article back then.
Last weekend I was trying to update the openwrt firmware on my
Linksys WRT54GL v1.1
router. For the first time I used the
sysupgrade utility
of openwrt. It should be the same like directly using the
mtd command to write the new
firmware to flash, except that I will save your config files and restore it
after booting the new firmware. Actually quite nice.
Enough theory back to the real stuff. I doesn't know why exactly but after executing
$ sysupgrade bin/openwrt-brcm47xx-squashfs.trx
on the device, the green power led was blinking and blinking. After some while nothing changed, so I removed the power cord (maybe I didn't waited long enough) and replugged it. Needless to say it was blinking green again, forever. Normally a flashing power led means, that the bootloader is running and will boot the firmware soon. After some time the DMZ led should light up and signal that openwrt has started. But this never happened. It was Saturday afternoon and I just made a new paperweight. Congratulations.
Table of Contents
- My adhoc JTAG experiment – The setup
- Try some other methods to restore the firmware
- Opening the case of a Linksys WRT54GL router
- Soldering the JTAG cable
- Running the software
- Flash layout and backup
- Flashing a new firmware
Debricking the device
-1. My adhoc JTAG experiment – The setup
Description of the image:
- The PCB of the router upside down. It's connected to power, ethernet and JTAG.
- The just in time made JTAG cable DLC5, soldered on a breadboard.
- My Thinkpad X40 notebook with an old fashioned parallel port
- Coffee mug. Yea, it was very late last at night.
- The LEDs of the router. The image was taken after I successfully flashed a new firmware. Thats why the led is shining orange constantly. In the bricked state it was blinking green.
0. Try some other methods to restore the firmware
Before soldering your own JTAG-Adapter, you should try some other
debrick methods which are easier and faster. They are described in the
OpenWrt wiki and in
DD-Wrt wiki.
For example if you enabled boot_wait in the nvram configuration (that's
the bootloader config) you can try to use the TFTP-Method to flash a new firmware).
Needless to say, none of these methods worked anymore.
(Note: After restoring my OpenWrt firmware, I wasn't able to successfully use
the TFTP-Server in the bootloader with
$ nvram set boot_wait=on $ nvram set boot_time=10 $ nvram set wait_time=10 $ nvram commit && reboot
(see
Using the TFTP method). I check the udp port 69 with nmap and the network
traffic with wireshark. No reactions. It seems the bootloader isn't working
correctly.)
So, what do we have: a router with a corrupted firmware and maybe with a
corrupted bootloader, too. Some basic skills in soldering and the will to fix it.
I've you can't open it, you don't own it.
1. Opening the case of a Linksys WRT54GL router
Opening the router may void your warranty. But flashing an openwrt firmware may have void your warranty already. Anyway. Not until I watched this youtube video, I managed to opened the case. The trick is simply stated: You have to pull very, very hard. That's it. Note: There maybe two screws below two of the four feets. Mine has none but check this first!
2. Soldering the JTAG cable
Since I wanted to restore my firmware within some hours, I have to find a
simple JTAG cable and using only electronic parts which are in my toolbox
already or which I can recycle them from existing projects. A simple JTAG cable for
the Linksys WRT54GL router is the Xilinx DLC5 JTAG Parallel Cable III.
Search for the term DLC5 on the internet and you find a lot of
tutorials to build it. I used the descriptions
Unbuffered Cable, Xilinx DLC5 Cable III
and JTAG-adapter.
The pin layout for the jtag port on the router pcb is documented
on the
WRT54G Website
of the OpenWrt wiki.
Every piece of equipment and software needs some sort of debugging utility and testing until it works correctly. I checked every connection of the jtag cable with a circuit analyser whether it's connected to the correct pin and hasn't any bypass with some other pin. And this was really necessary. I noticed that the connector on the breadboard wasn't connected properly. Nothing worked until I fix it.
3. Running the software
First I tried to use urjtag tool, but I
couldn't successfully get an image of the flash or reflash the device.
Nevertheless I will describe it here, because I may work for you and is a good
starting point to test your jtag cable.
First use your favorite package manager of your distro to install the urjtag
package. In gentoo it's the package dev-embedded/urjtag, in Ubuntu
it's called urjtag. After that you should check your parallel port.
If theres a file /dev/parport0, you have a parallel port and your kernel
is configured correctly. Since I use my own vanilla kernel with my own configuration,
the device /dev/parport0 wasn't there right once, although my notebook
has a parallel port in the docking station and the file /dev/lp0 is
available. lp0 is the device for a line printer. For the parport0
device you have to enable the kernel configuration parameter
CONFIG_PPDEV
and recompile your kernel, load the module or restart your computer.
Now you can assemble your router and your jtag cable. Plug in the power and
test the connection. In a root shell execute the command jtag and the
output is
$ jtag UrJTAG 0.10 #1502 Copyright (C) 2002, 2003 ETC s.r.o. Copyright (C) 2007, 2008, 2009 Kolja Waschk and the respective authors UrJTAG is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. There is absolutely no warranty for UrJTAG. WARNING: UrJTAG may damage your hardware! Type "quit" to exit, "help" for help. jtag>
Now it's time to define your type jtag cable. I used the DLC5 (see above).
jtag> cable DLC5 ppdev /dev/parport0
If this doesn't work because you don't have a /dev/parport0 file but you have a parallel port installed, you can use the PORTADDR method like
jtag> cable DLC5 parallel 0x3bc Initializing parallel port at 0x3bc
I found the address 0x3bc in the
Linux I/O port programming mini-HOWTO.
Now cross your fingers and type the magic command detect,
then urjtag will try to use the jtag cable to communicate with our router's micro
processor. If this this successful, you get the following output
jtag> detect IR length: 8 Chain length: 1 Device Id: 00000101001101010010000101111111 (0x000000000535217F) Manufacturer: Broadcom Unknown part! chain.c(149) Part 0 without active instruction chain.c(200) Part 0 without active instruction chain.c(149) Part 0 without active instruction jtag>
Hurray, it's working. If not, e.g. you don't get any output or something like
jtag> detect Warning: TDO seems to be stuck at 1
check your electrical connections with a circuit analyzer. I had this problem, because a pin wasn't properly connected (see above).
The next thing I tried was to make a flash dump with urjtag. I followed this forum thread Broadcom BCM5352 support?, because they dealt with the same Device Id 0x535217F. But the detectflash command was never successful. Since I don't have enough experience with JTAG, MIPS and urjtag to debug the issue myself, I looked for another solution.
The HairyDairyMaid utility is designed to debrick WRT54G routers. It's free software and the credit goes to HairyDairyMaid (a.k.a. - lightbulb). I didn't find an official homepage, so I got the sourcecode from the DD-Wrt people. The link is
ftp://ftp.dd-wrt.com/others/jtag%20tools/HairyDairyMaid_WRT54G_Debrick_Utility_v48.zip sha1sum: a198106be5753beaf0f4e01da295eb139bf97ef2 sha256sum: 609e3f2e0c4013261b05a76e072e511f514e12e217fcc71f6df2602d8444098c
It wasn't working out of the box and I had to tweak the code a little bit. You can get my changes from the git repository
$ git clone http://git.stefanchrist.eu/HairyDairyMaid_WRT54G_Debrick_Utility_v48.git
After compiling HairyDairyMaid you can try it with
$ ./wrt54g -probeonly /noemw ==================================== WRT54G/GS EJTAG Debrick Utility v4.8 ==================================== Probing bus ... Done Instruction Length set to 8 CPU Chip ID: 00000101001101010010000101111111 (0535217F) *** Found a Broadcom BCM5352 Rev 1 CPU chip *** - EJTAG IMPCODE ....... : 00000000100000000000100100000100 (00800904) - EJTAG Version ....... : 1 or 2.0 - EJTAG DMA Support ... : Yes Issuing Processor / Peripheral Reset ... Done Enabling Memory Writes ... Skipped Halting Processor ... <Processor Entered Debug Mode!> ... Done Clearing Watchdog ... Done Probing Flash at (Flash Window: 0x1fc00000) ... Done Flash Vendor ID: 00000000000000000000000011000010 (000000C2) Flash Device ID: 00000000000000000010001010101000 (000022A8) *** Found a MX29LV320B 2Mx16 BotB (4MB) Flash Chip *** - Flash Chip Window Start .... : 1fc00000 - Flash Chip Window Length ... : 00400000 - Selected Area Start ........ : 00000000 - Selected Area Length ....... : 00000000 *** REQUESTED OPERATION IS COMPLETE ***
You see, it's working nicely. I had to use /noemw otherwise my router stopped working.
4. Flash layout and backup
The WRT54GL contains 4MiB of flash memory. If your OpenWrt firmware is running, you can see the flash layout with the command cat /proc/mtd. The output is
dev: size erasesize name mtd0: 00040000 00010000 "cfe" mtd1: 003b0000 00010000 "linux" mtd2: 002c9800 00010000 "rootfs" mtd3: 00170000 00010000 "rootfs_data" mtd4: 00010000 00010000 "nvram"
From this you can guess the actual flash layout
from - to size name 0x000000 - 0x03FFFF 0x040000 CFE 0x040000 - 0x3EFFFF 0x3b0000 Firmware (here 'linux', also called 'kernel') 0x3F0000 - 0x400000 0x010000 nvram
For further details see The OpenWrt Flash Layout in the OpenWrt wiki. CFE is the bootloader of the device (You can get the source from the broadcom site Communications Processors Downloads. It shouldn't be possible to build your own CFE binary, because the hardware vendors may include there own setup code). The CFE will read configuration variables from the nvram (e.g. the above mentioned 'boot_wait' is such a configuration parameter). You can either use the nvram utility of OpenWrt or read it with your favorite unix tools, e.g. cat /dev/mtd4ro | strings. The Firmware is the actual operating system of your router. It maybe the original firmware or a free one like OpenWrt.
Before flashing a new firmware, I took a minute and made a backup of my flash memory. I could to this with
$ ./wrt54g -backup:kernel /noemw $ ./wrt54g -backup:cfe /noemw $ ./wrt54g -backup:nvram /noemw
These commands created three files in the current working directory:
'KERNEL.BIN.SAVED_20131214_235857', 'CFE.BIN.SAVED_20131215_004211' and 'NVRAM.BIN.SAVED_20131215_004553'
Based on the timestamps you can guess that this procedure took more than just a minute ;-). The JTAG interfaces is quite slow. Therefore the HairyDairyMaid utility is recommending:
*************************************************************************** * Flashing the KERNEL or WHOLEFLASH will take a very long time using JTAG * * via this utility. You are better off flashing the CFE & NVRAM files * * & then using the normal TFTP method to flash the KERNEL via ethernet. * ***************************************************************************
In my case this approach wasn't possible, because I haven't made a backup of the CFE and the nvram before the accident. Additionally the TFTP server in the bootloader wasn't working.
5. Flashing a new firmware
The last step is flashing a new firmware. First I tried to use my OpenWrt firmware, but
the router didn't come up. So I decided to use the original firmware from Linksys.
You can find it on the product page Linkysys WRT54GL. Here is the direct link to the file:
FW_WRT54GL_4.30.16.6_US_20130308_code.bin
(sha1sum: 313a977ca262a8908eab18ad8e912e128407ee33).
Running the Linksys firmware on the device I used the webinterface to flash
my OpenWrt firmware again. Yeah the Linksys firmware is only useful as a
sophisticated flash utility to install a real OS :-).
Later I noticed that this procedure is suggested in the
DD-Wrt wiki - Recover from a bad flash:
Linksys WRT54 GL:
Linksys wrt54 GL users please note that if flashing with tftp using dd-wrt firmware gives no results, original Linksys firmware from www.linksys.com is worth trying. If that works, do a hard reset and you can continue to flash with dd-wrt.
Ok, the overall process is clear. How to use the HairyDairyMaid program to flash the Linksys firmware/kernel? First you have to convert the .bin firmware image to a trx-file. You have to remove the first 32 bytes, e.g. you can use the tool dd
$ dd bs=32 skip=1 if=FW_WRT54GL_4.30.16.6_US_20130308_code.bin of=FW_WRT54GL_4.30.16.6_US_20130308_code.trx
Then the trx-file must be flashed to the flash location 0x040000.
On boot CFE will compare the checksum of the firmware. If it's correct, it
will load and execute it.
More information is in the OpenWrt wiki
TRX vs. TRX2 vs. BIN.
To flash it you have to rename the trx-file to KERNEL.bin,
because the program wrt54g uses this specific filename. There isn't a
commandline parameter for that. Instead of renaming I used a symbolic link:
$ ln -s FW_WRT54GL_4.30.16.6_US_20130308_code.trx KERNEL.BIN $ ./wrt54g -flash:kernel /noemw
Flashing with the JTAG adapter will take some time, but afterwords you have a happily running WRT54GL router again. That's it.