### Installing NanoBSD on my Alix mini router box ###


I recently got the idea to replace my m0n0wall router/firewall at home by a 'normal' FreeBSD system. The idea came mostly because I needed to perform tricky network configurations that aren't supported by m0n0wall. My router hardware is an 'Alix' box from PC Engines, and it runs on a small (512M) CompactFlash card. So the challenge is to make a FreeBSD system fit on that *and* not kill the flash card with writes (ideally running the whole thing on a read-only root).

First I created a VirtualBox machine with a standard FreeBSD system (I used FreeBSD v9.2 since it was the latest stable one at the time of this writing, but this article is currently up to date as of FreeBSD 10.0). The important thing is to use the same architecture than the destination system (in my case it was i386). Important note: give the VM some RAM, as it requires plenty when building the system! I allocated 2 GiB of RAM to my build VM, and yet it still managed to swap a little bit. Providing more than 1 virtual CPU helps, too (assuming your host machine have more than 1 core of course). The BSD build process uses plenty of parallel jobs. Also, don't be greedy on disk space - I started with a single 8G virtual disk and it wasn't enough. 16G is fine.

To build my embedded system, I used the nanobsd script that is present in the FreeBSD sources already, at /usr/src/tools/tools/nanobsd/.

There is already a pre-configured version for PC-Engines embedded computers, so at first I was tempted to use that as a base. Unfortunately I got into troubles I had no clue how to solve, so I forgot about the pcengines special script and went back to the standard nanobsd that I customized myself.
I created my own 'mateusz.conf' configuration file, as well as a 'MATEUSZ' kernel configuration. You'll find both attached to this article.

I also needed to add an application from ports into my nanobsd build (namely the ipsec-tools suite). To do this, I first created a package from ports:

  # cd /usr/ports/security/ipsec-tools
  # make
  # make package

Then, I created a 'packages' directory in the nanobsd config directory, and copied my newly created package there:

  # mkdir /usr/src/tools/tools/nanobsd/packages
  # cp /usr/ports/packages/All/ipsec-tools-0.8.1_3.txz /usr/src/tools/tools/nanobsd/packages/

Note, that on v9.2 the packages end up in their port directory, so the command above must be adapted:

  # cp /usr/ports/security/ipsec-tools/ipsec-tools-0.8.1_3.txz /usr/src/tools/tools/nanobsd/packages/

This same steps can be applied to any port. Take care to add all dependencies there, too. In my case, I added following ports:
  devel/binutils
  lang/gcc
  math/gmp
  math/mpc
  math/mpfr
  net/arping
  net/bird
  net/bird6
  net/isc-dhcp42-server
  net/libnet
  security/ipsec-tools

To make the package(s) actually find their way to my destination system, I used a customize function in the nanobsd configuration file, that's what the 'install_packages' function is about in the configuration file.

Finally, I executed the build script:

  # sh nanobsd.sh -c mateusz.conf

Then, you have plenty of time to do other things, since the building procedure takes a really long time (like 2h). But if you're a no-life like me, you might just as well spend the whole time monitoring the build system by looking at top, df, and checking gcc logs.. (and writing this article, too).

If you'd need to perform any future changes that do not require to rebuild the entire world (like adding a new port to the image), then it saves much time to skip the buildworld and buildkernel stages, adding -b as a command line parameter to nanobsd.sh.

=== Attachments ==========================================
MATEUSZ kernel configuration.txt
mateusz.conf