Category Archives: Wireless

An upgrade to Ubiquiti

I’ve been _extremely_ impressed with the quality of Engenius‘ products, most specifically the EOC-2610. For the 2 years that I’ve had my two units in service, I’ve had very little issue with them.

Recently my workplace ordered a batch of Ubiquiti products from DoubleRadius. Ubiquiti is loved by the WISP world, and (mostly) utilize Atheros boards – just as the Engenius products do. Both also have stock firmware that’s also based off OpenWRT. Being inspired, I purchased some equipment myself.

Part of the reason the Ubiquiti gear seems to be more popular is their excellent support and web forum. Engenius is notoriously difficult to get any answers out of. I’ve still yet to get a copy of their firmware source required by the GPL, and I gave up long ago trying to get anywhere. Luckily, the few questions I did have were answered by simply expirementing.

This weekend I began the migration to Ubiquiti. My first rollout involves a Rocket M2 and a 120 degree sector antenna. For the past few weeks I’ve been working on adding a more recent version of the excellent CoovaChilli to the device. I have located a version of the CoovaAP firmware that runs natively on a Rocket M2, however it lacked a number of features (non-Chilli related) that I was hoping for. After much searching, I’ve been able to locate a 5.3 SDK (which features AirControl and the built-in spectrum analyzer).

AirView
The AirView built in spectrum analyzer

As I mentioned, it took quite a bit of searching to obtain the SDK. According to Kevin Perry at Ubiquiti  “We’ve had to temporarily remove the SDKs from our site to comply with US export control regulations. Once approved, we will be able to continue providing SDKs. ”  I’ve not heard anything new, and that correspondence is from September of 2011.

Of course, the Internet is a not only a compendium of 140-word-or-less Tweets about what someone just ate for dinner, it’s also a giant archive of the past. And with a bit of searching, I came across the SDK still hosted (albeit hidden) on Ubiquiti’s site.

Unfortunately the latest SDK is 5.5, and not 5.3. I’ve not had luck locating it (and it does contain the patch for the SkyNet worm), so I’m working off 5.3 for the time being. I’ve locked down access to the web interface to prevent infection from the worm.

CoovaLogo2_0
The CoovaChilli Captive Portal

With the SDK in tow, I began the work of inserting CoovaChilli into the system. Ubiquiti ensures important services stay running by having them spawned (and respawned if needed) via inittab. The stock inittab on the system is basic, handling only login and a couple of runlevel items. Prior to /sbin/init starting, the system runs a bash script /init. This in turn handles filesystem mounts, makes a handful of device nodes, copies a number of files into place, partially configures sysinit, and sets the timezone. It also calls ubntconf which gleans information from the nvram variables, prior to executing the traditional /sbin/init.

ubntconf is a closed source application, although it’s pretty easy to glean most of it’s operations by simply running strings on it (It is an ELF not a script). Depending upon nvram variables that are set, different scripts are dropped into /etc/sysinit. Additionally, items are added to /etc/inittab like this:

null::respawn:/bin/pppd eth0
null::respawn:/bin/lighttpd -D -f /etc/lighttpd.conf
null::respawn:/bin/dropbear -F -d /etc/persistent/dropbear_dss_host_key -r /etc/
persistent/dropbear_rsa_host_key -p 22

Each of these entries will respawn the corresponding service should it crash. Using their system as a model, I created my own config creator “chilliconf” to add entries to inittab for the chilli daemon, in addition to the necessary iptables rules in /etc/sysinit, and a few modifications to their use of dnsmasq (I wanted to syslog DNS queries offsite). When I later added NProbe to my firmware, I also used my chilliconf configurator to add it to the inittab.

My chilliconf configurator, like ubntconf, is called from the /init script.

One thing of note – any daemon listed in the inittab file needs to actually run in the foreground (so calling the process a daemon isn’t entirely accurate). This is for the obvious reason that the initiating process fork()s then exits – so inittab will continually respawn the service until you run out of resources.

No Strings Attached
All original functionality is still there. It's a like a cyborg version of itself.

I used the 3.6SDK version of CoovaAP as a model for my web interface. Adding a tab was fairly easy – the web interface is maintained as the ubnt-web package in the SDK. Most of the web CGI is PHP/FI (with a couple of functions added to PHP to facilitate saving configs and reading values). The code is extremely readable, and easy to figure out.

When you save your settings in the Ubiquiti web interface, you’re presented with a blue message bar asking if you’d like to test or apply your settings. In either case, you’ll be disconnected for a moment while the system reconfigures itself. This appears to be done via a call to the original /init script. The blue bar is a bit of a problem when adding a new tab to the menu.

The background image for the blue bar (msg.png) is originally  745 pixels, and the screen width is set to 790 pixels. With an added tab, the screen width becomes 866 pixels. Using GIMP I resized this image to 821 pixels.

The Blue Message Menu
Resize the blue background to fit.
  • Originally it was 745, with the original screen width of 790.
    • 790-745 = 45.
    • 866-45 = 821 — our newly resized image.

The web interface went through a few iterations before I had all the options I presently needed. CoovaChilli’s dnsdomainlocal option is problematic – causing any DNS query that returns an NXDOMAIN error for an A record to cause a redirect to the portal. Unfortunately the portal (from my experience) doesn’t properly track in this instance if the MAC associated with the request is authenticated – and redirects the user back to the UAMSERVER with the “res=notyet” variable. This means the user is prompted with a login screen unnecessarily.

In other words, visit “adfasjzc9vdsa0f9jdsaf.com”, and you’re presented with a login screen even after you’re logged in.  Adding the option to disable dnsdomainlocal fixes this problem.

The CoovaChilli Tab
The CoovaChili tab (with NProbe)

By default, I have the “dhcpradius” option enabled. With this feature, when a DHCP request is received by the CoovaChilli server, it forwards the MAC address to the radius server (as both the username and password) for authentication. If it doesn’t authenticate, the system redirects the user back to the UAMServer for a captive portal login.

The North Facing Access Point
Broadcasting throught the stratosphere

For the time being, the system is a bit overkill, but the options it presents for the future are many. CoovaChilli can rate-limit individual users based on login or MAC address. This alone opens the door for a pay-for-bandwidth model. If a user is found to be filesharing (legal or not) or otherwise consuming an inordinate amount of bandwidth, they can be easily ratelimited.

I still have a few minor items to add to the firmware (including the ability to pull RSSI information per client), but in the meantime it’s been fun working with the Rocket M2. The access point is now being tested in the neighborhood.

Midtown Wifi – the internals.

In the next few days, I’ll be upgrading my north facing access point from Engenius to Ubiquiti. The firmware is already written, and I have most everything prepped for the rooftop mount. Before I post about working with the (hidden) Ubiquiti 5.3 SDK, I thought I’d give a quick tour of my system so far.

With Midtown Wifi I had the following goals:

  1. Work more in the C language.
  2. Build a stable and (mostly) embedded captive portal system with a minimal ToS acceptance screen.
  3. Let the surrounding neighborhood use the Internet for free in exchange for helping me build and test the system.
  4. Use the system as a way to introduce neighbors, let them post local interest items (missing pets, crime reports, events, etc).
  5. Provide maps of recently reported crimes via the Harrisburg, PA online Police Blotter.

Over the years I’ve accomplished all of this, to one degree or another. Harrisburg, PA is in the midst of some serious financial problems, so their online police blotter has gone away  – preventing me from easily obtaining local crime information. People are what they are, and as Google+, MySpace, and any other Social Site knows — getting people to truly use your social portal is a trick that requires sheer genius. Getting them to log into it and push a “Free Wifi” button however, is easy.

MidtownWifiLogin
The Midtown Wifi Login Screen (as of Feb 15, 2012)

How it works:

After connecting to one of the open access points, the end user is redirected (courtesy of a patched NoDogSplash) to a captive web portal. The web portal is based off Elgg, a fairly easy to use Social Network Engine written in PHP. I’ve made a few modifications to the base system, adding a more recent JQuery and JQueryUI (so that I can create interactive Dialogs), and writing a few plugins to handle Netflow display, wireless signal strength reports (per user), user speed tests, and to verify that they have a picture set before allowing them to use the Free Wifi.

By nature, people won’t set a profile picture when all they want is Free Wifi. I had to enforce a profile picture (“it doesn’t have to be you, it can be anything non-offensive”) to make the site NOT appear like a barren wasteland.

I eventually limited account creation strictly to the access points as registrations from outside those IPs were mostly just spam.

After a user creates an account and logs in, they are directed to the “Dashboard”, which is a listing of recent posts from any of the users. Most are quick “Hey you!”, but sometimes people post something more substantive. When my rear car window was broken, I used the system as a venting forum.

MidtownWifiDashboard
All the names and 1 dirty word have been removed.

I’ve consolidated most of my customizations relative to the wireless users into a single Elgg plugin I named “TSA Patdown”. Initially TSA Patdown only verified that a user had a profile image set, but now it does quite a bit more. Every 30 seconds I export Received Signal Strength Indication (RSSI) for each client from the  Engenius equipment. I collect this information, as well as information from a Javascript based speedtest widget I wrote to get an idea as to what kind of online experience each user is having.

I represent this information to myself on the following menu, with signal bars that I created using Blender:

MidtownWifiLogins
Signal Strengths, Login times, MAC addresses and more.

I can further delve into information on a per-user basis by simply clicking on a name. I can also pull a full neighborhood report, graphing each clients RSSI values as well as their recent speedtest results.

MidtownWifiSpeedTest
The Javascript Speedtest Widget

Being implemented in Javascript, the speedtest results aren’t the same as you’d see when visiting a Flash based speedtest. The standard web method of performing such a test is to have the end-user download an image file or two (oftentimes two images simultaneously)- and at random intervals determine how much of the image has been downloaded by that timeframe.  With a single image download, it can perform multiple measurements at various intervals and determine available bandwidth much more accurately. Since there’s additional overhead in the underlying TCP/IP layers, it appears most tests also add padding to their calculation to make things more accurate.

Speakeasy
Speakeasy Flash based speedtest

Flash has methods that will allow for such periodic sampling, Javascript however does not. This makes my Javascript implementation an overall average – so a report of 900Kbit/sec can easily represent 1.5Mbit/sec. (My results are much more akin to what Wireshark will report as throughput). I do plan to write a Flash based speedtest in the near future.

WiresharkThroughput
Wireshark measures throughput how I do: Bandwidth / (endtime - starttime)

In this example, the capture in Wireshark measures the throughput as 21.22Mbit/sec, nowhere near the 52.37Mbit/sec rating given by Speakeasy. The recent throughput information is all displayed in the signal screen:

MidtownWifiSignals
Can you hear me now? How fast can I talk?

The Netflow section of my TSA Patdown plugin details the current traffic flow on the network. This screen updates dynamically as users surf the internet. (I’ll reiterate my past posts here: The netflow data is only packet endpoints… basically “this person called this person at this time”, but not the actual content of those conversations). I’ve also added a small port-based protocol disector that colorizes the flows and provides protocol information depending upon the packet you select. If you choose a NetBIOS packet, you’ll get something similar to this:

MidtownWifiNetFlow
Flying by at the speed of light: PACKETS

The system monitors for NetBIOS names as well as DHCP hostnames that appear on Midtown Wifi. All of this information comes together to paint an accurate view of the network.

Clicking a Protocol Name (in this instance NetBIOS) will direct you to a Wikipedia article on the protocol and how it works. Unclassified protocols can be classified and colorized with a simple click. You can also specify the URL to load when the protocol name is clicked.

MidtownWifiProtocolAssignment
Pick a transport, a color, a name, a URL - and you've defined a protocol

The pie charts, RSSI graphs, and throughput graphs are all handled using the PHP JPGraph libraries. In the future, I intend to improve the graphs (there are tendencies for my labels to bleed off-screen or over each other).

The access points share their own ADSL line for bandwidth but maintain individual PPPoE sessions. The wiring in my home needs improvement (the house was built in the 1800’s, the Cat5 running through the house is obviously not that old but does have some serious issues) . Most of the exterior walls appear to be metal, which does hinder re-running the DSL line a bit.

I recently migrated my home network graphing from NetMRG to Cacti, and I’m using Cacti‘s (albeit poor) FTP export function to offload graphs pertaining to MidTown Wifi to the captive portal.

MidtownWifiGraphs
Graphs that have been imported from Cacti.

As you can see in the graphs, the system currently has 175 subscribers. I have deleted the bogus accounts that weren’t created through the APs. The high number of subscribers is largely the result of transient users (my home is on a major bus line, rental homes in the area turn over somewhat frequently, the local college is blocks away,  etc). A couple of users have duplicate accounts having apparently lost their credentials (as is evidenced by a few repeat MAC addresses).

To put the large number into proper perspective:  in the last 7 days there were 157 logins by 18 unique users. Unlike myself, most of the users don’t spend every waking moment on the Internet.

I’ve covered the access points and the firmware images in a number of previous posts, so I’ll let them speak for themselves. In the next few days (hopefully not weeks), I’ll be introducing my first Ubiquiti access point to the system with full details posted then. If you have any thoughts or input, by all means reach me in the comments section.

 

OpenWRT on the MikroTik RouterBoard 493AH

I recently came across a MikroTik RouterBoard 493AH at work. We’d acquired the device among numerous other pieces of equipment from a now defunct wireless ISP.

It smells of Goo-Gone and looks to have dandruff.

The 493AH features 9 ethernet ports, can accept POE on its WAN interface, has 64M NAND,  128M RAM, and can support 3 mini-PCI cards. Configuration can be performed via a serial interface and there is an external power connector available if POE isn’t used.

The device itself wouldn’t boot, only hang at the RouterBoot bootloader. Attempts to boot the NAND image failed, but the bootloader gives an easy option for downloading an image to it via TFTP.

MikroTik Logo
A brand that's loved by WISPs

Looking around, it appears the 493AH is an Atheros AR7161 .. an architecture readily supported under OpenWRT. Sure, I could just re-install RouterOS… but let’s do that later.

To install OpenWRT to the 493AH, first format the NAND. This can easily be done via the bootloader (option e):

FormatNAND
Waxing the memory

Next, use subversion to check out the Backfire version of OpenWRT:

mkdir ~/svn/

cd ~/svn/

svn co svn://svn.openwrt.org/openwrt/branches/backfire backfire

Building the image is fairly easy, all configuration is done via a “make menuconfig“. First, we’ll build a small initramfs. This will give us a tiny environment to boot into the device and later install our kernel with.

Ensure that you’ve selected the AR71xx target architecture…

Building an AR71XX System

Next, I opt for the default profile (to give me all the modules I should need)

TargetProfileSelection
I demand everything!

And finally, select the build of a ramdisk image:

BuildRamDisk
Fun with arrow keys and a spacebar.

After you’ve made your selections, exit saving your changes, and run make. The build itself will take some time, but when you’re finished you’ll have the first key ingredient – a basic root filesystem embedded into the kernel. This image is essentially a “Live CD” that we’ll use to install our real kernel.

As with all of the images you create, you’ll find them under ~/svn/backfire/bin/ar71xx/ Our newly created image is openwrt-ar71xx-vmlinux-initramfs.elf

Next, we’ll want to build our actual system. To do this, re-run make menuconfig and select the packages that you wish to compile and include in your firmware image. After you’ve made all of your selections, change your Target Image to squashfs and exit saving your changes.

SquashFSBuild
Planting a SquashFS Garden

A quick make later, and we now have a working rootfs and kernel – in addition to our initramfs to install the system with:

openwrt-ar71xx-vmlinux-initramfs.elf (Our temporary kernel)
openwrt-ar71xx-vmlinux.elf (The kernel)
openwrt-ar71xx-root.squashfs (Our Root Filesystem)

We now have almost everything we need.

Oh, the sticker says "Warranty Void if Removed"...

To install our kernel, we need a few additional tools. First off, we need to configure a DHCP server (I’m using ISC’s). Here’s an example from my dhcpd.conf file:

authoritative;
ddns-update-style interim;
subnet 192.168.1.0 netmask 255.255.255.0 {
range 192.168.1.20 192.168.1.40;
option subnet-mask 255.255.255.0;
option routers 192.168.1.1;
}

host routerboard
{
hardware ethernet 00:0c:xx:xx:xx:xx;
fixed-address 192.168.1.17;
}

 

Next, we’ll need a TFTP server. I prefer atftpd. No configuration is necessary, simply create a directory to serve files from and start the server:

mkdir /tftpboot/

chmod 777 /tftpboot/

atftpd ––daemon /tftpboot/

The only file that has to be loaded via TFTP is the initramfs kernel. Copy it to /tftpboot with the filename vmlinux and we’re ready to start.

cp ~/svn/backfire/bin/ar71xx/openwrt-ar71xx-vmlinux-initramfs.elf  /tftpboot/vmlinux

Power up the RouterBoard and quickly press the space bar. Select “boot over Ethernet” and it will download and boot the linux kernel.

BootEthernet
Opting to boot via TFTP

Next ,we need to install the kernel and root filesystem. Here’s where I ran into my first problem – the kernel has no init variable specified so it panics. Thankfully it clearly states this: “Kernel panic – not syncing: No init found.  Try passing init= option to kernel.

KernelPanic
Gratitous Image of a Kernel Panic

Unfortunately the boot loader doesn’t appear to allow one to specify command line options for the kernel and I was unable to find a way to set this when configuring the kernel. (I vaguely recall seeing it when compiling for x86, but may be mistaken). Either way, the solution is simple:

Add your kernel parameters to a file (kernel-params in my instance) and use objcopy to insert it into the ELF file:

The options I used are:

root=/dev/mtdblock2 rootfstype=squashfs,yaffs,jffs2 noinitrd console=ttyS0,115200 init=/etc/preinit

The toolchain supplied with OpenWRT contains a MIPs compatible version of objcopy that will allow you to add a kernel parameters section to the ELF file:

cd ~/svn/bin/ar71xx/

~/svn/backfire/build_dir/toolchain-mips_r2_gcc-4.3.3+cs_uClibc-0.9.30.1/binutils-2.19.1/binutils/objcopy ––add-section kernparm=kernel-params openwrt-ar71xx-vmlinux.elf

To install the kernel, configure an IP on your ethernet  (or bridge) interface, mount /dev/mtdblock1 and use scp to copy your kernel to the device (as “kernel”).

ifconfig br-lan 192.168.1.10

mkdir /mnt/boot

mount /dev/mtdblock1 /mnt/boot

cd /mnt/boot/

scp 192.168.1.1:~/svn/backfire/bin/ar71xx/openwrt-ar71xx-vmlinux.elf kernel

 

Next, install your squashfs root filesystem to /dev/mtdblock2. Unlike the kernel, This shouldn’t be mounted when installed.

cd /tmp/

scp 192.168.1.1:~/svn/backfire/bin/ar71xx/openwrt-ar71xx-root.squashfs .

cat openwrt-ar71xx-root.squashfs > /dev/mtdblock2

After the root filesystem is installed, reboot the device and welcome to OpenWRT on the RouterBoard 493AH

ItBoots
It's Alive!

I’m not quite sure what I’ll end up doing with the 493AH just yet. The neighborhood wireless system now consists of 2 Engenius EOC2610 units running firmware images based off OpenWRT… so there may be the potential to add it to the fray.  The 9 ethernet ports would make it ideal for a Quagga router (although I already have one). Installing the MikroTik RouterOS and working with MPLS is another options. Right now it sits on my desk at work as a “pretty cool paperweight with a lot of potential”.

If you have any suggestions – please let me know.

Engenius EOC-2610 and OpenWRT: Getting Started

I’m looking forward to the upcoming CPLUG presentation: “Unleash your home router’s potential“. As 48 users will now attest, the captive portal I’ve been building has been a pretty big success.

Numerous attempts to fix the EOC-2610 reboot bug have all been in vain. The problem is this: the device reboots fine until the wireless modules are inserted AND the device placed into Master mode (to serve as an access-point). Removing the modules, using GPIO pin 0 instead of 5 to reset, pointing things back to the bootloader at either address 0xbfc00000 or 0xa8000000, and numerous other tests all fail. I cannot seem to locate the source that Engenius uses (which would help in finding the solution), and neither Engenius nor Senao will respond back to emails or Facebook posts. (I’ve spoken to Engenius reps in California that have pointed me to Singapore – I’ve been on hold for almost an hour there to no avail).

Serial Connection or Brain Surgery. Can't see it well enough to say.

But enough complaining, I’ll fix that bug eventually.

Update 8/10/2010: A coworker suggested double-checking voltage and direction on GPIO pin 0, as well as ensuring that AR2315_RESET_GPIO was set correctly this morning. Sure enough, I had a problem. I’ll release a very basic patch shortly. -=Bug squashed=-

Here’s the lowdown on how to build a basic linux kernel and rootfilesystem using OpenWRT and how to install your new firmware via the Redboot bootloader. I’m posting it as a quick introduction.

First off, use subversion to grab the appropriate source. In this instance, I’m using the BackFire port:

svn co svn://svn.openwrt.org/openwrt/branches/backfire

This contains everything you need to get started: toolchain, compiler,  and scripts to pull in the source for the kernel and all packages that will be built. OpenWRT is very well documented, and it’s worth the time to read the README file as well to build and read the contents of the docs/ directory.

Menuconfig is used to determine not only kernel options, but packages that will be built as part of the firmware image.

cd backfire
make menuconfig

Obviously the first thing you want to do is set the appropriate Target System. For the Engenius EOC-2610, you’ll want to use Atheros AR2315:

Menuconfig: Selecting your Target

Next, ensure you select squashfs for the Root filesystem image (under Target Image). Target Profile will only have one option (Default), so no changes are needed there. I generally use the default Global build settings (as they’re ample), but look them over if you want more advanced debugging options and to enable things like IPv6, etc.

The Image Builder option is to allow creation of a firmware image using precompiled binaries. I generally leave this and the other Main build options off..

Base system is exactly as it sounds: it’s a list of base utilities like dropbear, bridging utilities, iptables, mtd, and other items. In fact, all of the remaining options are fairly self-explanatory: Network, Libraries, Kernel Modules – they all mean what they say. If you can’t find an option, use “/” and search for it. Luckily a working firmware (that incorporates wireless) can be built with simply selecting the correct target (Atheros AR2315). You can add more features later.

When you’re ready to roll, a simple make V=99 will cause the OpenWRT system to download all the appropriate tools, compile them, and build your firmware. Obviously the first time you build an image, it will take some time. Subsequent builds focus solely on the kernel and root filesystem, not building the entire toolchain. The images are found under the bin/ directory.

For Future Reference: The Serial Pinouts

Now that you have an image, one has to use the Redboot bootloader to upload it. There’s excellent documentation out there on this as well, but here’s a quick rundown:

Use a crossover cable to connect to the Engenius EOC2610’s Ethernet port. The bootloader defaults to using 192.168.1.1, so configure your IP accordingly (for this example, I’m using 192.168.1.2).

In one terminal, start pinging 192.168.1.1. Plug in the PoE adapter to start the 2610 and upon receiving an ICMP response, telnet to 192.168.1.1, port 9000. (Since you need to send a Ctrl-C to the Redboot bootloader, I have found that using puttytel seems to be the preferred method to connect to it). You may find a blank screen that doesn’t respond – if you do quickly disconnect and reconnect to the device.

The first time you'll lay eyes on Redboot.

When you see the above screen (and have hit Ctrl-C), you’re ready to go.

Ensure that you have a TFTP server on your local machine and that the kernel (openwrt-atheros-vmlinux.lzma) and rootfs (openwrt-atheros-root.squashfs) are in the TFTP root location. Next, configure the bootloader to use your system as a TFTP server (and ensure that it can connect to you):

RedBoot>
RedBoot> ip_address -l 192.168.1.1 -h 192.168.1.2
IP: 192.168.1.1/255.255.255.0, Gateway: 0.0.0.0
Default server: 192.168.1.2
RedBoot> ping -h 192.168.1.2
Network PING – from 192.168.1.1 to 192.168.1.2
PING – received 10 of 10 expected
RedBoot>

Uploading the kernel is easy:

RedBoot> load -r -v -b %{FREEMEMLO} openwrt-atheros-vmlinux.lzma -m tftp
Raw file loaded 0x80041000-0x80110fff, assumed entry at 0x80041000
RedBoot>

Ensure that everything was uploaded ok and that the checksums match:

RedBoot>
RedBoot> cksum
Computing cksum for area 0x80041000-0x80111000
POSIX cksum = 472679704 851968 (0x1c2c8518 0x000d0000)
RedBoot>

me@vonnegut/tftpboot $ cksum openwrt-atheros-vmlinux.lzma
472679704 851968 openwrt-atheros-vmlinux.lzma

If all is well, format the flash and burn the kernel image:

RedBoot> fis init
About to initialize [format] FLASH image system – continue (y/n)? y
*** Initialize FLASH Image System
… Erase from 0xa87e0000-0xa87f0000: .
… Program from 0x80ff0000-0x81000000 at 0xa87e0000:

RedBoot> fis list
Name              FLASH addr  Mem addr    Length      Entry point
RedBoot           0xA8000000  0xA8000000  0x00030000  0x00000000
FIS directory     0xA87E0000  0xA87E0000  0x0000F000  0x00000000
RedBoot config    0xA87EF000  0xA87EF000  0x00001000  0x00000000
RedBoot> fis create -r 0x80041000 -e 0x80041000 vmlinux.bin.l7
… Erase from 0xa8030000-0xa8100000: ………….
… Program from 0x80041000-0x80111000 at 0xa8030000: ………….
… Erase from 0xa87e0000-0xa87f0000: .
… Program from 0x80ff0000-0x81000000 at 0xa87e0000: .
RedBoot>

You can then verify that the kernel is saved to flash:

RedBoot> fis list
Name              FLASH addr  Mem addr    Length      Entry point
RedBoot           0xA8000000  0xA8000000  0x00030000  0x00000000
vmlinux.bin.l7    0xA8030000  0x80041000  0x000D0000  0x80041000
FIS directory     0xA87E0000  0xA87E0000  0x0000F000  0x00000000
RedBoot config    0xA87EF000  0xA87EF000  0x00001000  0x00000000
RedBoot>

Excellent – it is. Next up – the rootfilesystem. It’s loaded into memory via the TFTP  server in the same fashion as the kernel (again, run a checksum to ensure all transferred fine):

RedBoot> load -r -v -b %{FREEMEMLO} openwrt-atheros-root.squashfs -m tftp
Raw file loaded 0x80041000-0x801a0fff, assumed entry at 0x80041000
RedBoot>

RedBoot> cksum
Computing cksum for area 0x80041000-0x801a1000
POSIX cksum = 3009821226 1441792 (0xb3663a2a 0x00160000)
RedBoot>

me@vonnegut/tftpboot $ cksum openwrt-atheros-root.squashfs
3009821226 1441792 openwrt-atheros-root.squashfs

Next, determine how much space is actually free in FLASH. It helps to use bc to calculate this:

RedBoot> fis free
0xA8100000 .. 0xA87E0000
RedBoot>

bc 1.06.95
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty’.
iscale=16
oscale=16
A87E0000-A8100000
690000

With this information at hand, you can burn in the Root Filesystem, utilizing all the free space:

RedBoot> fis create -l 0x690000 rootfs
… Erase from 0xa8100000-0xa8790000: ……………………………………………………………………………………………
… Program from 0x80041000-0x801a1000 at 0xa8100000: ………………….
… Erase from 0xa87e0000-0xa87f0000: .
… Program from 0x80ff0000-0x81000000 at 0xa87e0000: .
RedBoot>

That’s it – you’ve now uploaded your firmware to the device. Next, lets just double-check and ensure all is well, and finally – let’s boot our new image:

RedBoot>
RedBoot> fis list
Name              FLASH addr  Mem addr    Length      Entry point
RedBoot           0xA8000000  0xA8000000  0x00030000  0x00000000
vmlinux.bin.l7    0xA8030000  0x80041000  0x000D0000  0x80041000
rootfs            0xA8100000  0x80041000  0x00690000  0x80041000
FIS directory     0xA87E0000  0xA87E0000  0x0000F000  0x00000000
RedBoot config    0xA87EF000  0xA87EF000  0x00001000  0x00000000
RedBoot>
RedBoot> fis load -l vmlinux.bin.l7
Image loaded from 0x80041000-0x802a0200
RedBoot> exec

At this point, detach from the telnet session (no output will be seen when the device boots), and once the system has booted – connect using telnet (or SSH if compiled).

The OpenWRT Busybox shell

Next up – customize your firmware image and build your own packages  – and check out the upcoming CPLUG meeting on unleashing your home routers potential.