Using make-kpkg

Debian contains a very useful command for helping you to compile and install kernels. It's called make-kpkg. This article gives a quick summary of the features of make-kpkg.

In this article, all the shell command examples assume that you're starting from the root directory of the kernel source (from, e.g., the /usr/local/src/linux-2.6.0 directory, or wherever your source happens to be). Shell commands with a "#" prompt are run as root. Commands with a "$" prompt are run as a normal user.

It is also assumed that you have already downloaded, unpacked and configured your kernel tree. If you haven't done that, then see the LinuxHints/KernelBuilding pages for the general introduction to building kernels.

Finally, you need the following installed, otherwise make-kpkg won't be on your system, and you won't be able to run "make menuconfig".

# apt-get install kernel-package fakeroot build-essential libncurses5-dev patch

Simply building a kernel

As an alternative to the following instructions, more recent kernels allow you to use

make deb-pkg

The most basic use of make-kpkg is this:

# make-kpkg kernel_image

Newbie note: Type exactly that, don't try and replace kernel_image with what you might think is a reference to your kernel source, but see next paragraph before you go ahead. The commands to make the kernel package should be run from the top level of the kernel source tree, e.g. /usr/local/src/linux-2.6.5.

Of course, it's not generally considered a good idea to do something as big and ugly as building kernels as root, so you should probably do it as an ordinary user. However, if you try running make-kpkg as a non-root user, you will find that it bombs out at the end without having built a package. This is because the package must be built with some files owned by root. One solution is to use the fakeroot package, and sudo:

$ fakeroot make-kpkg kernel_image

This builds a Debian kernel-image package in the parent directory which can then be installed using dpkg, as normal:

$ sudo dpkg -i ../kernel-image-2.6.0_i386.deb

where the version matches the one you have just compiled. If you mess up your first attempt at compiling you can start again after doing the 'fakeroot make-kpkg clean' step, described below.

Debian also allows for the use of kernel modules outside of its vanilla source tree (such as third-party vendors) to be packaged. The raw source tends to lie in /usr/src/modules. In order to tell the build process to use them one can prepend the 'modules_image' directive to the make-kpkg command, hence:

$ fakeroot make-kpkg kernel_image modules_image

The modules will then be installable as deb files in the usual way outlined above.

This package will contain not only the kernel, but also all of the in-tree modules that were built with the kernel. Installing the package will ask you whether you want to make a recovery disk, and whether you want to run lilo to make the new kernel bootable. The kernel packages rotate kernels, so installing a new kernel package will make the new kernel bootable with "linux" (the default) at the lilo prompt. The old kernel will still be bootable as "linuxOLD".

Building other things

You can build kernel headers packages, which are essential if you're going to be building out-of-tree modules packages, or anything else which requires kernel headers:

$ make-kpkg --rootcmd fakeroot kernel_headers
$ su -c'dpkg -i ../kernel-headers-2.6.0_i386.deb'

N.B. For situations above where you're having to use "su -c" to run a command, consider using 'sudo' as an alternative.

The new kernel headers will be installed in /usr/src/include.

You can build both the image and headers packages at the same time:

$ make-kpkg --rootcmd fakeroot binary-arch
$ su -c "dpkg -i ../kernel-{image,headers}-2.6.0_i386.deb"

Versioning

If, like me, you build kernels for several machines on a single build box, it is usually helpful to give the packages a filename which reflects the contents. make-kpkg gives you this feature. So, when I build a kernel for my main box (vlad), I do:

$ fakeroot make-kpkg --revision vlad.01 binary-arch
$ su -c "dpkg -i ../kernel-{image,headers}-2.6.0_vlad.01_i386.deb"

The revision string must contain only alphanumeric characters, plus (+) and dot (.), and must contain at least one number. I use the machine name, and a sequence number, so that I can compile multiple kernels of the same version for the same machine and still distinguish them.

Note that if the files stamp-configure and stamp-debian exist from a previous build, you won't be able to set a revision number. You will need to run a clean before running make-kpkg with a different revision number:

$ fakeroot make-kpkg clean

It is worth remembering that this step should be done after an interrupted kernel compilation as well to remove old files.

Clearing up your mess

If you get part way through a kernel build and then abort it, or if it crashes out for some reason you can clean up the source tree using:

$ fakeroot make-kpkg clean

Out-of-tree modules

Debian ship some sets of module sources (notably ALSA) which can be used to build additional modules outside the kernel tree. These modules are not built into the kernel-image packages, but must be compiled separately, and produce their own installation packages.

Install the module sources as root:

 1. aptitude install alsa-source
 1. cd /usr/src
 1. tar -xzf alsa-driver.tar.gz

Now, return to your kernel source, and build the additional kernel modules:

$ fakeroot make-kpkg modules_clean
$ fakeroot make-kpkg modules
$ su -c "dpkg -i ../alsa-modules-2.6.0_0.9.4-1+vlad.01_i386.deb"

If you're running a 2.6 kernel, the ALSA headers are already included within it.

It is my experience that in order to get the modules to build for the right kernel version, you will need to run modules_clean. You will also need to be running the kernel that you are building the modules for. This means that you will have to reboot after you build and install the new kernel, and before building and installing the modules. You don't have to reboot after installing the modules packages.

You can tell make-kpkg only to build some module packages, if you have more than one installed:

$ fakeroot make-kpkg modules --added-modules i2c,lm-sensors

If you omit the --added-modules parameter, it will build all of the module packages it can find in /usr/src/modules.

Debian patch sets

Debian patch sets (such as the Device Mapper patches for 2.4) are also handled by make-kpkg. You need to set the PATCH_THE_KERNEL system variable in order to get it to attempt the patching:

$ aptitude install kernel-patch-device-mapper
$ export PATCH_THE_KERNEL=YES
$ fakeroot make-kpkg binary-arch

The patch system will patch the kernel source, build the kernel packages, and then unpatch the source again. So, if your patches require configuration options to be set, you should use the --configure option:

$ fakeroot make-kpkg binary-arch --configure menu

You can specify old, menu, x, or any of the config targets. This will run the configure process after patching the kernel, so that you can set the appropriate configure options.

Note also that the Debian patch sets know which kernel versions they can patch. If you try to patch a kernel which is too new (or too old), then the patch will be ignored.

LinuxHints/KernelCompiling (last edited 2010-01-15 14:11:16 by 81)