Compile And Install Kernel


Step by Step for the Linux Debian


March 11, 2016 - Tommy Dräger


Compiling your own Linux kernel can be a powerful and rewarding endeavor. By doing so, you can strip out unnecessary components to reduce the kernel size and improve system performance, which is particularly beneficial for older or resource-constrained hardware. Additionally, compiling your own kernel allows you to test and use experimental features and drivers that are not yet available in the stable kernel versions provided by your distribution. Whether you're looking to optimize performance, explore new capabilities, or simply gain a deeper understanding of your system, this guide will walk you through each step of the process in Linux Debian.

Table of Contents

Download Kernel

First, find out which kernel is already installed on your machine.

uname -a
# or
uname -mrns

Example output:

Linux my-debian 4.2.6-linux-4.2.6 x86_64
  • -s: Print Operating System (‘Linux’, here).
  • -n: Print System Hostname (‘my-debian’, here).
  • -r: Print Kernel Version (‘4.2.6-linux-4.2.6’, here).
  • -m: Print Hardware Instruction Set (‘x86_64’, here).

Next, download the latest stable version of the kernel from kernel.org.

Copy the download link and use wget to execute:

wget https://www.kernel.org/pub/linux/kernel/vx.x/linux-x.xx.tar.xz

Verify Kernel Signature

After downloading the kernel image, also download the signature.

wget https://www.kernel.org/pub/linux/kernel/vx.x/linux-x.xx.tar.sign

Unpack the image:

unxz linux-x.xx.tar.xz

Download the public key if it is not automatically recognized in the next step:

gpg --recv-keys 00411886

Next, verify the image:

gpg --verify linux-x.xx.tar.sign

Installing Required Packages

Before compiling the kernel, install the following programs and libraries on your Debian system.

apt-get install libncurses5-dev fakeroot kernel-package binutils libc6-dev gcc make bin86

Optionally, but recommended:

apt-get install tkstep8.0-dev

Building Kernel

After installing all programs, navigate to the working directory (the unpacked folder from the kernel image).

cd linux-x.xx/

Before proceeding, copy the .config file of the existing kernel into the current directory. The current kernel images are located under /boot/.

cp /boot/config-`uname -r` .config

Now, generate a new .config file based on the copied file using menuconfig (a graphical interface for configuring the kernel). Since we installed ncurses, we can use:

make menuconfig

After a few seconds, a screen will appear allowing you to adjust various drivers, modules, etc. Load the copied .config file into the program and adjust it to your preferences. Close the program and clear any unnecessary content.

make-kpkg clean

Compiling Kernel

The compilation process can take a lot of time, depending on the resources of your PC. You can speed up the compilation by exporting the CONCURRENCY_LEVEL.

export CONCURRENCY_LEVEL=X

Where X is a number determined by the number of cores. To find out the number of cores:

cat /proc/cpuinfo

Example output:

processor       : 0
vendor_id       : GenuineIntel
cpu family      : 6
model           : 30
model name      : Intel(R) Core(TM) i7 CPU         870  @ 2.93GHz
stepping        : 5
cpu MHz         : 2945.000
cache size      : 8192 KB
physical id     : 0
siblings        : 8
core id         : 0
cpu cores       : 4
apicid          : 0
initial apicid  : 0
fpu             : yes
fpu_exception   : yes
cpuid level     : 11
wp              : yes
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe pni dtes64 monitor ds_ cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm sse4_1 sse4_2 popcnt lahf_lm ida dtherm
clflush size    : 64
cache_alignment : 64
address sizes   : 36 bits physical, 48 bits virtual
power management:

Some rules of thumb for determining the CONCURRENCY_LEVEL:

  • 1 core: CONCURRENCY_LEVEL = 1
  • 2 cores: CONCURRENCY_LEVEL = 3
  • 4 cores: CONCURRENCY_LEVEL = 5

So, in my case:

export CONCURRENCY_LEVEL=5

Now, compile the image and modules, as well as generate the header files and .deb packages:

fakeroot make-kpkg --append-to-version "-YOURLINUXNAME" --revision "1" --initrd kernel_image kernel_headers

The compilation can take a very long time.

...

After everything is compiled, the relevant Debian packages are placed in the parent directory. Assuming we are still in the working directory of the unpacked kernel image:

cd ..
ls -l linux-*.deb

Example output:

linux-headers-x.xx.x-YOURLINUXNAME_1_amd64.deb
linux-image-x.xx.x-YOURLINUXNAME_1_amd64.deb

Install these two packages with the dpkg package manager:

dpkg -i linux-image-x.xx.x-YOURLINUXNAME_1_amd64.deb
dpkg -i linux-headers-x.xx.x-YOURLINUXNAME_1_amd64.deb

The relevant files are copied to the appropriate directories. The bootable image is now under /boot/:

cd /boot/

There should now be two new files. Depending on your bootloader, you may need to refresh it. I use GRUB, so:

update-grub

Finally, reboot:

reboot

During boot, select the "Advanced options" to see a list of available kernels. Select the latest kernel to boot the system. After the system boots, check the current kernel version:

uname -mrns

Et voilà. The current kernel should match the one just installed. Enjoy.