An introduction to OpenWrt - Background - As all of my friends know, I'm one of those people that runs Linux on everything; I've got several computers running Linux, I've got two tivos running Linux and I've even installed Linux on a few pdas. If there's a way to load Linux onto the device, chances are I've tried it. So, it should come as very litte surprise that as soon as rumor spread about a wireless router runing linux, I had to go out and buy it. The router worked as advertised, but you'd never know the device was running linux; everything was controlled via a web page with a madlibs approach to administration. In other words, to do anything you just had to find the appropriate box on the web page and fill in a value. While that's fine if there's a box for what you want to do, it really makes it difficult to use -- what if I need to setup port forwarding for more than 10 ports? there's only 10 boxes for port forwarding. Fortunately, there was a way into the Linux system. No, not something obvious like a telnet or ssh session, you literally had to hack your way to the command line. One of the features of the administration web page is to use ping as a means of network diagnostics, you just type in an address and the web page starts the ping command. What was interesting was what happened if you didn't type in an address -- as you may have already guessed by now, all the web page was doing was taking the address entered and inserting it right onto the ping commandline; there was almost nothing in the way of validation, so you could run pretty much any arbitrary command. This simple flaw sparked off a small revolution. It started simply enough, you'd type in the command and the output would appear on the web page as the ping results. The problem was that there just weren't that many commands you could run; the firmware was designed to be controlled via the web page. A few enterprising individuals figured out a way to upload files into RAM, allowing the installation of a telnet server and several common utilities, but even that had flaws. The main flaw with using RAM was that if the router was ever unplugged or rebooted everything in RAM would be lost and the way the firmware applied changes from the web page was to simply store the new configuration and reboot the device. The only really useful thing that you could do with the ping trick was to set a variable called 'boot_wait'; once set you could upload firmwares as the device was booting, without being forced to use the firmware upgrade mechanism on the web page. This meant that you could suddenly update the firmware with impunity, if the firmware failed you simply uploaded another one. It was at this time that the 3rd party firmwares started to spring up. They started with the normal firmware, added a few applications and made a new web page and called it a new firmware. There were literally dozens of these one-off firmwares, most of them didn't do any drastic changes simply because they would just have to repeat their changes all over again to keep up with the latest official firmware releases. - Enter OpenWrt - OpenWrt really started with two specific goals: The first goal was to turn the device into a Linux machine. Admittedly the device was already running Linux, but you'd hardly know that; I wanted it to actually feel like a Linux machine, accepting all the commands one would expect to find on a Linux machine. OpenWrt was designed to resemble a Linux distribution. The second goal was to make the system as open and flexable as possible. I didn't want to have to run over to another machine and recompile every time I wanted to make a change to the firmware; I wanted to have complete control over the router directly from the device. The first thing that I did was strip the firmware down to the bare essentials. This was done both to reduce the size of the firmware and because many of the applications that made up the default firmware were full of bugs. The bug in the ping command still exists to this day and the ntp client they wrote would set the time to UTC and then calculate the correct timezone offset and reset the clock to the correct time -- the authors were apparently completely unaware of the fact the C library already provides various timezone functions. To understand the second goal of creating an open and flexable system it helps to know how these devices are structured; the routers typically have 4M of flash laid out as follows: [ boot loader ] [ firmware ... ] [ nvram ] When you power on the device, it runs a loader which initializes the hardware and then boot straps into the firmware. The firmware contains the Linux kernel and filesystem while all configuration changes are stored as variables in a separate part of the flash called the nvram. All the firmware did was read some variables from nvram and apply them; short of reflashing the device, you really can't do anything with the firmware, and even if you did modify the filesystem it would be treated as corruption by the boot loader. The key to this whole thing is that the firmware doesn't use all of the available space -- there's a gap between the end of firmware and the start of nvram, and the smaller you can make the firmware, the larger that gap will be. This allows the firmware itself to remain read only while allowing a writable filesystem in the remaining flash space, and it's this writable filesystem that's the key to OpenWrt. Where OpenWrt really shines is the fact that you're not limited to what features were compiled into the firmware; the writable filesystem allows you to add and remove packages in exactly the same way that you would in a Linux distribution. This means that instead of trying to cram as many features as possible into one firmware, users are now free to pick the features that they actually need, and developers are free to focus specifically on making packages without having to deal with an entire firmware. To make things even more flexable, OpenWrt uses shell scripts instead of compiled binaries which could not be easily edited from the router. - The build system - OpenWrt's policy for being flexable extends beyond just the firmware itself, into the actual system which builds the firmware -- buildroot. Instead of a typical set of sources, OpenWrt's buildroot system actually contains almost no sources. Instead, buildroot is a template, a script for exactly how to download the sources required, and what to do to compile them. What this means is that if a new version of the kernel comes out tomorrow, I don't have to spend any time replacing old kernel sources with new kernel sources, I just have to edit one line which tells buildroot which kernel to download.