You are not a member of this wiki. Join now  Dismiss


ADAM2 - The bootloader


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, NetgearDG834G, LinksysWAG54Gv2.

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 (standart 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.66

My 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/%7Esibbe/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 0x00

The 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 [[http://www.mips.com/content/Products/SoftwareTools/content_html/yamon 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 CHECKSUM

Record #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


You can find more in the firmware page.

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/%7Eenrik/fbox/util/recover (perl script) or http://web.archive.org/web/20041120225126/http://www.akk.org/%7Eenrik/fbox/recover (perl script)
http://www.akk.org/%7Eenrik/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 Busybox's TFTP command.

Links




-- This page was initially copied from http://seattlewireless.net/?ADAM2 --