Compiling FreeBSD

FreeBSD 4.X (the current stable version is 4.2 at the time of this writing) is a terrific operating system, and compiling it is actually easier than compiling a Linux kernel. Compiling your kernel will probably be second nature to you if you're a Linux veteran. And for UNIX in general, booting a custom kernel is one of the few times you'll ever need to reboot. Building a custom kernel is good because it will use less memory than the generic kernel you boot by default. This will greatly improve performance.

You have to be root to create a new kernel, so this article won't apply to you if you don't have root over your FreeBSD box. The steps are to install the system source, create a kernel configuration file, create the build directory with the program config, run make depend to create the dependency information for the kernel build, make and then install the kernel and reboot.

The first thing to do once you've installed FreeBSD is to see if /usr/src/sys exists. If this directory doesn't exist, then you need to install the sources from CD-ROM or from online (online upgrades are normally done with cvsup and will be covered in another article). You can either use the /stand/sysinstall program to install the sources from CD-ROM, or you can simply do something like the following:

mkdir -p /usr/src/sys
ln -s /usr/src/sys /sys
cd /
cat /cdrom/src/ssys.[a-d]* | tar xzvf -

I generally prefer to install sources upon when I install the operating system (using /stand/sysinstall), but if by chance the source installation program is broken at all, you might have to remove the /usr/src/sys directory and execute the above commands anyway.

Once the source code is installed, you define your kernel in a kernel configuration file. To create a new kernel, change your directory to /usr/src/sys/i386/conf. (This assumes your architecture is Intel; if it's not, substitute your architecture for ``i386''.) You'll notice several files in there, such as GENERIC, LINT. To create a custom configuration file, copy GENERIC to your new configuration name and edit it with only the configuration instructions you require.

cd /usr/src/sys/i386/conf
cp GENERIC NEWKERNELNAME
vi NEWKERNELNAME

Obviously, NEWKERNELNAME should be the name of the new kernel you're creating. I generally name the new kernel after the host it will run on. My current host, for example, is JUNO. So I would type cp GENERIC JUNO. Also, you can replace ``vi'' with whatever editor you fancy.

Fortunately, the GENERIC configuration file is quite well documented. Mostly, you will only need to comment out parts of it that you won't be needing. You might also be uncommenting parts that were commented before, such as SMP or Bridged PCI cards. (If you don't know what they mean, you probably don't need them.) For those areas of the configuration file that are not described completely, you can look at the LINT file.

The LINT file contains options and definitions you will probably not use. They are there just in case. When you find something that you need and that applies to your platform, simply copy those lines from the LINT file to the NEWKERNELNAME file.

One example of something you'll probably need from the LINT file will be for your sound card. Sound configuration is normally not included in the default GENERIC kernel. So you'll need to copy those lines to your new configuration file.

I'm sorry to say that compiling sound into your kernel is not terribly well documented in the FreeBSD Handbook. For more in-depth instructions, check out www.freebsddiary.org/sound.html. There are links to other sites there as well. Be advised that under 4.X kernels, the snd0 driver is deprecated in favor of the pcm0 driver. Also, be sure to check out the latest and greatest edition of the FreeBSD handbook online for any syntax changes (www.freebsd.org/handbook. Sometimes the supplied version of the handbook on CD-ROM could be slightly out of date.

Once your configuration file is edited to your satisfaction, simply run the /usr/sbin/config NEWKERNELNAME command. Please note that you'll need to change directories before you make your kernel dependencies, make your kernel and install it. The whole scenario looks like this:

cd /usr/src/sys/i386/conf
cp GENERIC NEWKERNELNAME
vi NEWKERNELNAME
/usr/sbin/config NEWKERNELNAME
cd /usr/src/sys/compile/NEWKERNELNAME
make depend
make
cp /kernel.old /kernel.save
make install

A few notes: the config command has several options you might be interested in, such as -g for debugging and -r to remove the old compile directory. When you run the config command, your NEWKERNELNAME file will be checked for syntax errors. This is very helpful, since anyone can make a typo. The error might look like this, for example:

config: line 47: syntax error

Then you could edit line 47 of NEWKERNELNAME and run config again, and you would be off and running with the rest of the procedure.

Note that the make install procedure copies your existing kernel to /kernel.old. This is handy because if your new kernel doesn't work, you can simply boot from kernel.old instead, which you know works. However, if you already have a kernel saved in /kernel.old, it will be overwritten. So, copy /kernel.old to /kernel.save if you want to save that. Then you can run make install and test your new kernel.

To check your new kernel, check the output from dmesg. Your startup messages will show up there, and any errors you see will point you to changes you'll need made in your NEWKERNELNAME file.

The major points where FreeBSD kernel compiling differs from building a Linux kernel are these:

In conclusion, I'm happy about how easy it is to build a custom kernel with FreeBSD. I think it's even more straightforward than with Linux. Another time, I'll talk about how to upgrade your FreeBSD distribution.



dsj@dsj.net