Linux on a Linksys WAG54G

N.B. this section is far from being complete and contains generally inaccurate information. It's just here for my note taking until I have worked things out properly. This has all been tested against a version 2 box, but should work with the almost identical version 3 as it just has twice the RAM and NAND space.

The idea of this page is to try and document my slow and irregular work to get Linux working on the Linksys WAG54G (version 2) without using the OpenWRT distribution.

Flashing the Firmware

Seems that all the instructions relating to the WAG54G are different on the internet to the version of the ADAM2 bootloader that I have (version 0.22.12). I do not get the exciting option of FTP however I do get TFTP, which is available when the bootloader kicks in (you can give yourself a larger window of opportunity if you interrupt it by pressing any key over the serial port) with:

$ tftp -v -m binary 192.168.1.1 -c put openwrt-WA21-jffs2-64k-code.bin

The above command then flashes what is '`mtd4`' in the partition table below.

Misbehaving Ethernet Ports

Another gotcha is a broken capacitor (33uF 16V) can lead to all sorts of trouble. I had this issue with all three WAG54Gs I have bought off fleabay and found that with one of them I was able to get a temporary workaround by using a direct connection from my laptop by typing:

# ethtool -s eth0 autoneg off speed 10 duplex half

Partition Table

The onboard 4MB (64kB erase size) NAND is partition as follows.

partition start end size name
mtd0 0x900e0000 0x903f0000 3136kB rootfs
mtd1 0x90020000 0x900e0000 768kB kernel
mtd2 0x90000000 0x90020000 128kB adam2 bootloader
mtd3 0x903f0000 0x90400000 64kB adam2 cfg
mtd4 0x90020000 0x903f0000 3904kB kernel + rootfs

Under Linux the `ar7part.c` driver is meant to spit out a suitable partition table for both bootloaders (PSPBoot and ADAM2) that are available on the AR7 platform however it does not and should not be used; for me the 'rootfs' partition overlaps the 'linux' partition.

Serial Cable

The best serial port mod I have seen for the Linksys routers is done by placing a standard stereo 3.5mm headphone jack onto the front leg of the box. This makes for a very tidy setup, however what to plug into the headphone jack and how do you wire it up? Well FTDI make very nice serial cables that work great under Linux, including the TTL-232R-3V3-AJ which means you do not need to mess with a MAX-232 chip or soldering.

Wiring it up could not be any easier, the pinout of the TTL-232R-3V3-AJ is available from their website and the pinout is shown below (shamelessly stolen from the old OpenWRT wiki); remember that when wiring you attach the TX pin of one end to the RX pin of the other and of course GND to GND.

|
|    __
|   |  |        <- Pin 1, GND
|    --
|   |  |        <- Pin 2, Not Connected
|    --
|   |  |        <- Pin 3, Router's Serial RX
|    --
|   |  |        <- Pin 4, Router's Serial TX
|    --
|   |  |        <- Pin 5, VCC
|    --
|
|
 \__led__led__led__led____________________
                Front of WAG54G

Once all hooked up, you should see some action when you load minicom and configure the serial port to run at 38400 8N1 with no hardware or software flow control.

Resurrecting a Brick

Never did get the JTAG working, but here are some useful links:

You will also probably need the ADAM2 0.22.12 bootloader blob.

Creating Firmwares

$ # svn co svn://svn.openwrt.org/openwrt/trunk openwrt
$ git clone git://nbd.name/openwrt.git
$ gcc -o srec2bin openwrt/tools/firmware-utils/src/srec2bin.c
$ gcc -o addpattern openwrt/tools/firmware-utils/src/addpattern.c

The 'cook-firmware' script is as follows:

#!/bin/sh -eu

objcopy -S -O srec --srec-forceS3 linux/vmlinuz vmlinuz.srec

./srec2bin vmlinuz.srec vmlinuz.bin

if [ $(wc -c vmlinuz.bin | cut -d' ' -f1) -gt 786432 ]; then
        echo kernel too big
        exit 1
fi

# we only need the following:
#  MAKEDEV std
#  MAKEDEV consoleonly
#  MAKEDEV ptmx
#  MAKEDEV ttyS0
#  rm tty0 ram* loop*
cat <<'EOF' > /tmp/mkfs.devtable
# <name>        <type>  <mode>  <uid>   <gid>   <major> <minor> <start> <inc>   <count>
/dev/mem        c       640     0       15      1       1       -       -       -
/dev/kmem       c       640     0       15      1       2       -       -       -
/dev/null       c       666     0       0       1       3       -       -       -
/dev/port       c       640     0       15      1       4       -       -       -
/dev/zero       c       666     0       0       1       5       -       -       -
/dev/full       c       666     0       0       1       7       -       -       -
/dev/random     c       666     0       0       1       8       -       -       -
/dev/urandom    c       666     0       0       1       9       -       -       -
/dev/tty        c       666     0       15      5       0       -       -       -
/dev/console    c       600     0       5       5       1       -       -       -
/dev/ptmx       c       666     0       5       5       2       -       -       -
/dev/pts        d       750     0       0       -       -       -       -       -
/dev/ttyS0      c       660     0       20      4       64      -       -       -

/bin/busybox    f       4755    0       0       -       -       -       -       -
EOF

/usr/sbin/mkfs.jffs2 -D /tmp/mkfs.devtable -X zlib -x lzo -x rtime -e 65536 -n -p -t -l - d buildroot/output/target/ --squash -o fs.img
if [ $(wc -c fs.img | cut -d' ' -f1) -gt 3211264 ]; then
        echo filesystem too big
        exit 1
fi

rm /tmp/mkfs.devtable

( dd if=/dev/zero bs=16 count=1; dd if=vmlinuz.bin bs=786432 conv=sync; cat fs.img ) | ./ addpattern -o firmware-code.bin -p WA21

tftp -v -m binary 192.168.1.1 -c put firmware-code.bin

exit 0

Time to build yourself a toolchain and the root filesystem:

$ git clone git://git.buildroot.net/buildroot
$ cd buildroot
$ git checkout -b wag54g origin/next
$ # cp ../buildroot.conf/config .config
$ make menuconfig
$ # UCLIBC_CONFIG_FILE=../buildroot.conf/uclibc.config make uclibc-menuconfig
$ # BUSYBOX_CONFIG_FILE=../buildroot.conf/busybox.config make busybox-menuconfig
$ make

$ rm output/target/sbin/ip
$ ln -s ../bin/busybox output/target/sbin/ip

Prepare the kernel source:

$ git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
$ cd linux

$ # git remote add mips git://git.linux-mips.org/pub/scm/linux-queue.git
$ # git fetch -n mips

$ git checkout -b ar7 v3.2

$ export OPENWRT=$(git --git-dir=../openwrt/.git log -n1 | sed -n '/git-svn-id:/ s/^.*trunk@\([0-9]\+\) .*$/\1/ p')

$ # patch -p1 drivers/tty/serial/8250.c ../openwrt/target/linux/ar7/patches-2.6.37/500-serial_kludge.patch
$ # git commit -s -m "Apply [[OpenWRT]]@$OPENWRT Serial Kludge patches" drivers/tty/serial/8250.c

$ # do *not* apply the cpmac patches
$ # find ../openwrt/target/linux/ar7/patches-2.6.37 -type f -name '9*-cpmac*.patch' | xargs cat | patch -p1
$ # git commit -s -m "Apply [[OpenWRT]]@$OPENWRT CPMAC patches" -a

$ # tar c -C ../openwrt/target/linux/generic/files drivers/net/phy/{adm6996.{c,h},swconfig.c} include/linux/switch.h Documentation/networking/adm6996.txt | tar vx | xargs git add
$ # cat ../openwrt/target/linux/generic/patches-3.0/70* ../openwrt/target/linux/generic/patches-3.0/720-phy_adm6996.patch | patch -p1
$ # git commit -s -m "Apply [[OpenWRT]]@$OPENWRT ADM6996 patches" -a

Time to cook your kernel:

$ alias mmake="ARCH=mips CROSS_COMPILE=/usr/src/wag54g/buildroot/output/host/usr/bin/mipsel-linux- make"
$ # 'mmake ar7_defconfig' or 'cp ../linconf .config'
$ # try to get as much as you can in the main kernel, as modules take up filesystem space
$ mmake menuconfig
$ mmake -j$(grep ^processor /proc/cpuinfo | wc -l)
$ INSTALL_MOD_PATH=/usr/src/wag54g/buildroot/output/target mmake modules_install

Now run the 'cook-firmware' script and you should end up with a suitable image.

Kernel Cooking Notes

A list of issues and hints I have found with the kernel:

  • CONFIG_CPMAC requires CONFIG_FIXED_PHY to function
  • CONFIG_FIXED_PHY needs to be compiled into the kernel
  • you can trim down your kernel considerably by compiling out CONFIG_BLOCK support. On the WAG54G, or any AR7 based platform, there is argubly no point having this support (as there is no way to connect a block device such as SCSI, USB, IDE, etc). For ages I was under the impression that to use JFFS2 you had to have CONFIG_BLOCK enabled so you could pass 'root=/dev/mtdblock0', however you can pass instead 'root=mtd0' which seems to be undocumented (in any JFFS2 documentation, however it is a function of the MTD subsystem)
  • if you use anything other than CONFIG_HZ_100, the timing delay loops go crazy; Florian thinks it is a bug in 4KEc stuff
  • CONFIG_CPMAC conflicts with anything other than CONFIG_PREEMPT_NONE if CONFIG_NO_HZ is set, reseting the box with no visible oops to trace the problem from when it initialises; only occurs if you have no PHY
  • you might need to apply the second part of the patch to 'drivers/serial/8250.c' from 500-serial_kludge.patch to make the serial console behave; this depends on the revision of your AR7 SoC, if the serial console looks a bit mixed up in places use this to fix it
  • for me the ar7part code is broken and so instead I add “mtdparts=physmap-flash.0:…..” to my kernel parameter list
  • for those wanting some kind of client NFS-esque support, I would recommend you look at 9p2000 and npfs as it only adds about 100kB of kernel modules to your kernel

Might be interesting for you, I use the following cmdline:

CONFIG_CMDLINE="mtdparts=physmap-flash.0:3136k@896k(rootfs),768k@128k(kernel),128k@0k(adam2)ro,64k@4032k(adam2-cfg)ro,3904k@128k(kernel+rootfs) rootfstype=jffs2 root=mtd0 rw"

TI ATM

If you cannot deal with the OpenWRT sangam-atm setup, you can download a tarball of my git tree that I have for it:

$ wget http://stuff.digriz.org.uk/sangam-atm.tar.bz2
$ tar jxf sangam-atm.tar.bz2
$ cd sangam-atm
$ mmake

If you use PPPoE, you will also need the br2684ctl tool. You will need to CVS checkout the tree at http://linux-atm.sourceforge.net/:

$ cd linux-atm
$ CC=/usr/src/wag54g/buildroot/output/host/usr/bin/mipsel-linux-gcc ./configure --with-kernel-headers=/usr/src/wag54g/linux/include/ --host=mipsel-unknown-linux-uclibc

$ cd ../buildroot/output/target
$ cp ../../../linux-atm/src/br2684/.libs/br2684ctl usr/sbin
$ cp ../../../linux-atm/src/lib/.libs/libatm.so.1.0.0 usr/lib
$ /usr/src/wag54g/buildroot/output/host/usr/bin/mipsel-linux-sstrip usr/sbin/br2684ctl
$ /usr/src/wag54g/buildroot/output/host/usr/bin/mipsel-linux-sstrip usr/lib/libatm.so.1.0.0
$ ln -s libatm.so.1.0.0 usr/lib/libatm.so
$ ln -s libatm.so.1.0.0 usr/lib/libatm.so.1

ADSL2+

Interesting Links

 
wag54g.txt · Last modified: 2012/03/17 17:16 by alex
 
Except where otherwise noted, content on this wiki is licensed under the following license:Public Domain
Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Run by Debian Driven by DokuWiki