Monday, November 14, 2005

Building Products with FreeBSD

The availability of high-quality source code from the FreeBSD project, under its liberal license, is a boon to organizations (particularly startups) creating software products and appliances.

However, most organizations that I've had the oppurtunity to observe have not been looking at long term collaboration with the project. They take in FreeBSD source code as a one-time drop and forget to keep an eye on where things are going. These are the kinds of mistakes that I've seen being made:

  • One organization developed a kernel module that relied on kernel threads being non-preemptible (despite PREEMPTION being present in -CURRENT). They had to scramble when kernel preemption appeared in -STABLE.
  • One organization started with FreeBSD 5.X and kept fixing bugs that they encountered in their private copy of the code. They didn't feed anything back upstream, and had to redo their patches when they took the next code drop from upstream.
  • One organization started an ambitious FreeBSD project but never spoke about it in public. They advertised for candidates, but had a few excellent candidates walk away unconvinced that they would find good FreeBSD work in that company.

Traditionally, you wouldn't think of collaborating with your OS vendor. You would buy their software, either as a binary or as source, and start using it. You wouldn't have the ability to influence your vendors strategy and decision making process (unless you were IBM, of course). While some vendors do let you view their bug-list, bug prioritization remains their prerogative, so if you are hurting because of a nasty bug, you just have to cross your fingers and wait. You would be constrained by your vendor's platform support policies too; they could stop supporting a platform that is unprofitable for them but still profitable for you.

Collaboration with volunteer developed projects is something new, something that is nearly never done in the closed source world. Collaboration is also something that is not possible with every open source project out there (just being "open-source" is not enough). Effective collaboration requires projects to be complete, transparent, to have good engineering practices, and to have fair and tranparent ways for you to contribute and influence their evolution.

FreeBSD has good code, and, perhaps more importantly, follows many practices that make it a solid foundation to develop products on.

So I wrote an article to introduce FreeBSD as a toolbox for product development. I've listed the benefits of taking the long-term view, and examined best-practices to follow when collaborating with the FreeBSD project.

This article on the FreeBSD website now: http://www.freebsd.org/doc/en_US.ISO8859-1/articles/building-products/.

Read, enjoy, spread the word!

Wednesday, October 26, 2005

Cross building FreeBSD

A Tale of OS Bootstrapping

What do you do when an AMD64 box comes by your way but you only have an 32-bit operating system to run on it? With FreeBSD, you can bootstrap your way into a 64 bit world. Here is what you do:
  1. Install FreeBSD in the usual way. When doing so, keep a spare disk partition for holding the new amd64 OS. In this example, we'll assume that this is partition 'd'. Mount this partition on some convenient mount point, say /1. The full FreeBSD system occupies about ~250MB these days; so make this partition a few GB in size. Don't forget to install the sources to the FreeBSD system of course, otherwise there won't be anything to cross-build.
  2. Change directory to the root of the source tree /usr/src and execute the following commands:
    # cd /usr/src
    # make world TARGET_ARCH=amd64 DESTDIR="/1"
    This step builds an amd64 userland and populates it into /1. Several interesting things happen as part of this step.
    • Since the host OS at this point is running in 32-bit mode it has to build a full cross-toolchain first: tools running on the i386 architecture but manipulating libraries and executables for the amd64 architecture.
    • It then needs to compile the whole source tree for the amd64 architecture using tools running on the i386.
    • Once compilation succeeds, the build process transfers the newly built binaries into the filesystem rooted at /1.
    Other options for TARGET_ARCH include powerpc, sparc64, alpha, ia64.
  3. The next step is to populate a default /etc. This is how you do this:
    # make distribution TARGET_ARCH=amd64 DESTDIR=/1
    This step populates /1/etc with the default set of startup scripts.
  4. Now we need an amd64 kernel to boot from:
    # make kernel KERNCONF=GENERIC TARGET_ARCH=amd64 DESTDIR="/1"
    This builds a kernel following the configuration specified in the configuration file named /usr/src/sys/amd64/conf/GENERIC and installs it under /1/boot/kernel.
  5. Copy over /etc/fstab to /1/etc/fstab and change the definition of the / (root) mount point to use partition 'd' (the default is to mount / on the 'a' partition).
  6. Copy over /etc/rc.conf to /1/etc/rc.conf, as this contains the machine's hostname, and IP addresses of its interfaces.
  7. Create a file boot.config in the 'a' disk partition containing the following text:
    0:ad(0,d)/boot/loader
    This command informs the first stage boot loader (see boot(8)) that we want to boot from partition 'd' instead of the usual partition 'a'. If you've booted from a SCSI disk, you may need to specify the boot device as da(0,d).
  8. Reboot. Viola! You boot into an AMD64 kernel running an AMD64 userland.