Kernel Compilation
— print (last updated: Jul 2, 2009) print

Select font size:
The procedure described in this document is taken mostly from this URL:
http://easylinuxcds.com/blog/?p=3244
The reason one would want to do a kernel compilation, other than to learn how to do so, is to enhance the performance of your machine, making it more suitable to your needs. The generic Ubuntu kernel is meant to suit the needs of many types of CPUs in many different circumstances and so its features often represent the "least common denominator" of all possibilities.

In particular, the Ubuntu generic kernel is not ideally suited for many fine-grained Desktop multimedia applications for sound recording, etc. There are other limitations as well, but we will describe these as we are going though the compilation preparation.

Everthing is done as root, so you might as well invoke a root shell. Here are the packages you'll need to install:
# apt-get install kernel-package linux-source fakeroot \
  libncurses5-dev libqt3-mt-dev

Preparation

Everything takes place in /usr/src. The linux-source package appears to be nothing more than the tarball.

First Kernel Compilation

The first time is the least complicated.
# cd /usr/src
# tar xjf linux-source-2.6.28.tar.bz2
# cd linux-source-2.6.28
We need to obtain the config file from the current kernel; it needs to be copied to ".config" in the current directory. Do
# ls /boot
# uname -r
You want the config file whose suffix is the output of the last command. You can put it together in one step:
# cp /boot/config-$(uname -r) .config

First Kernel configuration

Run:
# make xconfig
Alternatively, if you do not have a graphical display, use:
# make menuconfig
The only changes we're going to make are in the Processor type and features section. The features chosen depend alot on how the machine will be used. Let's say the machine's target is being a "high-performance desktop" as opposed to a server. Select this line and look on the right side to make these changes:
  1. Processor family. Set the processor type specific to yours. In our case, we want Core 2/newer Xeon. The way you can discover this is by
    $ cat /proc/cpuinfo
    
  2. Preemption Model. For desktop multimedia applications you want to choose Preemptible Kernel (Low-Latency Desktop).
  3. Timer Frequency. Again, high-performance multimedia applications generally want a higher clock frequency to allow more frequent interrupts. Choose 1000 HZ.
After these changes, save the settings (File Save) and close the configurator.

One other noteworthy setting is High Memory Support. The lab machines have 2GB of RAM, and so the default setting is OK, but keep this setting in mind for newer machines, especially newer servers, which can easily have 8GB of RAM these days.

Compilation

Compilation takes a long time. It's best to start it and not wait. We'll show you something which will allow you to start the compilation and go on and do other things while allowing you to monitor the progress.

I would recommend creating a compilation script, /usr/src/COMPILE (one level above the compilation directory), like this:
#!/bin/bash
# COMPILE
ver=01
nohup fakeroot make-kpkg --initrd --append-to-version=-$ver \
  kernel_image kernel_headers >& OUTPUT &
From inside the compilation directory, one accesses this script by "../COMPILE". Make it executable
# chmod +x ./COMPILE
The version variable, ver we've indicated, which comes after "--append-to-version=" is used to keep track of your kernel version that you compile. It must begin with a minus (-) and must not contain whitespace. For example, we've suggested starting with "01". The compilation begins with the execution:
# ../COMPILE
What we've done is to background the process and redirect both standard output and standard error to the file OUTPUT. Doing so effectively diconnects the process from the shell.

You can log out of this shell at any time! You can log out of the system! The process keeps running. You can see that the compilation is running by doing:
$ w
.............. load average: 1.xx
A load average of "1.something" usually means there is 1 CPU intensive process running.

To see what's currently going on at any time, do this
# cd /usr/src/linux-source-2.6.28 
# tail -f OUTPUT
If you decide you want to terminate the compilation, it's OK. You should be able to simply restart the compilation later and it will take up where it left off. To terminate, do this:
# ps ax | grep fakeroot
Look for the process id (PID) as the first number in the output line:
 NNNN ? ...
Then stop the compilation by killing the process:
# kill NNNN

Install the new kernel

After compilation is done, the installation packages are in the /usr/src directory (one level above the compilation).
# cd /usr/src
# ls linux-*.deb
linux-image-....Custom_i386.deb
linux-headers-...Custom_i386.deb
Install both of these packages.
# dpkg -i linux-*.deb

Reboot to new kernel

The new kernel is installed in these files/directories:
/boot/
   config-..
   System.map-..
   vmlinuz-..
   initrd.img-..
/lib/modules/
   2.6.28.9-01/
/boot/grub/
   menu.lst
Edit the boot loader config file, /boot/grub/menu.lst. This is set to run your newly installed kernel along by default, but the other generic choices are still present. Change the timeout settings to give you more time to choose an alternative kernel. Look for the line:
timeout         3
and change it to
timeout         10
That's the only change. But scroll down until you see the installed kernel as the first "title" line:
title           Ubuntu ..., kernel 2.6.28.9-01 
uuid            ...
kernel          /vmlinuz-2.6.28.9-01 root=... ro quiet splash
initrd          /initrd.img-2.6.28.9-01
Then reboot. When the "grub boot message" becomes visible, hit the Escape (Esc) button to get a list of kernel choices. Try out the new one, the default, at the top. If something goes wrong, reboot and choose the generic one.

Subsequent kernel upgrades

It appears that subsequent kernel installations, generic or custom, will not automatically make themselves the default boot kernel in /boot/grub/menu.lst. Once you have the linux-source package installed, new kernels will reinstall a new version of linux-source-2.6.28.tar.bz2, and so what you'll want to do is this:
  1. remove the old kernel compilation source:
    # cd /usr/src
    # rm -rf linux-source-2.6.28
    and then proceed as before.
    # tar xjf linux-source-2.6.28.tar.bz2
    # cd linux-source-2.6.28
  2. change the version number -nn to the next one up
  3. Copy the previous configuration as you current config file as before, but, instead of "make xconfig", you probably only need to do:
    # make oldconfig
    
    to pick up any necessary changes from the previous kernel. Often this does nothing, but occasionally you will be queried to pick make configuration settings. In these cases, usually hitting Enter will choose the best default setting.
  4. Compile and install as before, but now you have to edit /boot/grub/menu.lst and either move the new kernel's boot stub to the top of the list, or change the setting
    default     position-of-new-kernel-boot-stub
    


© Robert M. Kline