## blog @ bjerck.net

#### Compiling an upstream kernel on ubuntu.

by: tom
##### Introduction

After downloading the source from kernel.org or any of the mirrors, you have at least two options for how to compile the source for a ubuntu system. First you can just do it the traditional way and just use the Makefile that comes with the source directly. A second and more convenient and safer way to do this is to make a deb package, and let apt handle the installation and later eventually the removal of the kernel when it is no longer needed. Also making a deb will make sure that any installation scripts in the /etc/kernel directory is executed. These scripts currently updates the initramfs image, updates grub config and recompiles any third party modules. These scripts can not be part of the kernel package since they are dependent of the target system.

##### Compiling using the make deb-pkg target in the Linux kernel source Makefile

I didn't know this until recently, but the kernel Makefile has a deb-pkg target. It's the functionality used for compiling a new kernel documented in the Debian Kernel Handbook chapter 4. Se the scripts/package/builddeb file in the Linux source to see what this build target does. If you have a multi core cpu, you may use make's -j<num jobs> option, to speed things up.

##### Compiling using kernel-package

You should install the following packages:
kernel-package fakeroot build-essential

###### Relevant documentation:

man make-kpkg
man kernel-package
man make
Debian Kernel Handbook
wiki.ubuntu.com/KernelTeam/GitKernelBuild
/usr/share/doc/kernel-package/README.gz
/usr/share/doc/kernel-package/Kernel.htm
man gpg
man wget
www.kernel.org/signature.html
kernelnewbies.org/FAQ/KernelCompilation

###### Versions

There are three version labels:

1. The stable upstream kernel versions at kernel.org whose format are three numbers separated by dots, like 3.4.6.
2. The deb package of the kernel has it's own version; usually composed of the upstream version numbers and local revision numbers.
3. Then there is a third versioning labeling the locally configured and compiled kernel. This version number is the output of uname -r.
The last version label mentioned above is used to name the Linux kernel image file, and also to name the directory where it's modules are installed under /lib/modules. It's important that these names are unique for each new kernel installed on the system in order to have binary compatibility between the kernel image and it's modules and prevent previously installed kernels and modules from being overwritten.

In the following I'll download and unpack the source code for the 3.4.6 version of the upstream Linux kernel. I'll also download the gpg signature file and use it to verify the download. Using wget:
wget "https://www.kernel.org/pub/linux/kernel/v3.0/linux-3.4.6.tar.xz"
wget "https://www.kernel.org/pub/linux/kernel/v3.0/linux-3.4.6.tar.sign"
The compressed tar file needs to be decompressed before gpg verification:
xz -d "linux-3.4.6.tar.xz"
Use gpg to verify:
gpg --verify "linux-3.4.6.tar.sign"
If you get an error message about a missing key, you need to import the signing key from a keyserver:
gpg --recv-keys <key id>
And then run the gpg verify command again. You should then get a message proclaming "Good signature". If you get a message stating "Bad signature" something is wrong. If this step goes well, continue and untar the archive:
tar xf "linux-3.4.6.tar"
This should extract a directory named linux-3.4.6. Make this your working directory:
cd linux-3.4.6

###### Configure the kernel

You now need to configure the kernel. If you want base the new configuration on the old config that was used when building your currently running kernel, you just copy it from the /boot directory like this:
cp /boot/config-\$(uname -r) .config
The new kernel will likely have new configuration options not present in the config for the old kernel. Therefore you now need to run one of the several utilities supplied with the kernel source for editing the configuration. For a terminal user interface you can use menuconfig which you start by giving the command make menuconfig in the root directory of the source.