What would you do if your D-Link (TrendNet, Allied Telesyn or other crappy manufacturer) broke after the warranty period is exhausted?

Recently, exactly that happened to me: our DGS-1248T manageable switch, which we used to connect non-critical servers to, stopped working. Well, in fact, it continued to switch packets, but it become totally unmanageable, nothing better than these lower-end Compex or Surecom switches. Good value for money, isn't it? This brick, truly speaking, never worked fine — its f*cking so-called web-interface is compatible only with IE5, it has no telnet port, it has even no... rs232 interface.

Not willing to pay anything more to D-Link, I decied to fix it myself. At least, I decided, it would be a lot of fun, even if I fail to do that. Furthermore, my boss volunteered to help me out — being a good hardware engineer in the past, he's able to easily fix PCBs using just a 40W soldering iron. So, I rolled up my sleeves, took the screwdriver and opened the box:

DL1248T disassmbled

The hardware inside was semi-standard for such kind of devices — a printed circuit board with an ARM940T based Samsung S3C2510A SoC mircocontroller as its CPU, forth Vitesse Switch-on-a-chip cores, and a number of Vitesse PHYs (in fact, I thought Vitesse only produce teapots... probably D-Link just missed components — they're hot like a boiled water).

S3C2510A cpu

Vitesse folks seems to have a good sense of humor — their PHY chip is called SimpilPHY.

Vitesse PHYs

Unfortunately, there was no rs232 connector on the board — thus, no chance to see what happened to it. In fact, there was place to put a standard DB-9 connector on the PCB, but no signal output at all. Clearly, there was something missing... By looking in the CPU manual (well, not the CPU one, but evaluation board manual for previous Samsung model — 2410), I discovered, that the processor uses TTL voltage logic, and output driver for rs232 is recuired. And... near the UART contacts there was a place exactly for MAX2332 UART driver. Looks like they just took their development board and removed all debug components in retail version. Woot, woot!

We took our old oscilloscope to ensure if there were signals at the contact box. Yes, they were!

Our old good oscilloscope

Next we put the MAX2332 microscheme where it belongs to, and even placed the standard DB-9 connecter to simplify things a bit.

UART attached

Now the switch board looked like a real ARM development board. I even put a reset button on it:-) However, this didn't helped much. The console attached showed:

uart init successful
flash init successful
Get my mac[0-13-46-36-39-da]

image verify failed, loader mode

Not very informative. In this mode, the console didn't answered any keys, even echo didn't worked. Funny enough, there was one active TCP port on the switches management IP address — port 80, that acted like an echo server. Definitely, something bad happened to firmware.

Fortunately, there was yet one nice connector on the board — JTAG. JTAG stands for Joint Test Action Group, and presents IEEE 1149.1 standard for testing integrated circuits with boundary scans. Nowaday, most SoC manufacturers, implement comprehencive in-circuit debug solutions using JTAG as a serial interface to the chip. In particular, ARM 9 core uses standartized JTAG-based protocol, that allows developer to submit and execute any command on CPU, set breakpoints, and so on. It's not too surprising, that this allows you to do whatever you want with target platform, including reflashing. All you need is to configure a memory controller to map flash properly and implement a program that will run on target hardware and reflash the memory.

In fact, there're a lot of excellent JTAG software available, OpenOCD being among of them. This excellent piece of software can make you feel like debugging a locally runned program while communicating with an embedded processor via JTAG. Using it GDB-server interface you can easily connect your GDB instance to it, and fully control the board. Besides that, it also provide a custom telnet interface, where you can perform a lot of high-level debugging tasks like examining the target memory, modifing it, viewing registers and so on. It also provide interface through which the flash modules can be programmed, and it's easily extensible. It took nothing more than a hour for me to understand the OpenOCD code structure, and perform all required modifications to support D-Link configuration. The switch developers employed AMD AM29LV800 flash chip as it's media — it's a pretty standard chip, so only the identity of the memory and a couple of knobs has to be added to OpenOCD code to support it.

Having nothing else to do, I decided to reflash the switch with recent image available from D-Link. From the processor state it was clear they mapped the flash to 0x80000000 with bootloader occuping the address space up to 0x80030000, and the OS image put just after that address. What's suspicious — D-Link guys configured all eight banks, though only three were really used. Furthermore, all banks were configured in the way as they provide 16MiB of memory each, though it was not true (e.g. flash is only 1 MiB). Have they ever thinked about folks who had to reverse engineer their software in future?;-)

Luckily enough, the switch started working after the reflashing. It happily blinked with all its LEDs, clearly showing how it's happy to be healthy again, displaying on console:

 uart init successful
 flash init successful
 Get my mac[0-13-46-36-39-da]
image verify successful, jump to 0x80030000
cpu init finished 
system init successful 

 flash alloc[222bb8]


web server running... [5307]

Not sure which OS it runs, probably VxWorks or RTEMS. My first assumptions were it'll be some flavour of Linux, but things don't look like this. Probably, some information might be extracted from the image intself, but I didn't looked into this yet. I noticed, however, that the image consists of small unpacker and compressed code. So it has to be unpacked before anything could be analyzed further.

Unfortunately, the chip can't run FreeBSD, or any other BSD as it got no MMU. Thus my dreams about 48-port BGP router have no chances to come true:-(

Anyway, now you know what to do if your switch or router will broke out. Don't pay D-Link extra money for missed functionality — just fix the device yourself. It's easy enough.

5 Responses to “Hacking the D-Link DGS-1248T switch”

  1. Andrei Kovacs Says:

    Nice article. It will sure come handy if one of our 2 Dlink 1248T will someday fail :)

    Maybe you have a solution for another problem I've found on these switches even after flashing with the latest version: from time to time (random) they stop answering to IP (no management can be done, HTTP or SNMP). Do you have any ideea or solution for it ?

    Thanks

  2. stas Says:

    Sorry, but can't help with that. The only thing I can say - I had exactly the same problem before it died at all. Not sure if my reflashing fixed that - I haven't loaded it fully yet.

  3. Tyristor Says:

    Could you put up a picture of where you found the JTAG connector?, and maybe a short story of how you found it.

    Thoe one thing makes me really wonder. Howcome the flash failed in the first place ..?, esp considering they are supposed to manage 100000 writes before trouble occours. Just consider these new SSD equipped "laptops".

    Why does the word "timebomb" popup in my head? :-)

  4. AlexM Says:

    Your blog is interesting!

    Keep up the good work!

  5. Stanislav Sedov Says:

    There wasn't very hard to find a JTAG connector as it was the standard 20-pin header already soldered on the board. There're was no need to trace the processor pins even, it worked out of the box.

    What's about the flash failure - it's not clear to me too why this happened. Given the fact it doesn't need to write anything to flash during the normal operation...

Leave a Reply