Instructions for building TomatoUSB Toastman RT-N firmwares

Back in September/October I had the “pleasure” of dealing with trying to build TomatoUSB (specifically Toastman’s RT-N releases) on a Linux system I have (thank god for VMware Workstation!). I was given all sorts of reference materials from folks on the linksysinfo.org forum, except I kept running into all sorts of problems. I tried other Linux distributions, other releases of the same distribution, etc. and the failures all seemed to differ.

I figured it would be worthwhile to document exactly how I got the firmware to build and what the necessary steps are as of the date of this blog post.

Prerequisites:

  1. Linux system running a 32-bit (i386/x86) kernel. I was not able to get 64-bit (amd64/x64) working (details in a moment). Distributions I can confirm work are Ubuntu 11.04 i386, Ubuntu 11.10 i386, Debian 6.0.6 i386, Debian 6.0.7 i386, and Debian 7.1 i386.
    • Reason: the toolchain binaries stored in the official git repository were built on a Linux 2.6.8 32-bit system
    • The failure message you’ll receive if using a 64-bit system is something like mipsel-linux-uclibc-gcc: No such file or directory. The message is misleading to anyone not highly technical and familiar with multiple architectures; I imagine most users would have great difficult figuring this one out. This is not a library-related problem; this is the kernel or ELF loader not having support for 32-bit binaries (I did not care to figure out which)
    • The proper way to solve this is to rebuild the toolchain from source, except I cannot find any documentation stating how to do that correctly
  2. Around 20GBytes of disk space (really!), which should suffice for the Linux/base install and all of TomatoUSB
  3. Root-level access. This is needed because symlinks need to made within the /opt directory
  4. sudo must be installed in advance (the build system uses it)

Step-by-step instructions are below. Please note that these must be done as a user, and not as root! Building the firmware as root is not supported!

sudo apt-get install libncurses5 libncurses5-dev bison flex libstdc++6-4.4-dev
sudo apt-get install m4 g++-4.4 g++ libtool sqlite gcc binutils patch
sudo apt-get install bzip2 make gettext unzip zlib1g-dev libc6 gperf
sudo apt-get install automake automake1.7 automake1.9 git-core

(Note: For Debian 7.1, there is no automake1.7 package; it's not needed there)

cd ~
git clone git://repo.or.cz/tomato.git
cp -pR tomato tomato.orig

sudo mkdir -m 0755 -p /opt
sudo ln -s ~/tomato/tools/brcm /opt/brcm

cd tomato
git checkout Toastman-RT-N

export PATH="$PATH:/opt/brcm/hndtools-mipsel-linux/bin:/opt/brcm/hndtools-mipsel-uclibc/bin"

cd release/src-rt

make V1={versionstring1} V2={versionstring2} {buildtype}

Please note during the build you will see quite a large number of Makefile errors which are ignored (e.g. “Error 1 (ignored)”), and an even larger number of warnings during compiling. It absolutely blows my mind that something as critical as an embedded firmware is maintained in such a sloppy manner; I am one of those coders who uses -Wall -Werror and for a damn good reason.

If the compile completes successfully, you’ll end up with a firmware in the release/src-rt/image directory.

Now for some explanation of what the {versionstringX} and {buildtype} placeholders are:

The two {versionstringX} placeholders can be anything you want; they’re used to create the actual firmware filename. For example, to make an “official-looking” Toastman firmware file called:

tomato-K26USB-1.28.0500.5MIPSR2Toastman-RT-N-Ext.trx

…you would do:

make V1=0500.5 V2=Toastman-RT-N r2m

{buildtype} is rather lengthy. Rather than explain all the possibilities here, it’s a lot easier to just direct you to run make help in the release/src-rt directory and read the results for yourself. But just for posterity, here’s the list as of this writing:

a            A build (standard)
b            B build (standard minus SSH)
c            C build (standard minus CIFS)
d            D build (standard minus Samba server)
m            M build (standard plus extra utilities and NTFS support)
nc           NC build (standard plus VPN, extra utilities, NTFS support and NOCAT)
ncm          NCS build (no USB support, NOCAT)
ncs          NCS build (std + NOCAT)
m            Ext - (standard plus extra utilities and NTFS support)
e            E build (standard plus VPN, extra utilities and NTFS support)
i            I build (IPv6 with no USB support minus CIFS and RIPv1/2)
s            S build (no USB support)
f            F build (no USB support minus CIFS and RIPv1/2)
fs           FS build (no USB support minus CIFS, JFFS, Zebra and RIPv1/2)
v            V build (VPN with no USB support)
vs           VS build (Small VPN with no USB support)
r2a          MIPS Release 2 A build (standard)
r2b          MIPS Release 2 B build (standard minus SSH)
r2c          MIPS Release 2 C build (standard minus CIFS)
r2d          MIPS Release 2 D build (standard minus Samba server)
r2e          MIPS Release 2 E build (standard plus VPN and extras)
r2f          MIPS Release 2 F build (no USB support minus CIFS, RIPv1/2)
r2fs         MIPS Release 2 FS build (no USB support minus JFFS, CIFS, RIPv1/2, Zebra)
r2i          MIPS Release 2 I build (IPv6 with no USB support minus CIFS and RIPv1/2)
r2m          MIPS Release 2 M build (standard plus extras)
r2nc         MIPS Release 2 NC build (standard plus VPN, extras and NOCAT)
r2ncm        MIPS Release 2 NCM build (no USB support, plus NOCAT)
r2ncs        MIPS Release 2 NCS build (standard plus NOCAT)
r2s          MIPS Release 2 S build (no USB support)
r2t          MIPS Release 2 T build (no USB support with extras)
r2u          MIPS Release 2 U build (no USB support plus VPN with extras)
r2v          MIPS Release 2 V build (VPN with no USB support)
r2vs         MIPS Release 2 VS build (Small VPN with no USB support)
       Linksys E-Series with 60k Nvram
n60m         Linksys E-series build (60KB NVRAM, standard plus extras)
n60e         Linksys E-series build (60KB NVRAM, standard plus VPN and extras)
n60nc        Linksys E-series build (60KB NVRAM, standard plus extras, plus VPN, plus NOCAT)
n60s         Linksys E-series build (60KB NVRAM, no USB support)
n60v         Linksys E-series build (60KB NVRAM, VPN with no USB support)
       Linksys E-Series with 64k Nvram/8MB Flash(E900/E1200v2/E1500)
n64m         Linksys E-series build (64KB NVRAM, standard plus extras)
n64e         Linksys E-series build (64KB NVRAM, standard plus VPN and extras)
n64nc        Linksys E-series build (64KB NVRAM, standard plus extras, plus VPN, plus NOCAT)
n64s         Linksys E-series build (64KB NVRAM, no USB support)
n64v         Linksys E-series build (64KB NVRAM, VPN with no USB support)
       Linksys E-Series with 4MB Flash(E1000v2/v2.1/E1200v1)
e1000v2i     Linksys E1000v2-v2.1/Cisco M10v2 MiniIPv6
e1000v2f     Linksys E1000v2-v2.1/Cisco M10v2 Mini
e1200v1i     Linksys E1200v1 MiniIPv6
e1200v1f     Linksys E1200v1 Mini
       Netgear WNR3500L v2 builds (128MB Flash)
v2e          Netgear WNR3500Lv2 build

If you wish to adjust Linux 2.6 kernel features, you will need to edit release/src-rt/linux/linux-2.6/config_base manually. Do not use make menuconfig! There are known adjustments applied manually during the build stage that may break if you do that.

If you want to add/remove features from netfilter (related to iptables), you will need to edit release/src/router/iptables/extensions/Makefile manually.

Here’s an example where both of these files needed to be edited to add support for the IPv4-only xt_string.ko module (iptables -m string support).

I hope this helps folks in some way/shape/form, as I found the entire process to be quite badly documented in general.