Building a Modified Linux Kernel

These instructions, intended for MCS-378, are adapted from the Ubuntu Community's KernelCompile document, specifically following the "Alternate Build Method: The Old-Fashioned Debian Way"

You will need a directory to work in; here I assume it is called paginglab. Start by creating that directory and changing into it:

  mkdir paginglab
  cd paginglab/

Next, install all the stuff that the above-cited document claims you'll need:

  sudo apt-get install fakeroot build-essential makedumpfile
  sudo apt-get build-dep linux
  sudo apt-get install linux-source

Now you want to unpack the Linux source directory tree and change directory into it. The name of this depends on the version; if the version has advanced beyond 2.6.28, you'll need to make the appropriate change here:

  tar xjf /usr/src/linux-source-2.6.28.tar.bz2 
  cd linux-source-2.6.28/

Although your goal is to build a modified kernel, I strongly suggest that you start by building a kernel that is completely unmodified, except that it has an extra string tacked onto the version name. (Here I assume that extra string is -paginglab though you could substitute something else.) The reasons for building this unmodified kernel are two-fold: (1) If something goes wrong in the build process, you'll know it isn't caused by your modifications. (2) When you later make modifications and re-build the kernel, the build-process will go much more rapidly (and bomb out much more quickly, if your modifications don't compile properly), because most of the files won't need recompilation.

Following the KernelCompile document's instructions, the next few steps would be as follows:

  cp -vi /boot/config-`uname -r` .config
  sudo apt-get install qt3-dev-tools libqt3-mt-dev
  make xconfig

At this point, you are confronted with the graphical user interface of the xconfig program, which lets you change any of myriad configuration settings. (If you had instead chosen to use menuconfig, the situation would be analogous, except that the user interface would be running within the terminal window.) This raises a question: what should you change? The answer: nothing at all. As soon as you are into xconfig, immediately quit back out of it. So why run it? Because the build process requires this step as a way of confirming that you have an up-to-date configuration.

Going back to following along the KernelCompile document, the next step is

  make-kpkg clean

At this point, you'll find that despite everything you installed earlier with apt-get, you don't have make-kpkg. But luckily, as usual, the attempt to run a non-installed program will give a message telling you what package you need to install. So, you can install that package and complete the kernel build process:

  sudo apt-get install kernel-package
  make-kpkg clean
  CONCURRENCY_LEVEL=3 fakeroot make-kpkg --initrd --append-to-version=-paginglab kernel-image kernel-headers

You might notice that the command to make the kernel package includes the environment variable setting CONCURRENCY_LEVEL=3. (This is done in a somewhat different manner than shown in the KernelCompile document, so that it applies only to the one command.) This makes the process only take a very long time (roughly 4 hours) rather than a ridiculously long time. The previous lab should have given you some sense for why a concurrency level of 3 might make sense even though your processor can only run two threads at a time.

At this point, assuming nothing went wrong, you've built a new kernel package (distinguished only by its name), but not installed it. Now you can edit some of the source files to incorporate your modifications. Once you have done your editing, in order to make the build process look and see which files are modified, and recompile those, you need to delete a directory of "stamp" files. (However, you should not take the more extreme step of repeating the make-kpkg clean command; that would cause the entire kernel to be recompiled from scratch, even the parts you didn't modify.) The commands to delete the stamp files and rebuild the kernel packages are as follows:

  rm -r debian/stamp/
  CONCURRENCY_LEVEL=3 fakeroot make-kpkg --initrd --append-to-version=-paginglab kernel-image kernel-headers

Because of the concurrency, if your modifications don't compile correctly and the build process fails, the error messages may not be at the end of the output; you might need to scroll upward to find them. (Alternatively, if the build process fails, you can retry it without any concurrency.)

On the other hand, if you successfully built the modified kernel packages, now you can install them. They are up one level in the directory tree (in the paginglab directory in my example). Change directories up to there and use the installation commands shown in the KernelCompile document:

  cd ..
  echo vesafb | sudo tee -a /etc/initramfs-tools/modules
  echo fbcon | sudo tee -a /etc/initramfs-tools/modules
  sudo dpkg -i linux-image-2.6.28.10-paginglab_2.6.28.10-paginglab-10.00.Custom_i386.deb 
  sudo dpkg -i linux-headers-2.6.28.10-paginglab_2.6.28.10-paginglab-10.00.Custom_i386.deb 

The package files shown in the last two commands are based on the current version when I wrote these instructions; they may have changed, in which case, use the corresponding filenames that are in your directory.

Now if you shutdown your computer and boot it back up, you should see your modified kernel at the top of the boot menu. Hopefully if you select it, you will find it runs as intended. If not, you can select a different kernel to boot.