home  wiki

Spelling: MinitarHacking



* Code Organization [1]
* ROM size and building the image [2]
* Embedded ramdisk [3]
* Bootloader [4]
* Memory map [5]
* Building the embedded ramdisk [6]
* Console login [7]
* Flash Variables [8]
* Builtin tftp [9]
* What is on this box? [10]
* Things that are prebuilt [11]
* Web pages [12]
* Firmware decomposition [13]

* Header structure [14]
* ROM partitions [15]
* Boot sequence (main.c ) [16]
* Backing up settings [17]
* Version 2.32 [18]
* Version 2.34 [19]
* Version 2.39 [20]
* Version 2.49 [21]
* Version 2.53 [22]
* Web download of image [23]
* Building the initrd image [24]

* What to add to this unit? [25]

* Useable [26]
* Useful [27]

* Software Modifications [28]

* Boot_wait [29]
* Route not Bridge [30]
* System access [31]
* Monitoring [32]
* Traffic management [33]
* Routing [34]
* Reality Check [35]

CODE ORGANIZATION

-------------------------

The source code released seems to be either "cleaned" or it is from
an early stage in the development of the device. I suspect it has been
cleaned, there are some obvious things that should be there such as
Makefiles in the Linux and AP directories as well as some packages and
files that you would expect to be there to make a working image. Check
out college essay [36] for more information.

The release has three parts:

* AP - application code running on the AP
* LINUX - kernal code
* boot - seperate archive containing the boot loader

As well as the code there is the build environment. This is a third
archive that has instructions to load it into /usr/local ( yeah right
- not this little black duck).
Looking through the build stuff it seems a bit of a mess. They have
zipped up the entire /usr/local from the build machine. Some
interesting things in there - looks like the thought about using eCos
at some stage as there is a directory fo it there. eCos is an Redhat
offering for embedded systems.

ROM SIZE AND BUILDING THE IMAGE

-------------------------
So, initally I though there was a limit on the image being 1MB when
compressed (well a little smaller, 1MB less the 0x0000-0x10000 (64 KB)
that is reserved for the boot code). I found when making an image that
some of the files were zero size, turns out that the embedded
filesystem that is built in the AP code tree needs to be big enough to
fit it all in.

The ROM image is a bit under 1MB when packed for flashing. As the
Flash on my unit is 2MB, it is probably safe to make a biger image and
load it on. I suspect that the initial units had a 1Mbyte flash and so
they are trying to keep the image within that size.

Need to build a test for the size of the image to make sure we
allocate enough blocks

EMBEDDED RAMDISK

-------------------------
The kernel has an embedded ramdisk that contains all the application
code. When the kernel is built the ramdisk is packed into the kernel
and is uncompressed and copied to ram as the kernel loads.

Usually a ramdisk like this is used for getting the system up and
initializing the disk subsystem etc. Once the normal filesystem is
loaded then the root is mounted at the appropriate place. In this
case, this is the only file system that is created and loaded.
The script that builds it and loads in the applications (mkimg) calls
appimg with an option -b that is labeled block-size, it is -b number
of blocks to make the image filesystem. appimg seems to be some sort
of munged binary that calls mk2fs then runs through the app_script
loading the files into the newly created and mounted filesystem
(mounted over /mnt). After the filesystem is created t is unmounted
and zipped

You can change the size of the ramdisk by changing the number of
blocks. There is an upper limit of 4000 Blocks due to mkimg using the
ramfs device to make the filesystem. a better way is to use the
loopback device and you are not limited to this size.

If you are building a ramdisk make sure you mount it and check it is
not full before trying to use it as the mkimg binary won't complain if
the device is full, you end up with a lot of zero length files.

BOOTLOADER

-------------------------
The bootloader (well if they are really using the one made from the
source) is in the btcode directory. The boot code is built first in
the boot dir than a file boot.img is dumped into the btcode directory.
running make in btcode finishes building the bootloader.

The assembly code in Start.S is the first thing executed. Does a bit
of houskeeping then copies the boot code to RAM

after that it jumps to the boot code

la k0, 0x80000000 --> set the address to jump to jr k0 --> jump to
the start of the boot code nop

The boot image is tftp'd to the device and left in RAM, then you use
the FLW command to write it to ROM. FLW the dst is 000000 the src
will be 80500000 and the size what is reported by the tftp

Notice the unusual copy semantics here

The is the offset from the base of the ROM, not an absolute address.

MEMORY MAP

-------------------------

ROM base is at 0x2bf0000 (or is it 0x00ff0000)

Found 1 x 2M Byte MXIC MX29LV160AB at 0xbe000000

There is 2MB ROM 0x000000 -> 0x200000

+-----------------------------+ | 2| 0| 0| 0| 0| 0| Digit counting
for hex challenged |0000|0000|0000|0000|0000|0000| | |1M |64K |4K |256
|16 | +-----------------------------+

in the boot loader code there is some mention of partitions in the
rom - This is in the first 64K of space 0x00000 to 0x010000.

ROM is partitioned into 4 chunks:

from for 0x000000 -> 0x004000 ( 16K ) 0x004000 -> 0x002000 ( 8K ) +
8K unalloc 0x008000 -> 0x008000 ( 32K ) 0x010000 -> 0x010000 ( 64K )

This partition map ( as documented in the source) is wrong. The
bootloader is a little under 24 KB and is followed by the HS (Hardware
Settings), DS (Default Settings), CS (Current Settings) to make up the
first 64KB.

It's something like this:

from for 0x000000 -> 0x006000 ( 24K ) Bootloader 0x006000 ->
0x000400 ( 1K ) HS Hardware settings 0x006400 -> 0x001C00 ( 7K ) DS
Default settings 0x008000 -> 0x008000 ( 32K ) CS Current settings
0x010000 -> 0x010000 ( 64K ) Web pages (depricated in most firmware)
0x020000 -> Space for CSYS image(s)

The map is a little cramped, My custom bootloader is bigger than 24K
now so I chain to it from the default bootloader rather than overwrite
it. Ideally the the partition should be enlarged to 32K and the HS, DS
and CS partitions "slipped" a bit.

It's supposed to be DANGEROUS to flash from address 0x000000 - boot
loader space here.
The firmware image is supposed to be flashed from 0x020000, so it is
after the four partitions mentioned in the map above.

It looks like the tftp that is included in the release is modified so
when it is launched from the web admin page it performs the transfer,
a validation then flashes the image. It expects a full image (WEBS and
CSYS) and so would flash from 0x10000. This tftp is different to the
one launched by the board boot code, the boot tftp will upload an
image to 0x80500000 in RAM and not do anything else with it. It will
also download an image in response to a GET but only if a previous
upload has been performed (do a PUT of a filename of a certain size
and then do a GET filename and it knows the last uploaded size, so
will retrieve what is in RAM from 80500000 for the size number of
bytes: - you may be able to extract ROM contents by writing a dummy
file of the appropriate size, doing a FLR 80500000 00000 then the
tftp get)

RAM base is at 0x80000000

80000000--- boot loader ? On startup it is copied to here then the
code jumps to here

80100000---

80200000---

80500000--- current system upload load point. The image that is
uploaded will have a CSYS header that contains the load memory
address. When the image has been written to FLASH the boot code looks
for the CSYS headder in a number of locations then reads the image
load address (in my case it was 80350000) and the size of the image.

from the boot messages:
Memory: 4836k/8192k available (1320k kernal code, 3356k reserved,
1696k data, 44k init, 0k highmem)

BUILDING THE EMBEDDED RAMDISK

-------------------------
The ramdisk is built using mke2fs. There is a binary that is provided
in the
SDK for building it but it is kind of restrictive.

dd if=/dev/zero of=/dev/ram bs=1k count=$block_count mke2fs /dev/ram
$block_count mount -t ext2 /dev/ram /mnt sh $script_file umount
/dev/ram dd if=/dev/ram bs=1k count=$block_count of=$temp_file rename
$temp_file, $image_file gzip -9v -f $image_file rename
"$image_file.gz", $target_file

A perl script to do the same is at the Sourceforge Forum [37]

Building the filesystem encounters problems when trying to run mke2fs
with more than 4096 blocks. It complains about the size of the
underlying device name="console_login">

CONSOLE LOGIN

-------------------------
The console login was cracked on earlier versions:

2.32 user: super passwd: lance@edimax.com.tw

When the system boots busybox starts, normally there is direct access
to the console, and the login screen did not seem to be part of the
busybox application?
It comes from a binary /bin/setup.
Ok so how is it invoked? Also how is the "real" system setup called
from when the kernel finished loading?

Busybox init.c shows that normally init runs the runlevels as defined
in /etc/init.d but in the case where there is not an init.d that it
runs some default settings and starts a shell on the system console.
The hack is that in /etc/profile (should be .profile? rather than a
normal "shell" configuration the /etc/init.sh script is called.

profile runs init.sh starts the webserver and then runs setup. As it
is a script then it should be possible to either patch the firmware to
comment out the setup call or patch the image once it has been loaded
but before we jump to it.

Setup dosn't seem to use the FLASH variables for super login, the
password stored in FLASH in the DS and CS sections didn't work. SO the
setup binary is a prime candidate for disassembling to work out where
it gets it's password from. I suspect that after the last one was
cracked so easily they have stopped putting it in clear text, though
even if they use someting simple like crypt, then crypt needs to be on
the box.

A dump of the file flash.inc shows DS and CS settings for both the
super and admin users. Unfortunately the password there ( user: super
passwd: APR@xuniL ) did not work for the login but it did give me a
clue to how it was being done.

FLASH VARIABLES

-------------------------
When running 2.32 on a Unit that came installed with 2.39 I was
looking at a script called create_flash.sh. This script pulls out the
data stored in the HS DS and CS segments of the Flash memory and puts
them in a file /etc/flash.inc. Thsi file is not present in the
firmware, it is created on the fly as the system boots.

# cat flash.inc

HW_BOARD_ID=3 HW_NIC0_ADDR=0050fcd7089d HW_NIC1_ADDR=000000000000
HW_WLAN_ADDR=0050fcd7089d HW_REG_DOMAIN=3 HW_RF_TYPE=3
HW_TX_POWER=1,1,1,0,0,0,0,0,0,0,0,0,0,0 HW_ANT_DIVERSITY=0 HW_TX_ANT=0
HW_CS_THRESHOLD=11 HW_CCA_MODE=1 HW_PHY_TYPE=0 HW_WLAN_LED_TYPE=0
DEF_DHCP_CLIENT_START='192.168.2.100'
DEF_DHCP_CLIENT_END='192.168.2.200' DEF_RSER_ENABLED=0
DEF_RSER_CLT_TBL_NUM=0 DEF_RSER_USR_TBL_NUM=0
DEF_ELAN_MAC_ADDR=000000000000 DEF_WLAN_MAC_ADDR=000000000000
DEF_SSID='default' DEF_CHANNEL=11 DEF_WEP=0 DEF_WEP64_KEY1=0000000000
DEF_WEP64_KEY2=0000000000 DEF_WEP64_KEY3=0000000000
DEF_WEP64_KEY4=0000000000 DEF_WEP128_KEY1=00000000000000000000000000
DEF_WEP128_KEY2=00000000000000000000000000
DEF_WEP128_KEY3=00000000000000000000000000
DEF_WEP128_KEY4=00000000000000000000000000 DEF_WEP_DEFAULT_KEY=0
DEF_WEP_KEY_TYPE=1 DEF_FRAG_THRESHOLD=2346 DEF_SUPPORTED_RATES=15
DEF_BEACON_INTERVAL=100 DEF_PREAMBLE_TYPE=0 DEF_BASIC_RATES=3
DEF_RTS_THRESHOLD=2347 DEF_AUTH_TYPE=2 DEF_HIDDEN_SSID=0
DEF_WLAN_DISABLED=0 DEF_INACTIVITY_TIME=30000
DEF_RATE_ADAPTIVE_ENABLED=1 DEF_DTIM_PERIOD=127 DEF_WLAN_MODE=255
DEF_NETWORK_TYPE=255 DEF_IAPP_DISABLED=0 DEF_AP_MODE=0
DEF_AP_MODE_TEMP=0 DEF_SECURITY_MODE=0 DEF_CLIENT_IP_DISABLED=0
DEF_WL_LINKMAC1=000000000000 DEF_WL_LINKMAC2=000000000000
DEF_WL_LINKMAC3=000000000000 DEF_WL_LINKMAC4=000000000000
DEF_WL_LINKMAC5=000000000000 DEF_WL_LINKMAC6=000000000000
DEF_WLAN_ENCRYPT=255 DEF_WLAN_ENABLE_SUPP_NONWPA=3
DEF_WLAN_SUPP_NONWPA=0 DEF_WLAN_WPA_AUTH=0 DEF_WLAN_WPA_CIPHER_SUITE=0
DEF_WLAN_WPA_PSK='' DEF_WLAN_WPA_GROUP_REKEY_TIME=0
DEF_MAC_AUTH_ENABLED=0 DEF_RS_IP='0.1.81.128' DEF_RS_PORT=0
DEF_RS_PASSWORD='' DEF_RS_MAXRETRY=0 DEF_RS_INTERVAL_TIME=60
DEF_ACCOUNT_RS_ENABLED=0 DEF_ACCOUNT_RS_IP='0.0.0.0'
DEF_ACCOUNT_RS_PORT=0 DEF_ACCOUNT_RS_PASSWORD=''
DEF_ACCOUNT_RS_UPDATE_ENABLED=0 DEF_ACCOUNT_RS_UPDATE_DELAY=0
DEF_ACCOUNT_RS_MAXRETRY=0 DEF_ACCOUNT_RS_INTERVAL_TIME=768
DEF_WLAN_ENABLE_1X=0 DEF_WLAN_PSK_FORMAT=0 DEF_ALIAS_NAME='Wireless
AP' DEF_IP_ADDR='192.168.2.1' DEF_DHCPGATEWAYIP_ADDR='0.0.0.0'
DEF_DHCPNAMESERVER_ADDR='0.0.0.0' DEF_DOMAIN_NAME=''
DEF_LAN_LEASE_TIME=84082693 DEF_SUBNET_MASK='255.255.255.0'
DEF_DEFAULT_GATEWAY='0.0.0.0' DEF_DHCP=0 DEF_STP_ENABLED=0
DEF_WLAN_MACAC_NUM=0 DEF_WLAN_MACAC_ENABLED=0 DEF_SUPER_NAME='super'
DEF_SUPER_PASSWORD='APR@xuniL' DEF_USER_NAME='admin'
DEF_USER_PASSWORD='1234' DHCP_CLIENT_START='192.168.2.100'
DHCP_CLIENT_END='192.168.2.200' RSER_ENABLED=0 RSER_CLT_TBL_NUM=0
RSER_USR_TBL_NUM=0 ELAN_MAC_ADDR=000000000000
WLAN_MAC_ADDR=000000000000 SSID='HYA-L1' CHANNEL=1 WEP=0
WEP64_KEY1=0000000000 WEP64_KEY2=0000000000 WEP64_KEY3=0000000000
WEP64_KEY4=0000000000 WEP128_KEY1=00000000000000000000000000
WEP128_KEY2=00000000000000000000000000
WEP128_KEY3=00000000000000000000000000
WEP128_KEY4=00000000000000000000000000 WEP_DEFAULT_KEY=0
WEP_KEY_TYPE=1 FRAG_THRESHOLD=2346 SUPPORTED_RATES=15
BEACON_INTERVAL=100 PREAMBLE_TYPE=0 BASIC_RATES=3 RTS_THRESHOLD=2347
AUTH_TYPE=2 HIDDEN_SSID=0 WLAN_DISABLED=0 INACTIVITY_TIME=30000
RATE_ADAPTIVE_ENABLED=1 DTIM_PERIOD=127 WLAN_MODE=255 NETWORK_TYPE=255
IAPP_DISABLED=0 AP_MODE=0 AP_MODE_TEMP=0 SECURITY_MODE=0
CLIENT_IP_DISABLED=0 WL_LINKMAC1=000000000000 WL_LINKMAC2=000000000000
WL_LINKMAC3=000000000000 WL_LINKMAC4=000000000000
WL_LINKMAC5=000000000000 WL_LINKMAC6=000000000000 WLAN_ENCRYPT=255
WLAN_ENABLE_SUPP_NONWPA=3 WLAN_SUPP_NONWPA=0 WLAN_WPA_AUTH=0
WLAN_WPA_CIPHER_SUITE=0 WLAN_WPA_PSK='' WLAN_WPA_GROUP_REKEY_TIME=0
MAC_AUTH_ENABLED=0 RS_IP='0.1.81.128' RS_PORT=0 RS_PASSWORD=''
RS_MAXRETRY=0 RS_INTERVAL_TIME=60 ACCOUNT_RS_ENABLED=0
ACCOUNT_RS_IP='0.0.0.0' ACCOUNT_RS_PORT=0 ACCOUNT_RS_PASSWORD=''
ACCOUNT_RS_UPDATE_ENABLED=0 ACCOUNT_RS_UPDATE_DELAY=0
ACCOUNT_RS_MAXRETRY=0 ACCOUNT_RS_INTERVAL_TIME=768 WLAN_ENABLE_1X=0
WLAN_PSK_FORMAT=0 ALIAS_NAME='' IP_ADDR='192.168.2.1'
DHCPGATEWAYIP_ADDR='0.0.0.0' DHCPNAMESERVER_ADDR='0.0.0.0'
DOMAIN_NAME='' LAN_LEASE_TIME=84082693 SUBNET_MASK='255.255.255.0'
DEFAULT_GATEWAY='0.0.0.0' DHCP=0 STP_ENABLED=0 WLAN_MACAC_NUM=0
WLAN_MACAC_ENABLED=0 SUPER_NAME='super' SUPER_PASSWORD='APR@xuniL'
USER_NAME='admin' USER_PASSWORD='1234'

BUILTIN TFTP

-------------------------
The builtin tftp that is invoked from the web interface loads,
verifies?, flashes and reboots. No source is provided for this binary.

This is not so useful as we would really like to do two things here:

* load and execute (not flash) - may not be possible due to space
constraints
* load an arbitary binary - if you have a console who cares?

WHAT IS ON THIS BOX?

-------------------------
Looks like the earlier firmware had a bunch of stuff for both an AP
and a Gateway (Router). This was changed somewhere along the way and
the 2.49 firmware is stripped right down. The following is what I have
cobbled together from the 2.32 firmware + some other packages.

BRCTL
Bridge utility. This manges and controls bridging tables for
joining the wireless and ethernet interfaces together as one LAN

PPPD
ppp daemon, Hmm, why is this here?

PPPOED
ppp over ethernet daemon, even curiouser. Tis can be used to
connect to a DSL modem or tunnel through to somewhere else

DHCPD
DHCP daemon for serving IP addresses to the wireless clients and
probablly also to wired clients

DHCPC
DHCP client, so we can get an address from ??

WEBS
tiny webserver for the admin pages

IPTABLES
interface to netfilter tables. Needs to have support in the kernel

IWPRIV
Wir eless tools

FLASH
Flash seems to be a utility that allows the get and set of
parameters; no source to this - extracted from the firmware. The
typical use is in scripts where it is run like: eval `flash get
WLAN_MODE` This sets an environment variable $WLAN_MODE that is used
after the get

THINGS THAT ARE PREBUILT

-------------------------
Uh, these are things that I extracted from the firmware. No source is
available for
any of them.

AUTH ??

DISC_SERVER

FLASH Very important. This is the binary that is used to write stuff
to flash - oh and also to read. Assuming it is something like the
flash that is included in the boot code (but driven from the command
line rather than linked in). There are examples of it's useage in the
scripts in the firmware.

IAPP ??

IWCONTROL ??

PPTP Client for the proprietary Microsoft Point-to-point Tunneling
Protocol PPTP (Allows connection to a PPTP based VPN -- or a cable or
DSL service)

SETUP Custom login binary that is executed from /etc/profile as the
system comes up. Presents a login screen using non-standard methods.

UPNPD Universal plug and play daemon. Supposed to help things like
MSN Messenger work from behind a firewall

WEB PAGES

-------------------------
The web pages used to be in an external archive that was loaded into
flash at an address 64K before the CSYS image. Somewhere arround 2.39
this changed. In 2.49 the web pages are in the ramdisk image in /web

Two things of interest with the web interface, firstly how are the
settings and ROM values extracted for the web server to display?

* In the asp pages there is the use fo a function "getInfo" that
seems to return the parameters needed. Where is this command, is it a
bit of Java script that is not included with the source? Is it some
other function - I suspect that the Flash chat for website [38] values
are retrieved weight loss product [39] from the flash dump in /etc
* Secondly how are changes applied back to the system?

After almost any change the system reboots, so it is probably a safe
bet that changes are vlidated then written to ROM and they system
rebooted. You can find more about it using essay writing service [40].

The GoAhead [41] webserver has a special type of CGI procesing. It
accepts a POST command with the target of /goform/pagename. This is
for an embedded function that proceses the POST data. A function is
added to the configuration using the websFormDefine function of
writing service [42] and a jump table is built of the embedded forms.
Each ASP page in the webs configuration uses this mechanism to pass
variables (configuration changes) to the embedded functions in the
webserver.

The webs binary in the 2.39 image is 238272 bytes
The webs built in the 1.6-SDK tree is 225196 bytes

partial dump of the 2.49 webs binary. Note: these are just the
strings form the bss section of the binary, the code that implements
these functions is elsewhere. The binary is stripped maing it a bit
difficult to reverse engineer the functionality of the forms.

00002a30 66 6f 72 6d 57 6c 61 6e 53 65 74 75 70 00 77 65
|formWlanSetup.we| 00002a40 62 73 46 6f 72 6d 44 65 66 69 6e 65 00 66
6f 72 |bsFormDefine.for| 00002a50 6d 57 6c 61 6e 54 65 6d 70 00 66 6f
72 6d 57 65 |mWlanTemp.formWe| 00002a60 70 00 66 6f 72 6d 57 64 73 57
65 70 00 66 6f 72 |p.formWdsWep.for| 00002a70 6d 54 63 70 69 70 53 65
74 75 70 00 67 65 74 49 |mTcpipSetup.getI| 00002a80 6e 66 6f 00 77 65
62 73 41 73 70 44 65 66 69 6e |nfo.websAspDefin| 00002a90 65 00 67 65
74 49 6e 64 65 78 00 77 6c 41 63 4c |e.getIndex.wlAcL| 00002aa0 69 73
74 00 66 6f 72 6d 50 61 73 73 77 6f 72 64 |ist.formPassword| 00002ab0
53 65 74 75 70 00 66 6f 72 6d 55 70 6c 6f 61 64 |Setup.formUpload|
00002ac0 00 66 6f 72 6d 57 6c 41 63 00 66 6f 72 6d 41 64
|.formWlAc.formAd| 00002ad0 76 61 6e 63 65 53 65 74 75 70 00 66 6f 72
6d 53 |vanceSetup.formS| 00002ae0 65 63 4c 6f 67 00 66 6f 72 6d 53 79
73 4c 6f 67 |ecLog.formSysLog| 00002af0 00 66 6f 72 6d 44 65 62 75 67
00 66 6f 72 6d 53 |.formDebug.formS| 00002b00 61 76 65 43 6f 6e 66 69
67 00 66 6f 72 6d 57 6c |aveConfig.formWl| 00002b10 53 69 74 65 53 75
72 76 65 79 00 77 6c 53 69 74 |SiteSurvey.wlSit| 00002b20 65 53 75 72
76 65 79 54 62 6c 00 66 6f 72 6d 57 |eSurveyTbl.formW| 00002b30 6c 45
6e 63 72 79 70 74 00 66 6f 72 6d 52 61 64 |lEncrypt.formRad| 00002b40
69 75 73 00 52 61 64 69 75 73 43 6c 74 4c 69 73 |ius.RadiusCltLis|
00002b50 74 00 52 61 64 69 75 73 55 73 72 4c 69 73 74 00
|t.RadiusUsrList.| 00002b60 66 6f 72 6d 52 65 62 6f 6f 74 00 66 6f 72
6d 41 |formReboot.formA| 00002b70 63 63 65 70 74 00 66 6f 72 6d 4c 69
63 65 6e 63 |ccept.formLicenc| 00002b80 65 00 77 69 72 65 6c 65 73 73
43 6c 69 65 6e 74 |e.wirelessClient| 00002b90 4c 69 73 74 00 66 6f 72
6d 57 69 72 65 6c 65 73 |List.formWireles| 00002ba0 73 54 62 6c 00 66
6f 72 6d 53 74 61 74 73 00 69 |sTbl.formStats.i| 00002bd0 49 70 61 64
64 72 00 77 65 62 73 53 65 74 48 6f |Ipaddr.websSetHo|

Forms called from 2.49 web pages

formSaveConfig
contool.asp

formWep
encryption.asp
encryption1.asp
encryption2.asp
wlwdk.asp
wlwep.asp
wlwsk.asp

formWlAc
macfilter1.asp

formRadius
radius.asp

formReboot
reset.asp

formTcpipSetup
sysutility.asp

formUpload
upgrade.asp

formWlEncrypt
wl1x.asp
wlars.asp
wlencrypt.asp
wlpsk.asp
wlsec.asp

formAdvanceSetup
wla.asp
wlaipc.asp

formWlanSetup
wlbasic.asp

formWirelessTbl
wlstatbl.asp

formWlSiteSurvey
wlsurvey.asp

formWdsWep
wlwdswep.asp

FIRMWARE DECOMPOSITION

This section is a dump of some stuff I did about 4 months ago. Some
of it is a bit wrong. and needs some formatting. Thought I would get
it out here though.
The firmware image is a single binary file that is loaded onto the AP
then burnt into flash at a specified address. The start of the binary
file is a structure that contains some ephedrine [43] information
about the image ( 12 bytes)
From previous attempts at decomposing the image there is a number of
archives in the file.

HEADER STRUCTURE

---from main.c in /boot/init --------

firmware signiture "CSYS" at 0x0010000

firmware image header signiture (len 4) start address (len 4)
unsigned long length (len 4) unsigned long

This is the 12 bytes that are at the start of the image. The next
bytes are the start of the compressed image (gzip header).

setting image header tag (len 1) version (len 2) length (len 2)

ROM PARTITIONS

There are four partitions in the ROM image. The partitions are used
to store different settings, At the ROM base is the initial boot jump
- this is the address where execution starts as the processor is
powered up. From that a jump is to the boot loader.

flash base 0x2bf0000

The boot section of the ROM is from offset 0x00000 to 0x010000

0x000000 -> 0x004000 (16K) - boot code ? 0x004000 -> 0x006000 ( 8K)
- ?? 0x004000 -> 0x006000 ( 8K) - ??

0x006000 -> 0x006400 ( 1K) - HS (Hardware settings) 0x006400 ->
0x008000 ( 7K) - DS (Default settings) 0x008000 -> 0x010000 (32K) - CS
(Current settings)

hw signiture "HS 0x00 0x00" at 0x0006000

sw D signiture "DS 0x00 0x00" at 0x0006400 sw C signiture "CS 0x00
0x00" at 0x0008000

code image offset 0x0010000 code image offset2 0x0020000 code image
offset3 0x0030000 code image offset4 0x0008000

The image offsets are used to locate the image during the boot
sequence. Each offset is checked in turn to find the firmware image
header. When booting we see the message "No image found at 10000" -
this is confusing as the image seems to be located there (check by
dumping the ROM contents to RAM then dumping to the console).

The alternative offsets are obviously planning for growth of the
firmware defaults or image (the offset4 location chews into the
"reserved space of the ROM by 32K

The image offsets are used to locate the image during the boot
sequence. Each offset is checked in turn to find the firmware image
header. When booting we see the message "No image found at 10000" -
this is confusing as the image seems to be located there (check by
dumping the ROM contents to RAM then dumping to the console).

The alternative offsets are obviously planning for growth of the
firmware defaults or image (the offset4 location chews into the
"reserved space of the ROM by 32K.

Note: the code as it stands would not work. The function to check the
image check_system_image() should return the starting address
contained in the image header. Inside the function the checksum is
computed and it returns(0) if there is a sum. This code is obviously
an early snapshot - as this would always return without an address.

BOOT SEQUENCE (MAIN.C )

start_kernel
checks for the image at the image offsets and returns the address of
the image the firmware image header is returned and then the image is
copied to RAM (from returned address to start address in ram
(0x80300000) and number of bytes 0x000eb802

00010000 43 53 59 53 80 30 00 00 00 0e b8 02 00 00 80 21
|CSYS.0.........!|

BACKING UP SETTINGS

From the web interface you can back up the settings. This leaves a
file config.bin on your computer. the file has a 4 byte header CS07
then is a gziped image.

Note the HS and DS are not backed up

VERSION 2.32

Version 2.32 had some sort of compressed web page volume at the start
of the archive the instructions to use dd | zcat always results in
trailing garbage - it looks like there is a data segment that starts
at

0x00000 WEBP 00 01 00 00 00 00

then a size and name of the output file webpages-app.bin

0x0000d -> 0x07300

then null until the next image in the file

0x00010000 CSYS.0 00 00 00

VERSION 2.34

00018000 00 00 00 00 00 00 00 00 00 00 00 00 1f 8b 08 08
|................| 00018010 83 48 af 3f 02 03 76 6d 6c 69 6e 75 78 5f
69 6d |......vmlinux_im| 00018020 67 00 ec 5b 6b 70 5c d5 7d ff df c7
4a 6b 7b 2d |g......kp-......| 00018030 ae e5 95 d8 12 19 ef 95 ae d6
8b a3 24 0b 55 41 |..............UA|

Start of gzipped linux image. 1f b8 is zip "magic"

+--+--+--+--+--------+--+--+-- |1f|8b|08|08|8348af3f|02|03|
+--+--+--+--+--------+--+--+-- ID1 - 1f ID2 - 8b CM - compression
method 08 = Deflate FLAG - bit flag 0 0 0 0 1 0 0 0 LSB | | | | | | |
+- FTEXT | | | | | | +---- FHCRC | | | | | +------- FEXTRA | | | |
+---------- FNAME | | | +------------- FCOMMENT MTIME - modification
time XFL - extra flag 2 = max compress, 4 = fast compress OS - 03 =
UNIX

last 8 bytes of the archive are the orig_crc (4) and orig_len (4)

VERSION 2.39

Version 2.39 has only a portion of the webpages (512bytes) then
nothing. It seems that the way of loading web pages has changed. I
suspect that the loading code is still there but the real pages are in
the ramdisk filesystem now.

00000000 WEBP ...... 00000120 00 00 00 00 00 .....
00010000 CSYS.5....
0001d060 00 00 03 5a 00 00 01 6c 00 00 03 a8 00 00 02 7e
|...Z...l.......~| 0001d070 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 |................| * 0001d400 00 00 00 00 00 00 00 00 00 00 00
00 42 5a 68 39 |............BZh9| 0001d410 31 41 59 26 53 59 16 60 bf
77 00 6d 8d 7f ff ff |1AY&SY.`.w.m....|

compressed bzip2 image at 0x1d40c
uncompress then find our markers:

0013d200 .ELF ....

0016cee0 04 04 04 04 04 04 04 04 04 04 10 10 10 10 10 10
|................| 0016cef0 10 41 41 41 41 41 41 01 01 01 01 01 01 01
01 01 |.AAAAAA.........| 0016cf00 01 01 01 01 01 01 01 01 01 01 01 10
10 10 10 10 |................| 0016cf10 10 42 42 42 42 42 42 02 02 02
02 02 02 02 02 02 |.BBBBBB.........| 0016cf20 02 02 02 02 02 02 02 02
02 02 02 10 10 10 10 08 |................|
0017d910 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|................| * 0017dc00 7f 45 4c 46 01 02 01 00 00 00 00 00 00
00 00 00 |.ELF............| 0017dc10 00 02 00 08 00 00 00 01 00 40 2b
20 00 00 00 34 |.........@+ ...4| 0017dc20 00 05 57 4c 00 00 00 05 00
34 00 20 00 06 00 28 |..WL.....4. ...(|
od -s 0x16ce00 someimg.out | more | grep -B 1 -e ^* > gaps
to find the gaps in the binary data

VERSION 2.49

pull out the vmlinux image as before

The ramdisk is not at the same location (16d000) in the vmlinux.image
so my guess is that they have changed the type of the filesystem
beingused for the ramdisk. (Could be cramfs or squishfs).

The kernel code has some obvious markers in it just before the
ramdisk:

0016fb90 04 04 04 04 04 04 04 04 04 04 10 10 10 10 10 10
|................| 0016fba0 10 41 41 41 41 41 41 01 01 01 01 01 01 01
01 01 |.AAAAAA.........| 0016fbb0 01 01 01 01 01 01 01 01 01 01 01 10
10 10 10 10 |................| 0016fbc0 10 42 42 42 42 42 42 02 02 02
02 02 02 02 02 02 |.BBBBBB.........| 0016fbd0 02 02 02 02 02 02 02 02
02 02 02 10 10 10 10 08 |................|

then a bunch of nulls and then some new data starting at 0x00170000

0016fc60 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|................| * 00170000 42 5a 68 39 31 41 59 26 53 59 fb 62 b7
aa 00 93 |BZh91AY&SY.b....| 00170010 56 ff ff ff ff ff ff ff ff ff ff
ff ff ff ff ff |V...............| 00170020 ff ff ff ff ff ff ff ff ff
ff ff ff ff ff ff ff |................|

yep, pulling that part of the file out you get a Bzip2 file. when you
bunzip2 it
you get the good old ext2 filesystem.

mount as per previous instructions

This suggests that there is probably not any change in the boot
loader, the fact that the original web section of the binary is still
there ( any wasting space ) means that the /web uncompress still runs
though it only unpacks a simple header.

They have squashed the size of the image down considerably from
previous versions, this is the uncompressed and mounted fs - perhaps
they have taken out the routing software?

VERSION 2.53

Smaller image again.
strip of the webp.bin archive from the start

dd if=MNWAPB.bin bs=1 skip=$((0x10000)) > 2-53-csys.bin

the csys image has the 12 byte header and checksum at the end.

0x0000 -> 0x08000 (32K) is the secondary boot loader

0x08000 -> zipfile of vmlinux.img

if8b ID1 ID2 08 DEFLATE 08 FNAME a3 1c 23 41 MTIME 02 XFLG 03 UNIX

76 6d 6c 69 6e 75 78 5f 69 6d 67 vmlinux_img
The end of the zipfile has 8 bytes of zipdata 4 bytes of crc and 4
bytes of orig length.

dd if=2-59-csys.bin bs=1 skip=$((0x800C)) > vmlinux.img.gz gunzip
vmlinux.img.gz gunzip warns about trailing garbage - padding of 00 00
and the 2 bytes of the csys checksum

dd if=vmlinux.img bs=1 skip=$((0x170000)) > ramdisk.bz2 bunzip2
ramdisk.bz2 bunzip2 warns about trailing garbage - padding of 00 00 00
to 32k boundary?

and there is our favorite ext2 filesystem

mkdir mnt
mount -t ext2 -o loop ramdisk ./mnt -o rw,nodev,nosuid,noexec

the ramdisk is 1646 blocks (of 1K) with 1405 used

edited the /etc/profile (remove last line where setup is run
rebzip2 the file it is slightly larger 0x575xx compared to 0x57420
as extracted from the vmlinux.img the bzip2 file was padded out to
0x58000 (32K boundary?)

this must be because I didn't specify the -9 argument to bzip2
added padding to the end of the new bzip file
concatenated the kernel and the bzip
gzip -9 vmlinux.img
pad to 0xE1400

this resulted in a partial success. kernel started to uncompress but
then it gave an error ran out of data. The ramdisk I built is slightly
smaller than the original (higher compression? ) checking the
System.map there is a size of ramdisk symbol checking the build the
appimg.o get created as an elf it adds 0x1000 at the start and 0x01C0
to the end of the binary "image" the stuff at the end is the symbol
table - this gets stripped away building the final image. The stuff at
the start is an ELF header,it includes the size of the ramdisk image.

the error comes from the code where a character is retrieved from the
input file. It indicates that we have tried to read beyond the end of
the compressed file - but I havent found where the end is set yet.
This dosn't make sense as the gzip file is made from the concatenated
kernel and ramdisk.

I'll try re-joining an unmodified ramdisk and see if that works -
this is to see if the uncompress is Ok on the gzip and bzip I am
using. I fthis proves Ok then I need to work ut why the modified
ramdisk is causing the uncompress to choke.
could try with a modified one that is a little bigger than the orig
rather than a little smaller.

Sofar so good the bzip is the same size, padded and attached to the
kernel is Ok, same size, adding the padding

WEB DOWNLOAD OF IMAGE

What I haven't worked out is how the image is decomposed when
downloaded. The download is a simple TFTP, a single composite image is
loaded into RAM. The TFTP reports the start address and the size. The
image is made up of a bunch of things:

000000 Web page archive
080000 CSYS image start
010000
018000 start of gzipped vmlinux image

extract the vmlinux image and it is made up of a number of parts also

000000 ?? kernel
16xxxx start of embeded ram disk (gzip in 2.23,2.32,2.34,bzip2 2.49

junk at the end ???
From the rtkload dir in the Linux kernal source the "target" is
linux.bin
backtrack through this to find where everything gets put

linux.bin = cvimg rtkrom linux.bin 80300000

looks like cvimg I suspect this relocates the code to the
specified address (sets relative jumps)

rtkrom = mips-linux-objcopy -Obinary memload-full rtkrom

object copy -O binary generates raw binary file, a memory dump of
the contents of the input file. All symbols and relocation information
is discarded. The dump starts at the load address of the lowest
section copied into the output file

memload-full = cp memload-partial memload-full

vestigal step?

memload-partial =

mips-linux-gcc -fno-pic -mno-abicalls -O2 -fomit-frame-pointer
-DKERNEL -EB -c vmlinux_img.c -o vmlinux_img.o creates an (almost)
empty binary, used to set the relocation base? as the remainder if the
kernal is added?

mips-linux-objcopy --add-section .vmlinux=vmlinux_img.gz
vmlinux_img.o Add the compressed Kernel(and embeded RAM disk) to the
binary

$(LD) -G 0 -T $(LDSCRIPT) -o memload-partial start.o hfload.o
read_memory.o vsprintf.o prom_printf.o string.o ctype.o display.o
misc.o vmlinux_img.o

$(NM) memload-partial produces the system.map (for information only,
as binary gets stripped later)

vmlinux_img.gz =

cp $(KERNEL_ROOT)/vmlinux vmlinux-stripped copy the kernal image
here copy the kernal image here mips-linux-strip vmlinux-stripped
strip it mips-linux-objcopy -Obinary vmlinux-stripped vmlinux_img
strip it again and remove relocation information rm -f vmlinux_img.gz
clean up gzip -9v vmlinux_img compress it

BUILDING THE INITRD IMAGE

in the AP dir the mkimg directory is where the ramdisk image is
built.
run the mkdir script

./buildfs -b 2800 -s app_script -o ../../linux-2.4.18/appimg/appimg

The mkimg script calls buildfs and leaves the resulting file in the
linux tree
to get included when the kernel builds. This is why the kernal is
built first then re-built after the applications are built.

buildfs seems to be some sort of composite binary, or compiled script
(perl?).
If you run it as a nonpriveledged user you see a bunch of erros that
let you know what is going on.

Makes a ext2 filesystem called appimg of size -b number of 1k blocks.
(need to be careful here as if you have more stuff than will fit it
creates the nodes in the filesystem but there is no data - all files
added after the fs is full are zero size).

You can check this by mounting the created fs and checking there is
free space with df

Once the filesystem is made it is mounted on /mnt then the app_script
is run to load the applications into the fs at the required location.

Note: the released source contains a few binary only applications.
Also when comparing the source to the images extracted from the
various firmware versions there are a few more binaries and a bunch of
scripts that are not in the source. These are now in the AP/binary and
AP/script directories and are loaded back in by the app_script

WHAT TO ADD TO THIS UNIT?

-------------------------
Well apart from just being able to build and modify the firmware,
what I was looking for is to add a few features that make it a bit
more useable and useful.

USEABLE

Means allowing someone that doesn't want to mod the hardware to
upload custom firmware. This may be a two step process. Use the web
interface to load a firmware version that allows access to the box
(telnet of ssh).

Need to investigate how the web pages interact with the device.
Interested in how settings are changed, change is affected and how the
firmware upload is done

From there a new bootloader could be installed that provides the boot
wait functionality that would allow recovery after a problem.

USEFUL

In a community wireless environment there are two possible uses of
this box, one as a public AP and the second as a backlink to a higher
order node. In addition it might be fun to use it as a WLAN only
Gateway device - turn the LAN port into a WAN port - all the software
is therebut not configured correctly.

* Public AP

* Needs NoCatSplash [44] for access control / logging
* Route (not bridge) between WLAN and LAN

* Backlink

* Configure as a client of the higher order node (wireless radio in
client mode)
* Route (not bridge) between WLAN and LAN

* Gateway

* Use ethernet port for WAN access (no local LAN only WLAN)
* Add second ethernet controller and line driver for WLAN,LAN and
WAN use

SOFTWARE MODIFICATIONS

-------------------------
These are software modifications I have been working on.

BOOT_WAIT

The serial port modification is a giant pain in the arse.
Modification to the boot loader to provide the same type of boot_wait
functionality as we have on the LINKSYS would be a good start.

* changed eth_tftpd.c to support "know" filenames. This will allow
automatic action when a tftp is done using well known file names. Two
names are supported: dna_test.img dna_flash.img

* If a file named fw_test.img is uploaded it is written to RAM and
execution jumps to the start of the file. (needs to not have the CSYS
header)

* If a file named fw_flash.img is uploaded it is written to flash at
the address 0x020000. This will be the system firmware upon reboot.
The aim of being able to do this is to let someone without a serial
console update the firmware during the boot wait period (especially
useful once you have accidently bricked your AP).

* Only a well formed CSYS image should ever be flashed this way (i.e.
not stripped header).

* changed main.c to run the tftpd during the user_interrupt wait
function. Now this function will start the tftpd server and go into
it's timer loop waiting for a keyboard interrupt. If there is no
interrupt and a tftp has commenced it falls into the monitor. There is
potentially a problem here if the transfer is not a known image - it
will write it to RAM then stay in the monitor forever. (reboot will be
Ok though).

To do this we need to re-flash the boot loader - For now build the
functionality we want, use the existing loader to copy it to RAM then
jump to it. See if we can get it to work then flash it.

For mass use the approach would be to distribute a firmware that has
the boot loaded image and a little utility.

Use the web download to put it on the machine then ssh in and run the
utility. This would then load the new boot loader.

Need to understand what get's flashed from the web interface (seems
to take the image including the web pages probably loads to 0x10000.

ROUTE NOT BRIDGE

The bridging rules are set up in a script that calls brutils. This
can be easily changed to remove the bridge between the WLAN and the
LAN interface. The script has code for a WAN interface (not physicaly
on this unit) that is a good template of what is wanted here. Need to
the set the WLAN and LAN addresses seperately

SYSTEM ACCESS

You can turn on the telnet daemon in busybox, useful for the initial
exploration. Not sure if the password protection on the serial port is
in the busybox code or a wrapper.

Once I have had a look around then dropbear looks like the way to go.
Using the code from the LINKSYS I have been able to build it in the
tree - need to make a script to do the setup. (crib the linksys rc
code). The start script first creates the server key (if it is not
present) the runs it.

?????? need to understand how the flash utility works - assume it
allows storing values in flash but how big and how much space is
available and how much is used - probably one of those partitions in
the boot sector of the flash.

MONITORING

Snort for intrusion detection.

TRAFFIC MANAGEMENT

Frottle, as the other nodes are likely to be using this.

ROUTING

Bird or Quagga for all routing.

REALITY CHECK

After another month or so of playing with this thing, I have realized
that 8MB of RAM is very tight. You loose almost 2MB for the kernel, a
further 3-4MB with the ramdisk and each application that is loaded
chews however much it needs. I could run bird (OSPF daemon) but
nothing else. So the reality check is that while a hypothetical device
could have configurations for the three uses described above the
reality is that with some reletively minor modifications this device
can be used for a cheap and cheerful backlink but it's not really
worth spending time trying to use it for a captive portal or an
Internet gateway.

One thing that could change this is the addition of a second RAM
chip. It was suggested to me that you could take a chip of a PC133
SDRAM (the RAM chip is a standard SDRAM 54 pin TSOP2 package). Adding
a second chip 64MBit gives you another 8MB RAM or replacing the
existing chip with a 128MBit and adding a second takes you up to the
max 32MB supported by the processor.

Using CRAMFS or a tiny bootdisk & NFS are also ways of getting back a
bit of RAM .

I'll post up the modified boot loader, I'm adding DHCP client support
to it so you can have the device boot from a TFTP server and a minimal
ramdisk to use it as a backlink radio

Links:
------
[1] http://melbournewireless.org.au/#code_organization
[2] http://melbournewireless.org.au/#rom_size_and_building_the_image
[3] http://melbournewireless.org.au/#embedded_ramdisk
[4] http://melbournewireless.org.au/#bootloader
[5] http://melbournewireless.org.au/#memory_map
[6] http://melbournewireless.org.au/#building_the_embedded_ramdisk
[7] http://melbournewireless.org.au/#console_login
[8] http://melbournewireless.org.au/#flash_variables
[9] http://melbournewireless.org.au/#builtin_tftp
[10] http://melbournewireless.org.au/#what_is_on_this_box_
[11] http://melbournewireless.org.au/#things_that_are_prebuilt
[12] http://melbournewireless.org.au/#web_pages
[13] http://melbournewireless.org.au/#firmware_decomposition
[14] http://melbournewireless.org.au/#header_structure
[15] http://melbournewireless.org.au/#rom_partitions
[16] http://melbournewireless.org.au/#boot_sequencemain_c
[17] http://melbournewireless.org.au/#backing_up_settings
[18] http://melbournewireless.org.au/#version_2_32
[19] http://melbournewireless.org.au/#version_2_34
[20] http://melbournewireless.org.au/#version_2_39
[21] http://melbournewireless.org.au/#version_2_49
[22] http://melbournewireless.org.au/#version_2_53
[23] http://melbournewireless.org.au/#web_download_of_image
[24] http://melbournewireless.org.au/#building_the_initrd_image
[25] http://melbournewireless.org.au/#what_to_add_to_this_unit_
[26] http://melbournewireless.org.au/#useable
[27] http://melbournewireless.org.au/#useful
[28] http://melbournewireless.org.au/#software_modifications
[29] http://melbournewireless.org.au/#boot_wait
[30] http://melbournewireless.org.au/#route_not_bridge
[31] http://melbournewireless.org.au/#system_access
[32] http://melbournewireless.org.au/#monitoring
[33] http://melbournewireless.org.au/#traffic_management
[34] http://melbournewireless.org.au/#routing
[35] http://melbournewireless.org.au/#reality_check
[36] http://www.bookwormlab.com/
[37]
http://sourceforge.net/forum/forum.php?thread_id=1066513&forum_id=350305
[38] http://www.flashcoms.com
[39] http://www.supplementstoweightloss.com/
[40] http://www.bestessayhelp.com/
[41] http://melbournewireless.org.au/?GoAhead
[42] http://customwritingservices.org/index.php
[43] http://www.shoppharmacycounter.com/c-8-ephedra-diet.aspx
[44] http://melbournewireless.org.au/?NoCatSplash

[EditText] [Spelling] [Current] [Raw] [Code] [Diff] [Subscribe] [VersionHistory] [Revert] [Delete] [RecentChanges]

> home> about> events> files> members> maps> wiki board   > home   > categories   > search   > changes   > formatting   > extras> site map

Username
Password

 Remember me.
>

> forgotten password?
> register?
currently 0 users online
Node Statistics
building132
gathering192
interested515
operational242
testing216