It was lying in storage for quite a long time. I got it primarily because it's the same series as the WRT54GL, my favourite router. It was quite cheap. ADSL gateway was no use to me, as I dont have any ADSL drop, but I felt I could play with it.
It uses a Samsung S3C2510, which is arm940t based CPU. Wireless is done by a PCMCIA adapter (not in the picture). There's a standard 2x10 ARM JTAG header (CN2) and a UART (CN9). There is a 2M flash connected to the CPU over CFI, and that's what we're after. However, it's very tricky to get the flash contents...
OpenOCD doesn't support the arm940t family but it seems that treating it as arm920t works well enough for my application.
I used a BusPirate as a JTAG adapter, for which it's pretty darn good. My OpenOCD config was split between two .cfg files: one for setting up the BusPirate and one for the CPU.
BusPirate config is as follows:
source [find interface/buspirate.cfg] buspirate_vreg 0 buspirate_mode open-drain buspirate_pullup 1 buspirate_port /dev/ttyUSB0 #buspirate_speed normal buspirate_speed fast buspirate_mode open-drain reset_config srst_onlybpjtag.cfg
And the CPU config file, as found online with a little modification is as shown:
if { [info exists CHIPNAME] } { set _CHIPNAME $CHIPNAME } else { set _CHIPNAME s3c2510a } if { [info exists ENDIAN] } { set _ENDIAN $ENDIAN } else { set _ENDIAN little } if { [info exists CPUTAPID] } { set _CPUTAPID $CPUTAPID } else { set _CPUTAPID 0x1094009d } jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x01 -irmask 0x03 -expected-id $_CPUTAPID set _TARGETNAME $_CHIPNAME.cpu # target create $_TARGETNAME arm9tdmi -endian $_ENDIAN -chain-position $_TARGETNAME -variant arm940t target create $_TARGETNAME arm920t -endian $_ENDIAN -chain-position $_TARGETNAME $_TARGETNAME configure -work-area-phys 0x40000000 -work-area-size 0x4000 -work-area-backup 0 flash bank $_CHIPNAME.extnorflash cfi 0x00000000 0x00200000 2 2 $_TARGETNAME s3c2510a.cpu arm7_9 dcc_downloads enablesamsung.cfg
I had to set proper flash size (after being warned by flash probe 0). I also enabled DCC downloads - thats the first important thing! (not related to IRC DCC)
Both CN2 and CN8 were unpopulated. I had to solder the pins myself
As for the UART connection, there's a console port at 115200 8n1 baud. Pinout below, (pin 1 marked on silkscreen with the arrow):
__ \/ __ |1 |3v3 |2 |TxD |3 |RxD |4 |??? |5 |GND |6 |GND --
The JTAG connections are as follows:
MOSI -> TDI [ 5] MISO -> TDO [ 13] CLK -> TCLK [ 9] CS -> TMS [ 7] AUX -> RESET [ 15] VPU -> VCC [ 2] GND -> GND [any]
The console plays a crucial part in the flash dumping operation - we need it to disable the watchdog timer. Why? Because of the way it works, and the way OpenOCD dumps flash.
A WDT, short for watchdog timer, is a peripheral of modern CPUs that is designed to prevent lockups. It's implemented as a timer that runs in the background. In a typical situation the main application periodically notifies the WDT, either by clearing a bit in a register, or some other way, that it's running. If it fails to do so in a predefined amount of time, the WDT kicks in and resets the CPU.
In order to extract the flash image, OpenOCD uploads and executes a small flash transfer program to the target. Now if you leave the WDT (watchdog) runing, it will keep resetting the CPU - as the transfer program isn't periodically notifying the WDT that, it's in fact, not frozen.
Luckily the console allows us to disable the WDT
CON>wdt Watch Dog off CON>
openocd -f buspirate.cfg -f samsung.cfgand telnet 127.0.0.1 4444 in another terminal. For some reason the router fails to boot up if OpenOCD is running. Make sure DCC transfers are enabled.
$ telnet localhost 4444 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. Open On-Chip Debugger > halt target halted in ARM state due to debug-request, current mode: User cpsr: 0x80000010 pc: 0x0000cd68 MMU: disabled, D-Cache: enabled, I-Cache: disabled > targets TargetName Type Endian TapName State -- ------------------ ---------- ------ ------------------ ------------ 0* s3c2510a.cpu arm920t little s3c2510a.cpu halted
> dump_image linksys.bin 0x00000000 0x00200000
Enjoy. You might want to run strings against the binary to verify it's correct. Besides that, the CPU is pretty much useless. It's an old ARM (ARMv4), no MMU (just some rudimentary 8 segment protection circuitry). Analyzing the binary with binwalk didnt even yield any filesystems embedded inside. There is no operating system running on the router. The image has bits of HTML scattered throughout. The copyright string dates the software to 2001.
_--____________________________________ | || | |'-'| | | | | | '-' | | | | | | |____________| '---' | | _____________ ___ | | _ |_____________| | | | | / \ ___ '---' | | \_/ | | || || | || ::: '---' |'_'| | || _____ | | #: | | ______ o * | | #: | | _ | | []| | #: |_____|| | | | * *| | #: | | | | ___ | | #: '-' '______' | | | |# _ _ _ o '---' | |# / \/ \/ \ <> | |# \_/\_/\_/ | \__o__o_o_o_o__o__o___________________/
I made an asciiart of the board. Isn't it cool?
Serial bootlog (until the CON> prompt)
------- START AP --- IMG = 41AL HW = V1.1---- ADSL:download init code write jump command with address=0x8000000 got ACT:Init code OK ADSL:download init code OK ADSL:download runtime code write jump command with address=0x0 got ACT:Modem code OK ADSL:download showtime code OK utopia para(Level:1,AddrFast:1,AddrInterl:1)-- ok function code(0xa1)-- ok vendorID([0][49][54][43]) ok SW Feature Code(0x12)-- ok write Tx Gain Offset(0x0)--ok Target Noise Margin Offset(0xff)--ok Max Bits/Tone Limit(0xe)--ok Rx Gain Offset(0x0)--ok TX_Boost(0x0)--ok write open command(0x3)--ok open command ok ------- START watchdog timer---- ST version is 02(HEX) NV offset at 44891
I also found an unpopulated USB socket. Maybe it's used in another model?
I am not bound by any subscriber agreement regarding this ADSL gatewayLast update: 2024-11-03