Contents
ADAM2
ADAM2 (Avalanche Device Application Manager?) is a simple bootloader/monitor for the Texas Instrument AR7 System-on-Chip. ADAM2 is used in the following devices: ActiontecGT701, ActiontecGT704, DlinkDslG604t, DlinkDslG624t, NetgearDG834G, LinksysWAG54Gv2, Asmax AR-804gu.
ADAM2 Revision 0.22.02 (C) Copyright 1996-2003 Texas Instruments Inc. All Rights Reserved. (C) Copyright 2003 Telogy Networks, Inc.
ADAM2 contains support for the TI AR7 (16c550 compatible) serial console, TI Ethernet driver (cpmac), TCP/IP, DHCP client, FTP server and FLASH memory writer/eraser.
ADAM2 resides in the mtd2 FLASH partition (0x90000000 virtual KSEG0 == 0x10000000 physical addresses).
Texas Instrument AR7 chip has a tiny (4K) boot-ROM embedded at the 0xBFC00000 (standard MIPS 4KEc reset vector). This code initializes external memory interface (EMIF) and jumps to the 0x90000000 (ADAM2 start).
ADAM2 Serial commands
Commands Description
-------- -----------
h/help commands supported
info Displays board information
memop Memory Optimization
setmfreq configures/dumps the system and cpu frequencies
dm Dump memory at <address>
setmac Change memory at <address> <value>
erase Erase Flash except Adam2 Kernel and Env space
printenv Displays Env. Variables
setenv Sets Env. variable <var> with a value <val>
unsetenv Unsets the Env. variable <var>
fixenv Defragment for Env. space
go Loads the image starting at address <mtd1>Several commands may be separated by ";" i.e. "printenv;info" .
The dm <start> <stop> command allows you to examine various memory regions :
Adam2_AR7RD > dm 0xbfc00000 bfc00000: 10000004 00000000 00000000 00000000 - ................ bfc00010: 0c081000 3c1aa861 375a1a00 8f5a0000 - ....a..<..Z7..Z. bfc00020: 335a0007 24010001 13410013 00000000 - ..Z3...$..A..... bfc00030: 24010002 13410013 00000000 24010003 - ...$..A........$ bfc00040: 1341001a 00000000 24010004 1341001a - ..A........$..A. bfc00050: 00000000 24010005 13410021 00000000 - .......$!.A..... bfc00060: 24010006 1341001e 00000000 24010007 - ...$..A........$ bfc00070: 13410017 00000000 3c1ab000 03400008 - ..A........<..@.
dumps a standard MIPS 4KEc reset code (internal CPU EEPROM).
ADAM2 DHCP
If "dhcp" variable is true, ADAM2 acts as DHCP client on the Eth0 interface.
DHCP options supported:
subnet, timezone, router, timesvr, namesvr, dns, logsvr, cookiesvr, lprsvr, hostname, bootsize, domain, swapsvr, rootpath, ipttl, mtu, broadcast, ntpsrv, wins, requestip, lease, dhcp
ADAM2 FTP access
While booting up the device it waits for a few seconds for incoming FTP connection. The listening IP-address is stored in "my_ipaddress" environment variable.
# strings mtd3.img | awk '/my_ipaddress/ {getline; print;}'
10.8.8.8
10.48.88.66My box seems to have it stored twice. In this case, the latter one will be the one to connect to. Login with adam2/adam2 (hardcoded to all ADAM2 -based devices). The ADAM2 ftp commands and some more info can be found at http://www.nettwerked.net/actiontec.html
Recovery application can initiate such FTP session while ADAM2 in work (usually 5 seconds after ddevice reboot) by sending a special broadcast packet to port 5035. The box goes reboot and waits for incoming FTP connection on assigned IP address.
TODO:(Which Linux process is listening to this port ? cm_ ? lsof required). Here's the output of netstat -lp: http://www.hack.fi/~sibbe/dsl/netstat.txt
UDP broadcast port 5035: (16 bytes)
0x00 0x00 0x16 0x02 0x01 0x00 0x00 0x00
0xc0 0xa8 0x00 0x01 0x00 0x00 0x00 0x00
UDP response from modem to port 5035: (16 bytes)
0x00 0x00 0x16 0x02 0x02 0x00 0x00 0x00
0x01 0x00 0xa8 0xc0 0x00 0x00 0x00 0x00The 0xc0 0xa8 0x00 0x01 is an assigned IP address: 192.168.0.1 for recovery FTP session.
ADAM2 FTP commands
REBOOT UNSETENV SETENV GETENV MEDIA RETR TYPE STOR P@SW PASV SYST PASS USER PORT QUIT ABOR
It's impossible to execute all of this FTP commands from some weird FTP client (i.e. Windows). Try to telnet to port 21! All commands must be in Uppercase.
$ telnet 10.48.88.66 21 220 ADAM2 FTP Server ready. 530 Please login with USER and PASS. USER adam2 331 Password required for adam2. PASS adam2 230 User adam2 successfully logged in. ls 502 Command not implemented - Try HELP. HELP 502 Command not implemented - Try HELP. SYST 215 UNIX emulated bye ADAM2's FTP Server. GETENV 501 environment variable not set. GETENV * 501 * environment variable not set. GETENV autoload autoload 1 GETENV my_ipaddress 200 GETENV command successful my_ipaddress 10.48.88.66 200 GETENV command successful QUIT 221-Thank you for using the FTP service on ADAM2. 221 Goodbye. $
There are two special "virtual" filenames: env and config.xml for storing/retrieving an ADAM2's variables and /etc/config.xml content.
... 230 User adam2 successfully logged in. ftp> get env 200 Port command successful. 150 Opening ASCII mode data connection for file transfer. 226 Transfer complete. ftp: 1034 bytes received in 0,05seconds 22,00Kbyte/sec)
For sending ADAM2 specific commands you have to use "quote COMMAND" (command should be UPPERCASE).
... ftp> quote GETENV my_ipaddress my_ipaddress 10.48.88.66
It is ofcourse possible to flash a filesystem or a kernel image through FTP access.
... ftp> quote MEDIA FLSH 200 Media set to FLSH. ftp> bin 200 Type set to I. ftp> put fs.bin "fs mtd0" 226 Transfer complete. 2015240 bytes sent in 00:27 (72.45 KB/s) ftp> quote REBOOT 221-Thank you for using the FTP service on ADAM2. 221 Goodbye.
The put command needs that funny parameter fs.bin - file, fs - any sequence of character, mtd0 - place to wich ADAM2 must store image. Exception mtd3 - ADAM2 store files with offset, see note below. Also the connection might hang for a while before the transfer starts (while the partiton is erased, progress is availible on serial console) - just be patient. This should work with kernel images too, just use mtd1 instead of mtd0.
It is possible to download and run an "ADAM2 application" even without storing it in the Flash. To do it, change mode to MEDIA SDRAM and STOR-e a binary image. The image should be in the ADAM2 "go" command format like mtd1 (described below).
ADAM2_dump archive contains an example.
ADAM2 Environment Variables
ADAM2 maintains a set of Environment Variables in a so-called Non Volatile RAM, emulated by the last FLASH partition mtd3. This partition is split in two : the firsh 10kB contain the ADAM2 environment variables, whereas the last 54kB store a XML file detailing the global configuration of Montavista Linux as it was saved by the user.
The Linux /proc/ticfg/env file is a "cooked" interface to the ADAM2 environment variables.
Editing the Environment Variables
There are four ways to read and edit the persistent environment variables used by ADAM2 :
1. Use a serial console and the ADAM2 prompt commands setenv, unsetenv, printenv
2. Use the onboard FTP server's commands SETENV, UNSETENV, GETENV (all caps matter)
3. Use the Linux file /proc/ticfg/env:
# cat /proc/ticfg/env memsize 0x01000000 flashsize 0x00400000 modetty0 38400,n,8,1,hw modetty1 38400,n,8,1,hw bootserport tty0 cpufrequency 150000000 sysfrequency 125000000 bootloaderVersion 0.22.02 ProductID AR7WRD HWRevision Unknown SerialNumber none my_ipaddress 10.48.88.66 maca 00:0F:3D:98:09:F3 usb_vid 0x0 usb_pid 0x0 usb_rndis_mac 00.0d.88.11.03.02 usb_board_mac 00.0d.88.22.03.02 usb_man N/A usb_prod N/A usb_serial 1234567890 prompt Adam2_AR7RD firstfreeaddress 0x9401d328 req_fullrate_freq 125000000 mtd0 0x900a0000,0x903f0000 mtd1 0x90010000,0x900a0000 mtd2 0x90000000,0x90010000 mtd3 0x903f0000,0x90400000 autoload 1 mac_ap 00:0F:3D:98:09:F4 # echo usb_prod Test > /proc/ticfg/env # cat /proc/ticfg/env | grep usb_prod usb_prod Test
4. Edit the first 10kB of the mtd3 mtdblock file with an external hex editor and write it back to /dev/mtd.
WARNING : a corrupt mtd3 may place ADAM2 in a deadlocked state, thus making your device permanently inoperative. Editing mtd3 by hand is NOT recommended.
NVRAM format
Disclaimer : The following information was gained by reverse-engineering the NVRAM memory space storage format. As such, it is not authoritative and is currently incomplete.
ADAM2's environment variables are stored in the first 10kB of mtd3, hence from byte 0x0000 through byte 0x27FF (adresses relative to mtd3).
The "NVRAM" memory space is divided in records.
- A record is 128 bytes long
- There are 80 records in NVRAM
- A record is always padded with 0xFF
- The first record starts on byte 0x0000
There are two kinds of records : records that store an environment variable and empty records. Empty records are simply filled with 0xFF. Records that store an environment variable use the following format :
Offset |
Value |
Comment |
0x00 |
0x42 |
Capital 'B' or possible Douglas Adams reference |
0x01 |
Checksum byte |
The least significant byte of the sum of all data bytes |
0x02 |
Record index |
Index of the record, starting at 0x00 |
0x03 |
Data length |
Length of the record's data, including the 0x00 bytes |
0x04 |
Data |
variable name+0x00+variable value+0x00 |
Example:
0x0100 42 9B 02 18 6D 6F 64 65 74 74 79 30 00 33 38 34 0x0110 30 30 2C 6E 2C 38 2C 31 2C 68 77 00 FF FF FF FF 0x0120 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 0x0130 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 0x0140 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 0x0150 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 0x0160 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 0x0170 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 0x0180 42 9C 03 18 6D 6F 64 65 74 74 79 31 00 33 38 34 0x0190 30 30 2C 6E 2C 38 2C 31 2C 68 77 00 FF FF FF FF
FIXME : The behaviour of the fixenv command in ADAM2 prompt needs to be adressed here. fixenv rebuilds env space and delete unusable slots.
FIXME : Records may not always be contiguous.
ADAM2 API
ADAM2 provides two APIs for standalone applications, like OS second stage bootloaders or decompressor.
The first API emulates a MIPS YAMON bootloader. It formed as a "call vector" table, started at the address 0x90000500 (not 0xBFC00500):
#define YAMON_FUNCTION_BASE 0x90000500 /* YAMON Vector table offsets */ #define YAMON_FUNC_PRINT_COUNT_OFS 0x04 #define YAMON_FUNC_EXIT_OFS 0x20 #define YAMON_FUNC_FLUSH_CACHE_OFS 0x2C #define YAMON_FUNC_PRINT_OFS 0x34 #define YAMON_FUNC_REGISTER_CPU_ISR_OFS 0x38 #define YAMON_FUNC_DEREGISTER_CPU_ISR_OFS 0x3c #define YAMON_FUNC_REGISTER_IC_ISR_OFS 0x40 #define YAMON_FUNC_DEREGISTER_IC_ISR_OFS 0x44 #define YAMON_FUNC_REGISTER_ESR_OFS 0x48 #define YAMON_FUNC_DEREGISTER_ESR_OFS 0x4c #define YAMON_FUNC_GETCHAR_OFS 0x50 #define YAMON_FUNC_SYSCON_READ_OFS 0x54
Only 3 YAMON calls are supported (PRINT_COUNT, PRINT, EXIT). Unfortunately, GETCHAR does not work.
The second API is an own ADAM2 API. Gateway address is 0x90000480.
ADAM2 Applications
ADAM2 can load and execute MIPS LE applications in specific binary format. One of this application is a Linux Kernel, stored in the mtd1 FLASH partition.
There is a format ot the "ADAM2 application" and mtd1 content, as required by ADAM2's "go" command.
Record #1 Offset:
----------
0x00000000 SIGNATURE: .word 0xfeedfa42 ; NL! ADAM2 MIPS LE signature
0x00000004 LENGTH1: .word xxxx ; NL! Record #1 Length
0x00000008 ADDRESS1: .word 0x94192000 ; NL! RAM Address to load Record #1
.code
0x0000000c app: nop ; The first loaded instruction
; (will be loaded at ADDRESS)
...
0x0001000x _main: addiu sp, -0x5c0 ; Application entry point
...
0x0001000x j ra
addui sp, 0x5c0
.end
0x0002xxxx CHECKSUM1: .word xxxx ; NL! Record #1 CHECKSUMRecord #2 Offset ---------- 0x0002xxxx LENGTH2: .word 0 ; NL! Record #2 length (==0x0) 0x0002xxxx ADDRESS2: .word _main ; NL! Application entry point 0x0002xxxx CHECKSUM2: .word 0x6be6xxxx ; NL! Record #2 CHECKSUM
NL! -- Not Loaded
There is tiny ADAM2_dump utility to dump an "application" information. If you have a full firmware image you should disassemble it before using adam2_dump.
$ ./adam2_dump DLinkUK_DSL-G604T_kernel_V1.00B02T02.UK.20040618
ADAM2 application Header:
ADAM2 Magic= 0xfeedfa42 - GOOD!
ADAM2 application Record #1 Header:
LENGTH = 0x0006cd8f (445839)
ADDRESS = 0x94198000
.......... DATA
CHECKSUM = 0x688e3589
ADAM2 application Record #2 Header:
LENGTH = 0x00000000
ADDRSESS = 0x94198000 (entry point)
CHECKSUM = 0x6be68000
Compressed kernel image found!
Offset = 0x4b60 (19296), Length = 0x6823b (426555)
LZMA z7 compressed image.
File is signed by TI_chksum.The ADAM2_app contains an ADAM2 MIPS sample application (without decompressor, ofcource). You need a MIPS toolchain installed to build it.
ADAM2 sourcecode
ADAM2 sourcecode is available as part of the Linksys GPL tarball. All sourcecode copyrigted by Telogy Inc., and seems, Linksys have put this there due to error.
Direct link to Linksys FTP
Linux firmware
Linux firwmare consists of 3 parts: Linux kernel + FS image + Config data
There is Windows firmware recovery/update ulility, wich disassemles a whole firmware and stores in in the mtd partitions.
FLASH layout (sorted by mtdN number):
mtd0 - CRAMFS image (for root filesystem) mtd1 - Linux kernel (in ADAM2 application format) mtd2 - ADAM2 mtd3 - Environment variables and Linux XML configuration data
It is possible to "repartition" a FLASH, just change an ADAM2 variables:
mtd0 0x900a0000,0x903f0000 mtd1 0x90010000,0x900a0000 mtd2 0x90000000,0x90010000 mtd3 0x903f0000,0x90400000
Note, the partitions goes not in order. The mtd2 partition (64Kb) is an ADAM2 code and must be at address 0x90000000! The mtd3 is a NVRAM space and occupies latest 64Kb of FLASH. Linux kernel MTD driver will find all partitions automatically.
Linux kernel Boot sequence
ADAM2 executes "go" command automatically to run a mtd1 content if there is no activity on the Serial console, "autoload" is true and "autoload_timeout" exceeded. Usually, the mtd1 (0x90010000) contains a compressed Linux kernel image.
ADAM2's "go" command moves mtd1 content to the RAM ADDRESS1 and runs it. This piece of code (zlib/LZMA piggyback) decompresses Linux kernel to the RAM addess 0x94020000 and runs it there. Decompressor uses ADAM2 "call vector" API to print a string on successful decompression.
The /proc/iomem contains a physical addresses. To get a virtual kernel KSEG0 addresses, add 0x80000000.
# cat /proc/iomem 00000000-13ffffff : reserved 14000000-1401ffff : System RAM 14020000-14ffffff : System RAM 14020000-14169fdf : Kernel code 14176300-14191fff : Kernel data a8612800-a8612fff : eth0 #
Live Linux Kernel symbols (sorted) :
# cat/proc/ksyms ... 94024000 invalid_pte_table_Re30a91e5 94026000 init_task_union_R56b55918 94028a00 kernel_thread_R7e9ebb05 94028a68 get_wchan_R182e7552 9402c5a0 machine_restart_Re6e3ef70 9402c5c4 machine_halt_R9aa32630 9402c5e8 machine_power_off_R091c824a ...
Recovery app
Enrik Berkhan have built a perl program "recover" that mimics "recover.exe" for non-Windows users. It works for the AVM Fritz!Box device. The modification for the D-Link DSL-G604T should be trivial...
http://www.akk.org/~enrik/fbox/util/recover (perl script)
[Alternate link] http://web.archive.org/web/20041120225126/http://www.akk.org/~enrik/fbox/recover (perl script)
http://www.akk.org/~enrik/fbox/recovery.txt (German Language)
Linux config
The /dev/ticfg is a "raw" interface to the second half of the mtd3, where the /etc/config.xml stored:
# cat /dev/ticfg
The first two bytes seems a data length.
The entirely mtd3 (/dev/mtdblock/3) contains a "raw" data of the ADAM2 envoronment and the config.xml data.
Retreiving MTD content
How to get a content of the any MTDs on running Linux:
As it is known, the /var is mounted on the Ramdisk. The idea is to copy a bulk MTD content to the /var and run a second copy of the thttp server to get it.
# cat /dev/mtdblock/2 > /var/mtd2.bin # cat /dev/mtdblock/3 > /var/mtd3.bin # /usr/sbin/thttpd -g -d /var -u root -p 1080
Then, open a following URL in any browser: "http://192.168.1.1:1080/" and get a mtd2.bin (ADAM2 code) and mtd3.bin (device configuration) files from this folder.
It is possible, of course, to use Bysybox's TFTP command.
Other
DSL-302T demystified hacking (Italian language)
ActiontecGT701 uses ADAM2
Linksys WAG54G v2 uses ADAM2
NetgearDG834G uses ADAM2
Solwise ADSL-SAR-600E, http://www.linux-mips.org/wiki/SAR600E uses ADAM2
Sitecom WL-108 uses ADAM2
AVM Fritz!Box is based on the same TI AR7 chip (German language)
http://www.akk.org/~enrik/fbox/ A lot of tools for Fritz!Box hacking. Read "NEWS" file!
Linux-Mips.Org http://www.linux-mips.org/wiki/index.php/DSL-xxxT
Texas Instrument AR7 ADSL Router
OpenWRT AR7 Port project


