The kernels provided by Debian include the largest possible number of features, as well as the maximum of drivers, in order to cover the broadest spectrum of existing hardware configurations. This is why some users prefer to recompile the kernel in order to only include what they specifically need. There are two reasons for this choice. First, it may be to optimize memory consumption, since the kernel code, even if it is never used, occupies memory for nothing (and never “goes down” on the swap space, since it is actual RAM that it uses), which can decrease overall system performance. A locally compiled kernel can also limit the risk of security problems since only a fraction of the kernel code is compiled and run.
Recompilation of the kernel is also necessary if you want to use certain features that are only available as patches (and not included in the standard kernel version).
8.10.1. Introduction and Prerequisites
Debian manages the kernel in the form of a package, which is not how kernels have traditionally been compiled and installed. Specific tools have therefore been developed for this purpose. They allow easy creation of a Debian package from Linux kernel sources, possibly adding patches along the way. Since the kernel remains under the control of the packaging system, it can then be removed cleanly, or deployed on several machines. Furthermore, the scripts associated with these packages automate the interaction with the bootloader.
To compile a Linux kernel the Debian way, you will need to use the tools included in the kernel-package package. Furthermore, the configuration step for the kernel requires the libncurses5-dev package. Finally, the fakeroot package will enable creation of the Debian package without using administrator's rights.
8.10.2. Getting the Sources
Like anything that can be useful on a Debian system, the Linux kernel sources are available in a package. To retrieve them, just install the
linux-source-version
package. The
apt-cache search ^linux-source
command lists the various kernel versions packaged by Debian. The latest version is available in the
Unstable distribution: you can retrieve them without much risk (especially if your APT is configured according to the instructions of
Section 6.2.6, “Working with Several Distributions”). Note that the source code contained in these packages does not correspond precisely with that published by Linus Torvalds and the kernel developers; like all distributions, Debian applies a number of patches. These modifications include patches (some relevant to security problems) that are waiting to be included in the next version of the kernel, as well as some features that are specific to Debian (like cramfs, a filesystem specifically for the
initrd
image).
The remainder of this section focuses on the 2.6.32 version of the Linux kernel, but the examples can, of course, be adapted to the particular version of the kernel that you want.
We assume the linux-source-2.6.32 package has been installed. It contains /usr/src/linux-source-2.6.32.tar.bz2
, a compressed archive of the kernel sources. You must extract these files in a new directory (not directly under /usr/src/
, since there is no need for special permissions to compile a Linux kernel): ~/kernel/
is appropriate.
$
mkdir ~/kernel; cd ~/kernel
$
tar -xjf /usr/src/linux-source-2.6.32.tar.bz2
8.10.3. Configuring the Kernel
The next step consists of configuring the kernel according to your needs. The exact procedure depends on the goals.
When recompiling a more recent version of the kernel (possibly with an additional patch), the configuration will most likely be kept as close as possible to that proposed by Debian. In this case, and rather than reconfiguring everything from scratch, it is sufficient to copy the /boot/config-version
file (the version is that of the kernel currently used, which can be found with the uname -r
command) into a .config
file in the directory containing the kernel sources.
$
cp /boot/config-2.6.32-5-686 ~/kernel/linux-source-2.6.32/.config
Unless you need to change the configuration, you can stop here and skip to the next section. If you need to change it, on the other hand, or if you decide to reconfigure everything from scratch, you must take the time to configure your kernel. There are various dedicated interfaces in the kernel source directory that can be used by calling the make target
command, where target
is one of the values described below.
make menuconfig
compiles and executes a text-mode interface (this is where the libncurses5-dev package is required) which allows navigating the options available in a hierarchical structure. Pressing the Space key changes the value of the selected option, and Enter validates the button selected at the bottom of the screen; Select returns to the selected sub-menu; Exit closes the current screen and move back up in the hierarchy; Help will display more detailed information on the role of the selected option. The arrows allow moving within the list of options and buttons. To exit the configuration program, choose Exit from the main menu. The program then offers to save the changes you've made; accept if you are satisfied with your choices.
Other interfaces have similar features, but they work within more modern graphical interfaces; such as make xconfig
which uses a Qt graphical interface, and make gconfig
which uses GTK+. The former requires libqt3-mt-dev, while the latter depends on libglade2-dev and libgtk2.0-dev.
The make-kpkg
command, presented in the next paragraph, runs make oldconfig
automatically to ensure the presence of a kernel configuration. This configuration method simply reuses the choices saved in the .config
file. If there is no such file, it behaves like make config
, a text interface that asks all questions (hundreds of them) one a time. If the .config
file already exists but doesn't mention all the existing options, then this method will only ask questions for which the file has no saved answer.
8.10.4. Compiling and Building the Package
Once the kernel configuration is ready, the make-kpkg
command provided by Debian compiles the kernel, then generates the corresponding Debian package (or packages). Just like make
, make-kpkg
takes the name of a target to execute as an argument: kernel-image
generates a compiled kernel package, kernel-doc
a package containing the documentation included with the kernel, kernel-headers
a package of kernel header files (.h
files for the kernel in the include/
directory, which is useful for compilation of some external modules), and kernel-source
creates a package containing the kernel sources.
make-kpkg
also accepts several parameters: --append-to-version suffix
appends suffix
to the name of the kernel; the suffix is also included in the package name. --revision revision
defines the version number of the package generated. Debian uses certain suffixes to identify standard kernels, compiled specifically for a given processor, or with certain options (-486
, -686
, -686-bigmem
, -amd64
, -vserver-686
, -vserver-686-bigmem
, -openvz-686
, -xen-686
). These suffixes are best avoided for local packages, so that they can be easily recognized from official packages issued by the Debian project.
The
make-kpkg
program performs actions normally restricted to the root user when creating the Debian package; however, it can be tricked into working under a normal user's identity, with
fakeroot
(see sidebar
TOOL fakeroot
).
$
fakeroot make-kpkg --append-to-version -falcot --revision 1 --initrd kernel-image
[...]
$
ls ../*.deb
../linux-image-2.6.32-falcot_1_i386.deb
As you can see, the package is created with the name “linux-image-2.6.32-falcot_1_i386.deb
”.
8.10.5. Compiling External Modules
Some modules are maintained outside of the official Linux kernel. To use them, they must be compiled alongside the matching kernel. A number of common third party modules are provided by Debian in dedicated packages: lustre-source for the Lustre filesystem, qc-usb-source for the drivers for some USB webcams (Logitech QuickCam Express), etc.
These external packages are many and varied and we won't list them all here; the apt-cache search source$
command can narrow down the search field. However, a complete list isn't particularly useful since there is no particular reason for compiling external modules except when you know you need it. In such cases, the device's documentation will typically detail the specific module(s) it needs to function under Linux.
For example, let's look at the qc-usb-source package: after installation, a .tar.gz
of the module's sources is stored in /usr/src/
. These sources must then be extracted to the working directory:
$
cd ~/kernel/
$
tar xjf /usr/src/qc-usb.tar.bz2
$
ls modules/
qc-usb
The module sources are now located in the ~/kernel/modules/qc-usb/
directory. To compile these modules and create a Debian package, we invoke make-kpkg
with the modules-image
target and indicate the location of the modules via the MODULE_LOC
environment variable (without this variable, it uses /usr/src/modules/
, which won't work in our case). By default, it tries to create the packages for all the external modules that you extracted at this location. The --added-modules
option allows to explicitly choose the external modules to compile. To include more than one, separate them with a comma.
$
export MODULE_LOC=~/kernel/modules
$
cd ~/kernel/linux-source-2.6.32
$
fakeroot make-kpkg --append-to-version -falcot modules-image
[...]
Module /home/roland/kernel/modules/qc-usb processed fine
$
ls ../*.deb
../linux-image-2.6.32-falcot_1_i386.deb
../qc-usb-modules-2.6.32-falcot_0.6.6-7+1_i386.deb
8.10.6. Applying a Kernel Patch
Some features are not included in the standard kernel due to a lack of maturity or to some disagreement between the maintainer of the source code and the kernel maintainers. Such features may be distributed as patches that anyone is free to apply to the kernel sources.
Debian distributes some of these patches in linux-patch-* or kernel-patch-* packages (for instance, linux-patch-grsecurity2, which tightens some of the kernel's security policies). These packages install files in the /usr/src/kernel-patches/
directory.
To apply one or more of these installed patches, use the patch
command in the sources directory then start compilation of the kernel as described above.
$
cd ~/kernel/linux-source-2.6.32
$
fakeroot make-kpkg clean
$
zcat /usr/src/kernel-patches/diffs/grsecurity2/grsecurity-2.1.14-2.6.32.13-201005151340.patch.gz | patch -p1
$
fakeroot make-kpkg --append-to-version -grsec --revision 1 --initrd kernel-image
$
ls ../*.deb
../linux-image-2.6.32-falcot_1_i386.deb
../qc-usb-modules-2.6.32-falcot_0.6.6-7+1_i386.deb
../linux-image-2.6.32-grsec_1_i386.deb
Note that a given patch may not necessarily work with every version of the kernel; it is possible for patch
to fail when applying them to kernel sources. An error message will be displayed and give some details about the failure; in this case, refer to the documentation available in the Debian package of the patch (in the /usr/share/doc/linux-patch-*/
directory). In most cases, the maintainer indicates for which kernel versions their patch is intended.