SMC7004ABR Flash Reverse Engineering

Flash Memory map:

Area Start Address Final Address Size Link
Boot/Simple Monitor 0x0000.0000 0x0001.FFFF 128K BOOT
Configuration 0x0002.0000 0x0002.FFFF 64K CONF
Called gconf and gsettings in the debug menus of the main firmware
Web Image 0x0003.0000 0x0005.FFFF 192K FileSystem
Code Image 0x0006.0000 0x000E.FFFF 576K CODE
Params Area 0x000F.0000 0x000F.FFFF 64K PARAM
(serial #, ethernet mac, board version and other details, mostly unused)

The flash is at 0x0000.0000 and is (uncached) mirrored at 0x0400.000. The firmware always talks to the flash at the 0x0400.000 address.
Also, there seems to be gate to prevent flash writes, connected to GPIO2 - it needs to be LOW for the flash writes to be effective.

Rescue mini-firmware (area 1) able to download main firmware using web through the Ethernet port; the structure of the bootloader and the commands and texts are identical to those in the CX84200 based SMC7004VWBR box analyzed elsewhere on the HRI pages. The bootloader mentions Actiontec Electronics, Inc.

The 8MB ram lives at 0x0100.0000. There is no remapping of RAM to 0 as done on the CX84200, the exception vectors are vectored by the bootloader through the initial area in RAM (addresses 0x0100.0000 through 0x0100.001F contain pointers to routines to jump to) - this is why the actual code starts at 0x0100.0050 and not at the start of RAM.

For those curious, the main firmware actually seems to run in USER mode of the ARM processor, the bootloader switches to USER and I have not found any switch back. Privileged operations such as disabling interrupts are done using SWI 0x100. In the bootloader, SWI 0xFF switches to supervisor mode (this is a NOOP in the main firmware). However, the main firmware loads the stack pointers for all the modes, which would not work in the USER mode, so I might be wrong with this.

If your firmware wants to get to Supervisor, it needs to install a SWI vector with the same code as the bootloader SWI 0xFF or to use other exception vector to get out of the USER mode.

Flash Format

The format of the flash areas is the following:

The web and firmware areas are zipped (PKZIP, Infozip etc), 1 file per archive. The other areas are raw data. At the end of each flash area, there is a checksum and signature - in the last 3 dwords in little endian.

The first (at x.FFF4) contains the size of the valid data (this is the size of the zip file, for instance), the next dword is a signature of 0x12345678 and the last dword is the CRC32 of the valid bytes (that is of the whole compressed archive in case of ZIP file, not the content of the ZIPped data).

The CRC32 is identical to that used by ZIP and can be extracted from gzip/gunzip or infozip sources (they are not copyrighted). The bytes between the end of the used area and the last 3 dwords are all 0xFF.

The firmware download file (xxxx.bin) is constructed as follows:

You will get a file with 794624 (decimal) bytes, which the router is happy to install and run. I have written a small utility to make a firmware image from 2 ZIP files, stuffing the 0xFFs and computing the CRC32 sums and the other small details.

The rescue firmware and web disk are in the flash at 0x8000..0x1e7ff (builtin SOHO.BIN) and 0x1E800..0x1fbff (builtin PFS.IMG). These are again ZIP files, but without the CRC32, len etc and are 00 filled to the end of the area, not 0xFF. The BRNABR\0\0\0\0 followed by all 0xFF is at 0x1.FC00 and there is no checksum or any other dword at the very end of the bootloader.

Booting Sequence

Linux boot sequence: booting1 booting2



BootLoader decoding

Encoding: little (???)

Execution sequence:

- Boot loader code copied from 0x800 to 0x13f.0000 and run from there
- unzip area 3 to 0x174.0000
- unzip area 4 to 0x100.0050
- goto 0x100.0050 (?)

Update 04/Jan/04: Linux running at RAM 0x000.1000 and flash at 0x0100.0000


$Id: flash_mem.html,v 1.2 2004/02/19 20:57:28 bcabral Exp $