Compiling the FreeBSD Kernel

This is a very simple step by step guide on optimising your FreeBSD server or workstation. It doesn't go into a great amount of detail, but after spending several months searching for one source of simple optimisation information and failing, I wrote this paper. All the suggestions listed here are known optimisations available to you if you know where to find them and have the time to do so. There is nothing secret, or special or amazing in this paper, just information on how you can optimise your system.

It can mostly be applied to the other BSDs too, but not Linux. There are plenty of Linux documents out there, so go find one of those. I'm sure there are several HOWTO's. This document is true as of the release of FreeBSD 4.8. Some parts of it, such as optimising your kernel, can also be applied to some previous releases.


Before we proceed any further you should know that as with any system tuning, we have to accept the possibility that something will break. If you're going to recompile the kernel, please read the following URL first. If possible print a copy of the page and keep it with you. It'll help you if your new kernel doesn't boot:
http://www.freebsd.org/handbook/kernelconfig-trouble.html

First we need to make sure we have the right source files downloaded. The best place to start, is the original source files that were intended for the release of FreeBSD you are using. We assume you have a fairly recent release - not more than 2 revisions (approx 6 to 8 months) old. Execute the following command and follow the steps to get the sources needed to recompile a kernel:

  • # /stand/sysinstall
  • Choose 'Configure'
  • Choose 'Distributions'
  • Choose 'src'
  • Choose 'sys' and then choose 'OK', and 'OK' again.
  • Choose an FTP site to download the sources from. If you're prompted to 'skip over the network configuration now', choose 'Yes'. After the install is complete, choose the 'Exit' options until you exit sysinstall.

Congratulations, you now have a know working kernel source tree installed in /usr/src/sys!
Now, cd /usr/src/sys/i386/conf and follow the next steps.

You should see two files in this directory, GENERIC and LINT. These are both kernel configuration files and contain all the data the kernel needs from the user, to compile. They are very easy to read and edit.
GENERIC is the Generic kernel configuration which should work with every system. LINT contains a list of all possible kernel configuration file directives. We won't worry about LINT just yet. First lets trim the GENERIC kernel down and get comfortable with that. Follow these steps to success:

  1. Copy the GENERIC file to a new file. Traditionally, this new file has the same name as the hostname of your machine.
  2. Edit this new file in your favourite text editor. I prefer vi and have written a cheat sheet for new vi users at:
    http://networking.ringofsaturn.com/Unix/viguide.php
  3. There are only a few pitfalls and special cases to watch out for in this file. As you can see it just a plain text file and any line starting with a # is considered a comment and ignored by the compiler.
    • The word 'GENERIC' in the line 'ident GENERIC' is the name of your kernel. This can be any single alphanumeric word with no spaces or punctuation. I recommend you keep it short. Again, it is traditional to name this to be the same as your machine hostname and kernel configuration file name but it is not required. It is informational only.
    • The maxusers line does not actually limit the maximum number of users. It is used internally with an algorithm in the param.c file to determine the sizes and numbers of certain tables. This can remain at the default. As of FreeBSD 4.7 this is set to '0' by default, which causes the actual value to be auto-sized depending on the amount of memory that you have.
    • Most, if not all items in your kernel config will have a comment toward the end of the line. Anything labelled with '[KEEP THIS!]' should not be removed. FreeBSD needs these things! Anything labelled '(required!)' should also be kept if you're going to use that type of device. For example, if you're going to use SCSI devices, don't comment out 'scbus'. If you're not using any SCSI devices, then you should comment this out. Some PCI network cards require the inclusion of 'device miibus'. These are noted in your kernel configuration file. If you don't use these NICs you can also comment this out.
    • Now go through the entire file and comment out anything you don't think you'll need. Effectively every line contains a driver. Commenting it out will mean that particular piece of hardware will not work your system, even though it may be recognised as present in the system. Thus it is bad to comment out your own network card, but good to comment out any cards you don't have. Don't worry if you comment out something you will need later. You can always recompile fairly quickly and simply.
  4. After you've finished editing the configuration file, save it and exit from the editor.
  5. Change to the /usr/src directory.
    # cd /usr/src
  6. Compile the kernel.
    # make buildkernel KERNCONF=MYKERNEL
  7. Install the new kernel.
    # make installkernel KERNCONF=MYKERNEL
  8. Reboot.BR> # Reboot

If all went well, then your new kernel should load during the next reboot. To verify, simply run a uname -a to see the kernel version:

[tethys]:[11:00am]:[/home/rnejdl/www/networking/Unix] > uname -a FreeBSD tethys.ringofsaturn.com 5.2.1-RELEASE-p5 FreeBSD 5.2.1-RELEASE-p5 #1: Wed Apr 21 04:01:25 CDT 2004 root@tethys.ringofsaturn.com:/usr/obj/usr/src/sys/SATURN i386 [tethys]:[11:00am]:[/home/rnejdl/www/networking/Unix] >

Troubleshooting

If your new kernel does not boot, or fails to recognize your devices, do not panic! Fortunately, FreeBSD has an excellent mechanism for recovering from incompatible kernels. Simply choose the kernel you want to boot from at the FreeBSD boot loader. You can access this when the system counts down from 10. Hit any key except for the Enter key, type unload and then type boot kernel.old, or the filename of any other kernel that will boot properly. When reconfiguring a kernel, it is always a good idea to keep a kernel that is known to work on hand.

After booting with a good kernel you can check over your configuration file and try to build it again. One helpful resource is the /var/log/messages file which records, among other things, all of the kernel messages from every successful boot. Also, the dmesg(8) command will print the kernel messages from the current boot.

References:

This is a list of references I found when writing this paper. Most of them contain much more detail on their particular subject than I have provided here. Hopefully they will be as useful to you as they were to me.