Friday, September 5, 2008

Compiling a Linux (Vanilla) Kernel

Here's how I've compiled vanilla kernel for my SuSE 10.0 (1). A vanilla kernel is the one you can download from www.kernel.org,which does not include any modification by any distribution (e.g., Suse, Debian, etc.). Normally, a distribution adds its own patches, facilities to this core kernel.

Likewise, you can also add any patchset supported by the linux version you are about to compile. For example, ARA (adaptive readahead) is not a stock option as of version 2.6.21 but there is a patchset if you'd like to have ARA feature on your Linux box. Or else, you'd like to upgrade to an upper version you may apply the new version's patch, which are called prepatches.

Basically below are the steps you would normally go through when compiling a linux kernel source:
  1. Get the kernel source from kernel.org
  2. Untar the download file in /usr/src directory. This will create a new directory under /usr/src, which would be like linux-2.6.21.x
  3. Create a symbolic link named "linux" to this new directory again under /usr/src:
    • /usr/src/linux -> /usr/src/linux-2.6.21.x
  4. Apply the patches if you have any supported by the version you are about to compile
    • Untar the patch file under /usr/src/linux
    • I'd definitely recommend you first do a dry-run. A dry-run will not actually add the patch but kind of simulate it. You'd have a chance to see whether any failure occurred. You can find more information on how to apply patches to a kernel source tree here.
      • patch --dry-run -p1 < "patch_name"
  5. Now, it's cofiguration time. Before compiling the kernel you need to configure it. Basically, you select which drivers to include, change any default parameter, etc.

    It's a very common practice to use the already running kernel's configuration file because it is probably configured to include all the necessary drivers, etc. The running kernel's configuration file is found under the /boot directory. Hence, copy the existing config file (probably named as /boot/config-2.6.x.y) under /usr/src/linux:
    cp /boot/config-`uname -r` /usr/src/linux/.config (2)
  6. Use "make menuconfig" to start configuring your new kernel. This command brings up a menu. You need to first "load" the config file using the "Load an Alternate Configuration Final" menu item. This will load the old config file.
    Afterwards, you can go through the menu tree and configure your kernel. For example, as mentioned in kernel log buffer subject, you may want to change the size of the kernel log ring buffer, which can only be modified at kernel compilation time. You can do it by Choosing "Kernel Hacking" menu item and then change the "Kernel Log Buffer Size" menu item in the new menu.

  7. We have the source tree, we have configured the kernel parameters /drivers/etc; finally, it's time to build/compile the kernel. At this point, there is separate paths to follow depending on your Linux distribution. In Suse, you create an rpm file. In Ubuntu and Debian, you need to compile the kernel source into a deb package. "Linux HowTos and Tutorials" web site has a very nice set of documents for compiling kernel for each most popular linux distros.
  8. Normally, compilation takes half an hour to one or one and a half hours depending on the speed of your box. After building is done, it's time to install the newly built kernel.
    Again in above source, you can find how to carry out installation process for your Linux distro.

Footnotes:

(1) You can learn the version of your distribution from /etc/issue
(2) uname command prints the system information. "uname -r" gives the version of the running kernel.