Building OpenWRT for DSL502T Appliances - Removing Modules

When building OpenWRT Kamikaze 8.09.2 for the DSL502T there are a number of mobiles included by default that are important if you are using the device as a modem but unnecessary if you plan to use the device as an appliance.

After some playing I have found the following modules can be excluded:

Kernel Modules = kmod-sangam-atm-annex-a, kmod-ppp, kmod-pppoa, kmod-pppoe, kmod-ocx

In my configuration the difference in after boot memory usage is as follows:


Mem: 10268K used, 2492K free, 0K shrd, 1300K buff, 4168K cached


Module                  Size  Used by    Not tainted
tiatm                 151008  0
acx                   136704  0
nf_nat_tftp             1088  0
nf_conntrack_tftp       3760  1 nf_nat_tftp
nf_nat_irc              1856  0
nf_conntrack_irc        4768  1 nf_nat_irc
nf_nat_ftp              2432  0
nf_conntrack_ftp        6880  1 nf_nat_ftp
ipt_MASQUERADE          2080  0
iptable_nat             4240  0
nf_nat                 14624  5 nf_nat_tftp,nf_nat_irc,nf_nat_ftp,ipt_MASQUERADE,iptable_nat
xt_state                1600  0
nf_conntrack_ipv4      12064  3 iptable_nat,nf_nat
nf_conntrack           46592  11 pppoatm                 4320  0
ipt_REJECT              2976  0
xt_TCPMSS               3136  0
ipt_LOG                 6720  0
xt_multiport            2528  0
xt_mac                  1312  0
xt_limit                2016  0
iptable_mangle          2080  0
iptable_filter          2080  0
ip_tables              10064  3 iptable_nat,iptable_mangle,iptable_filter
xt_tcpudp               2624  0
x_tables               11504  11 ppp_async              10944  0
ppp_generic            26080  2 pppoatm,ppp_async
slhc                    5952  1 ppp_generic
crc_ccitt               1440  1 ppp_async
br2684                  7920  0
atm                    48912  3 tiatm,pppoatm,br2684


Mem: 7628K used, 5132K free, 0K shrd, 964K buff, 3180K cached


Module                  Size  Used by    Not tainted
acx                   136704  0
gpio_dev                3184  0
br2684                  7920  0
atm                    48912  1 br2684




Ubuntu 8.1 - Network Configuration Change Script

Ubuntu 8.1 works really well as a build environment for OpenWRT and programming environment for the DSL502T. 

I have found that to make OpenWRT a network connection with Internet access is required but to program the DSL502T using minimizing network traffic is important to prevent hangs during programming.

Also all the DSL502T units I have seen use as the IP address for programming... but my internal network using 10.x.x.x network addresses.

So I needed a quick/easy way to switch between DHCP assignment of addresses for the internal network and STATIC assignment when programming.

Directly editing /etc/network/interfaces and restarting the network services works but gets old fairly quickly.... instead I wrote the following setnet script which is called passing DHCP or STATIC as the parameter.  It changes the network configuration and restarts the networking services.


# Check if parameters are provided

if [ $# -ne 1 ]
    echo "Must specify STATIC or DHCP"
    exit 1

ETHMODE=`echo $1 | tr [:lower:] [:upper:]`

# Force both interface types to be off

sudo sed -i "s/#iface eth0 inet dhcp/iface eth0 inet dhcp/" $INTERFACES
sudo sed -i "s/#iface eth0 inet static/iface eth0 inet static/" $INTERFACES
sudo sed -i "s/iface eth0 inet dhcp/#iface eth0 inet dhcp/" $INTERFACES
sudo sed -i "s/iface eth0 inet static/#iface eth0 inet static/" $INTERFACES

# Now select the one that is required

if [ $ETHMODE = "STATIC" ]
    echo "setting STATIC"
    sudo sed -i "s/#iface eth0 inet static/iface eth0 inet static/" $INTERFACES
    sudo /etc/init.d/networking restart
elif [ $ETHMODE = "DHCP" ]
    echo "setting DHCP"
    sudo sed -i "s/#iface eth0 inet dhcp/iface eth0 inet dhcp/" $INTERFACES
    sudo /etc/init.d/networking restart
    echo "Unknown network mode"

Probably no awards for great linux shell scripting but it works for me.


DSL502T + Ruby + Webrick + YAML = DIY Monitoring Appliance

At the top of the hill on my rural property is a bore that provides stock water for my stock and three neighboring properties.

So what does this have to do with DLink DSL502T routers, Ruby, Webrick and YAML?

From time to time faults in the various farm system drain water from the header tank faster than the bore pump can pull water out of the ground.... so the pump runs continually.  Expensive on power but also potentially damaging.  Normal use is about 1 hour per day in summer, much less in winter.

The problem was how to know if the pump was running excessively without climbing the hill.... and even if I did check it was hard to know if the pump was running because it had just reached to refill point or had been running for three days.

A couple of years back I built a bore monitor that used an IR beam to determine of the bore pump was running and could be queried over the wireless network by a ruby application.  By querying every 5 minutes and storing the data in a MYSQL database I could graph daily usage over time and see when things had gone awry.

The network connection in the original design was performed using an AVR AT90S8515 and a Packet Wacker ethernet interface.  For 2 years this worked well and then the Packet Wacker died.

Around this time i had been playing with DSL502T's to provide Amateur Radio IGate services and had a build environment configured for the OpenWRT firmware.   Included in the OpenWRT packages is Ruby and I know I could easily write a ruby program with a web interface (using Webrick) and simple data storage (using YAML) so replace the original monitor board.

It took some playing but I was able to build OpenWRT with Ruby and the required modules for Webrick and YAML to operate with the following configuration:

make menuconfig

With the following options:

Target System = TI AR7 [2.6]
Target Profile = No WiFi
Target Images = squashfs

Base System = base-files, br2648ctl, busybox, dropbear, hotplug2, libgcc, libpthread, libstdcpp, mtd, opkg, uci, uclibc, udevtrigger

Network = atm-tools, wget
Library = (none)
IPv6 = (none)

Kernel Modules = kmod-ipt-core, kmod-ipt-nathelper, kmod-sangam-atm-annex-a, kmod-ppp, kmod-pppoa, kmod-pppoe, kmod-ocx

Utilities = gpioctl

Languages = ruby, ruby-core, ruby-erb, ruby-irb, ruby-openssl, ruby-webrick, ruby-yaml

The ruby-erb and ruby-openssl libraries are required in addition to ruby-webrick if you actually want webrick to work.  Not including these libraries will cause errors when you require 'webrick' in your ruby code.

I have not attempted a minimum size configuration here... it is highly likely when not used as a modem that modules such as kmod-pppoa, kmod-pppoe and kmod-sangam-atm-annex-a can be excluded.

It's not blindingly fast serving pages but as a stand alone monitoring appliance interfaced to data collection sensors via the onboard serial port and providing a simple web interface showing the current status and historical trends it does the job for me.

Another great use for $1 modems.  Time to buy a few more for the stockpile.


Building a DLink DSL-502T Based IGate

This project came about because a group of amateur radio operators in Auckland wanted to improve the APRS receive coverage by using IGates to add receive only coverage around South Auckland.

We found that a really low cost way of doing this (both initial investment and ongoing operational costs) was to use DLink DSL-502T ADSL routers with customized firmware.


The DLink DSL-502T is very common in New Zealand.  It was the router of choice for many first time ADSL users who signed up with the large ISP's.  Over time many users want devices with more capability (wireless or more ports) so the routers are available at very low cost (or free). 

For those who care about the technical details.... the official specification for a DSL-502T is

  • ADSL modem with ADSL2/2+ support to 24Mbit/s+.
  • Single 100MBps LAN port.
  • Single USB-B port (default firmware uses this to provide USB-over-ethernet to a PC host only, it's not clear if this can actually be used as a USB host)
  • Flash chip: 4MBytes - Samsung K8D3216UBC a 32Mbit NOR-type Flash Memory organized as 4M x 8
  • SDRAM: 16Mbytes - Nanya NT5SV8M16DS-6K
  • CPU: TNETD7300GDU Texas Instruments AR7 MIPS based

More complete hardware details are on the OpenWRT DSL-502T hardware page.

In it's IGate implement we don't use the ADSL modem or the USB-B port.  What the specification doesn't say is that there is an onboard serial port (even provided with soldered pin headers) which is perfect (with level conversion from RS-232 to 3.3V TTL) for connect to an TNC.

Using a DSL-502T as an IGate is as much an exercise of configuring software as it is connecting hardware.  The standard operating software makes the device an ADSL router.... we need to replace this so it becomes an IGate.

This article is written for those who are interested in how to build their own operating system image for the device and outlines the steps I followed.  It isn't hard if you have a Linux installation (real or in a VM).... I used Ubuntu 8.1 which work really well as a platform for building the operating software and flashing it into the routers.

If you don't want to get into the details and just want an image to flash visit the guys at WetNet who have prebuilt images available for download - for the DSL-502T you need an image compiled for an AR71xx.

Before going into the detail of how to we built and configured the firmware it is worth explaining what we wanted to achieve.

  • A standard set of firmware that we could flash into many routers.
  • Installation without needing to connect to each router to install extra packages or make configuration settings (unless absolutely necessary).
  • For the router to be able to indicate it's operational status using the front panel LED's (only Status, Ethernet and USB are controllable... it appears that the ADSL indicator is managed directly from the ADSL interface).
  • Central management of the APRSD configuration and have this automatically applied when the power is cycled on the router.

We achieved all these objectives using a custom OpenWRT build. 

It must be said that this project would not have been possible without the efforts of all those involved in the OpenWRT project (for creating the build scripts and environment), those who make it work on AR71xx based routers and those involved with the WebNet project who ported APRSD for the OpenWRT platform.  We are thankful to all these people and hope that the notes here benefit others wanting to package these components to build IGates.

The following outlines the process and scripts we used to configure the DSL-502T as an IGate to meet these objectives.

A suitably configured environment is required to build the OpenWRT firmware.  Assuming you are using Ubuntu 8.1

1.  Install the packages required by the OpenWrt Kamikaze buildsystem

sudo apt-get install build-essential binutils flex bison autoconf gettext texinfo sharutils subversion libncurses5-dev ncurses-term zlib1g-dev 

2.  Checkout and prepare Kamikaze and the packages.  We built out image based on Kamikaze 8.09.2

mkdir ~/openwrt
cd ~/openwrt
svn checkout svn:// .

3.  I installed the minicom and ntpclient packages in the image.  Minicom is useful for checking the serial port works..... and ntpclient to keep the time correct.  Without ntpclient the box doesn't keep very good time.

./scripts/feeds install minicom
./scripts/feeds install ntpclient

4.  By default the serial ports are configured as serial consoles.  This needs to be disabled to use them to connect with a TNC.  Disabling the ports requires a customized /etc/inittab to be included in the flash image.  

Any files in the ./files folder of the build will be added to the flash image when it is built. 

Create the following ./files/etc/inittab to configure the serial ports so they can be used.

::sysinit:/etc/init.d/rcS S boot
::shutdown:/etc/init.d/rcS K stop
#tts/0::askfirst:/bin/ash --login
#ttyS0::askfirst:/bin/ash --login
#tty1::askfirst:/bin/ash --login

5.  The default configuration for OpenWRT (at least for the version I built) is to bring the network up with a static IP address.  I wanted DHCP so a customized /etc/config/network needs to be included in the flash image. 

Create the following ./files/etc/config/network to configure the network for DHCP.

# Copyright (C) 2006

config interface loopback
    option ifname    lo
    option proto    static
    option ipaddr
    option netmask

config interface lan
    option ifname    eth0
    option proto    dhcp   


6.  While we are making changes to /etc/config it is a good idea to configure the system name and timezone.

Create the following ./files/etc/config/system to configure the system name and timezone (in this case New Zealand).

config system
    option hostname    OpenWRT_IGate
    option timezone    NZST-12:00:00NZDT-13:00:00,M10.1.0,M3.3.0


7.  We installed the ntpclient package earlier but this still needs to be configured so it connects to an appropriate time server.

The configuration details are in /etc/init.d.

Create the following ./files/etc/init.d/ntpclient to start the ntpclient with an appropriate time server (or pool in this case).

/usr/sbin/ntpclient -c 1 -s -h &

8.  OpenWRT uses symbolic links between /etc/rc.d and /etc/init.d so we need to create these in ./files to reference the updated ntpclient start script.

Create the following symbolic link in ./files/etc/rc.d

ln -s ../init.d/ntpclient S55ntpclient

9.  Time to build OpenWRT for the AR7 based DSL-502T.  First it is necessary to configure the build:

make menuconfig

With the following options:

Target System = TI AR7 [2.6]
Target Profile = No WiFi
Target Images = squashfs

Base System = base-files, br2648ctl, busybox, dropbear, hotplug2, libgcc, libpthread, libstdcpp, mtd, opkg, uci, uclibc, udevtrigger

Network = atm-tools, wget
Library = (none)
IPv6 = (none)

Kernel Modules = kmod-ipt-core, kmod-ipt-nathelper, kmod-sangam-atm-annex-a, kmod-ppp, kmod-pppoa, kmod-pppoe, kmod-ocx

Utilities = terminal/minicom, gpioctl

10.  We wanted to default the Minicom configuration so it opened port /dev/ttyS0 at 9600 baud, did not send the default initialization string but instead sent the "VER" command to the TNC.

This is done by creating the file minirc.dfl in ./files/etc with the following contents:

pu port             /dev/ttyS0
pu baudrate         9600
pu minit            VER^M
pu mreset          
pu rtscts           No 

11.   The aprsd package (or other amateur radio packages) is not included in the OpenWrt source tree at the time of writing.  The packages can be downloaded from

The OpenWrt-AX25.tgz that you download doesn't match the the folder structure required by the OpenWrt build (at least for version 8.09.2) so it is easiest to uncompress to a different location and then copy the files to the locations as shown in the following table:

OpenWRT-AX25.tgz OpenWRT Source
packages/libs/libax25 package/libs/libax25
packages/net/aprsd package/net/aprsd
packages/net/ax25-apps package/net/ax25-apps
packages/net/ax25-tools package/net/ax25-tools
packages/net/digi-ned package/net/digi-ned


12.  Ensure the aprsd and required libraries are flagged to be built:

make menuconfig

With the following additional options:

Library = libax25
Amateur Radio = aprsd


13.  If you are going to flash a single DSL-502T you can set the aprsd configuration by adding appropriately configured aprsd.conf, aprsd.config, INIT.TNC, RESTORE.TNC and welcome files to the ./files/etc/aprsd folder.  

Because we were going to install multiple DSL-502T IGates and were trying to create a standard image that could be flashed to all units it was important to have a more flexible configuration process for aprsd.

We went with the approach of storing the aprsd.config file for each unit on a central web server.  The files are named with the Ethernet MAC address of the router. 

The startup script downloads the appropriate config file on startup of the router and updates the version in flash if it has changed.  

The script we used is an extension to the standard aprsd startup script and is as follows:

#!/bin/sh /etc/rc.common
# Starts or stops aprsd server.
# Extended to perform additional DSL-502T IGate Configuration Load
# Ethernet and USB Leds are used to indicate status of router configuration
# Ethernet
#    Off =
#    On = IP Address OK from DHCP
#    Flash = No IP Address from DHCP
#    Off =
#    On = APRSD Configuration OK
#    Flash = APRSD Configuration Invalid 


# Initially both off
echo none > /sys/class/leds/ethernet/trigger
echo none > /sys/class/leds/usb/trigger

MYMAC=`ifconfig eth0 | head -1 | grep 'HWaddr ' | cut -c39-55`
MYIP=`ifconfig eth0 | head -2 | tail -1 | grep 'inet addr:' | cut -c21-33`

if [ -z $MYIP ]; then
        echo heartbeat > /sys/class/leds/ethernet/trigger
        exit 1
        echo default-on > /sys/class/leds/ethernet/trigger

cd /etc

if [ -n $MYMAC ]; then
        wget -q -N $SERVER$MYMAC.conf

if [ -f $MYMAC.conf ]; then
        if [ ! -f $APRSD_CONFIG ]; then
                cp $MYMAC.conf $APRSD_CONFIG
                CONFDIFF=`diff $MYMAC.conf $APRSD_CONFIG | wc -l`
                if [ $CONFDIFF -gt 0 ]; then
                        cp $MYMAC.conf $APRSD_CONFIG

# Check if $APRSD_CONFIG has been correctly configured

if [ ! -f $APRSD_CONFIG ]; then
        echo heartbeat > /sys/class/leds/usb/trigger
        exit 1

SERVERCALL=`cat $APRSD_CONFIG | grep 'AX_APRSD_SERVERCALL' | cut -d'=' -f 2`

if [ $SERVERCALL = '"nocall"' ]; then
        echo heartbeat > /sys/class/leds/usb/trigger
        exit 1

chmod 745 $APRSD_CONFIG

start() {
   echo  "Starting aprs server daemon. "
        # Create log directory - uncomment if you want logging
#       mkdir -p /var/log/aprsd       
        # Update aprsd.conf

        # Escape options that may include /
        AX_APRSD_PORT=`echo $AX_APRSD_PORT | sed 's/\//\\\&/g'`
        AX_APRSD_MYLOCATION=`echo $AX_APRSD_MYLOCATION | sed 's/\//\\\&/g'`
        AX_APRSD_NETBEACON=`echo $AX_APRSD_NETBEACON | sed 's/\//\\\&/g'`
        sed -i "s/\(tncport\)\(.*\)/\1 $AX_APRSD_PORT/" $APRSD_CONF
        sed -i "s/\(tncbaud\)\(.*\)/\1 $AX_APRSD_TNCBAUD/" $APRSD_CONF
        sed -i "s/\(servercall\)\(.*\)/\1 $AX_APRSD_SERVERCALL/" $APRSD_CONF
        sed -i "s/\(MyCall\)\(.*\)/\1 $AX_APRSD_MYCALL/" $APRSD_CONF
        sed -i "s/\(MyLocation\)\(.*\)/\1 $AX_APRSD_MYLOCATION/" $APRSD_CONF
        sed -i "s/\(MyEmail\)\(.*\)/\1 $AX_APRSD_MYEMAIL/" $APRSD_CONF
        sed -i "s/\(aprspath\)\(.*\)/\1 $AX_APRSD_PATH/" $APRSD_CONF
        sed -i "s/\(pass\)\(.*\)/\1 $AX_APRSD_PASS/" $APRSD_CONF
        sed -i "s/\(Server\)\(.*\)/\1 $AX_APRSD_SERVER/" $APRSD_CONF
        sed -i "s/\(NetBeacon\)\(.*\)/\1 $AX_APRSD_NETBEACON/" $APRSD_CONF
        #  start aprsd if enabled
        eval aprsd=$AX_APRSD
        if [ "$aprsd" = "TRUE" ]; then
                /usr/bin/aprsd -d
                echo default-on > /sys/class/leds/usb/trigger
                touch /var/lock/aprsd

stop() {
   echo  "Stopping aprs server daemon. "
        rm -f /var/lock/aprsd
        killall -q -INT aprsd

There are a few interesting things in the script.

  • The Ethernet and USB LED's on the DSL-502T are used to indicate status.
  • Ethernet flashing means no IP address was assigned so there is a problem somewhere with DHCP.
  • Ethernet on means an IP address was assigned.
  • USB flashing means that no aprsd.config file could be downloaded (and none already exists in flash).
  • USB on means that the device has a valid aprsd.config file (either newly downloaded or already existing).
  • When both Ethernet and USB LED's are lit the aprsd service will have been started.
  • The aprsd.config file was extended to include additional settings which are not included in the standard file and only exist in aprsd.conf.

14.  With all the modules selected the OpenWRT image is ready to build.


This could take a while.  Everything going well you will see a string of make messages, the last few messages if all went well being:

 make[2] package/rootfs-prepare
 make[3] package/preconfig
 make[2] target/install
 make[3] -C target/linux install
 make[6] -C target/linux/generic-2.6/image/lzma-loader clean compile

Your image is now built and available at ./bin/openwrt-ar7-squashfs.bin

This is the image that you flash to your DSL-502T with the command:

./scripts/ -setmtd1 ./bin/openwrt-ar7-squashfs.bin

Note:  Depending on the version of your DSL-502T the default IP address may be (rather than

Once the firmware is installed the DSL-502T will restart.... the restart process can take up to 60 seconds.  An operational IGate will be flashing the Status LED (like a heartbeat) and have Ethernet and USB LED's on.

Check your IGate appears using APRS.FI but note that your NetBeacon is not sent immediately on startup.... it will only be sent after the specified time.   Setting the NetBeacon interval to 1 minute initially to check the IGate appears and once you are properly communicating with the APRS-IS server update the NetBeacon interval to something more reasonable - we use 60 minutes.



Page 16 of 23

Powered by Easytagcloud v2.1

Contact Andrew Quinn