Compile and Install Linux Kernel 3.12.5 on Debian Wheezy

It’s one of those Sundays when I’ve got some spare time, and decided to upgrade an existing Linux kernel into the latest stable release (as I write this, the latest stable is 3.12.5) on one of my Debian VMs.

Pre-Installation Notes

NOTE 1: we’ll be upgrading from a Debian Wheezy kernel below:

$ uname -rv
3.2.0.4-686-pae #1 SMP Debian 3.2.51-1

NOTE 2: we are using GRUB 2 bootloader.

NOTE 3: make sure that there’s enough free space available on a / partition, preferably at least 8GB to avoid running into any problems, as different kernel configuration may require different amount of space. You’ve been warned.

NOTE 4: if using a separate /boot partition, make sure it’s mounted and has got at least 200MB of free space for initrd image, just in case. You’ve been warned.

Installation

Make sure the system is up to date:

# apt-get update && apt-get upgrade -uV && apt-get dist-upgrade -uV

Install mandatory packages if not yet present on a system:

# apt-get install gcc make bc

Install ca-certificates to avoid getting the following error with wget:

ERROR: The certificate of `www.kernel.org’ is not trusted.
ERROR: The certificate of `www.kernel.org’ hasn’t got a known issuer.

# apt-get install ca-certificates

OPTIONAL: install ncurses package if intended to configure kernel via text-mode windowed environment (make menuconfig):

# apt-get install libncurses5-dev

OPTIONAL: install QT packages if intended to configure kernel via Qt-based GUI environment (make xconfig):

# apt-get install pkg-config qt4-dev-tools qt4-qmake

OPTIONAL: install GTK+ development packages if intended to configure kernel via GTK-based GUI environment (make gconfig):

# apt-get install libgtk2.0-dev libglib2.0-dev libglade2-dev

Download Full Kernel Source Package

# cd ~
# wget https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.12.5.tar.xz

Extract archive into /urs/src:

# tar xvfJ linux-3.12.5.tar.xz -C /usr/src

Change to:

# cd /usr/src/linux-3.12.5

Configure Kernel 3.12.5

Remove old output files that may exist from previous kernel builds:

# make clean

Check “make mrproper” or “make distclean” if you feel you need to remove more files.

To configure the kernel, we will use “make oldconfig” as we want to preserve the existing kernel configuration. For simplicity purposes, we will accept default values for any new features:

# yes "" | make oldconfig

The oldconfig mode will move the original .config file to .config.old and a new .config will be created.

Compile Kernel 3.12.5

Compilation may take from several minutes up to several hours, depending on the speed of the hardware and the number of kernel features we’re compiling. Build the kernel:

# make bzImage

The bzImage stands for “big zImage”. It was developed to overcome the 512KB compressed size limitation of the zImage. Note that both kernel images are compressed by using the slowest gzip compression method. During system boot, the uncompressed zImage kernel image is loaded into low memory, while the uncompressed bzImage kernel image is loaded into high memory.

The kernel image file will be placed under /usr/src/linux-3.12.5/arch/x86/boot/bzImage:

# file -b /usr/src/linux-3.12.5/arch/x86/boot/bzImage
Linux kernel x86 boot executable bzImage, version 3.12.5 (root@debian) #1 SMP Sun Dec 15 13:04:15 GMT 2013, RO-rootFS, swap_dev 0x2, Normal VGA

Once we have bzImage image created, we need to build kernel modules. These are basically object files (.ko files) that can be loaded into the kernel to add needed functionality. Build modules:

# make modules

Worth mentioning that it’s also possible to use a default make target “make all” for the Linux kernel to build both the main kernel file and all the separate kernel modules.

Install Kernel 3.12.5 and Its Modules

Command “make install” serves as a shortcut for copying the kernel file, the System.map and the config files, and often (but not always) creating an initial RAM disk and modifying the GRUB configuration for the new kernel, where “make modules_install” installs kernel modules under /lib/modules/3.12.5. Install both:

# make modules_install install
INSTALL arch/...
INSTALL crypto/...
INSTALL drivers/...
INSTALL fs/...
INSTALL lib/...
INSTALL mm/...
INSTALL net/...
INSTALL sound
DEPMOD  3.12.5
sh /usr/src/linux-3.12.5/arch/x86/boot/install.sh 3.12.5 arch/x86/boot/bzImage \
		System.map "/boot"
run-parts: executing /etc/kernel/postinst.d/dkms 3.12.5 /boot/vmlinuz-3.12.5
run-parts: executing /etc/kernel/postinst.d/initramfs-tools 3.12.5 /boot/vmlinuz-3.12.5
update-initramfs: Generating /boot/initrd.img-3.12.5
run-parts: executing /etc/kernel/postinst.d/pm-utils 3.12.5 /boot/vmlinuz-3.12.5
run-parts: executing /etc/kernel/postinst.d/zz-update-grub 3.12.5 /boot/vmlinuz-3.12.5
Generating grub.cfg ...
Found background: /usr/share/images/desktop-base/umbrella.png
Found background image: /usr/share/images/desktop-base/umbrella.png
Found linux image: /boot/vmlinuz-3.12.5
Found initrd image: /boot/initrd.img-3.12.5
Found linux image: /boot/vmlinuz-3.2.0.4-686-pae
Found initrd image: /boot/initrd.img-3.2.0.4-686-pae
done

As we may see above, the initial RAM disk image has been created and grub configuration updated. Double-check to make sure that no files are missing under /boot. All four files in red must be present:

# ls -1 /boot
 config-3.12.5
 config-3.2.0-4-686-pae
 grub
 initrd.img-3.12.5
 initrd.img-3.2.0-4-686-pae
 System.map-3.12.5
 System.map-3.2.0-4-686-pae
 vmlinuz-3.12.5
 vmlinuz-3.2.0-4-686-pae

Note that in general kernel may have any of several names: vmlinuz, zImage (obsolete), bzImage, kernel (generic name). In our case, vmlinuz means that the kernel has been compressed with any of several tools and was rendered bootable by adding some features.

Create initrd File (If It Was Not Created Automatically)

Create the initrd image file only if one was not created automatically:

# cd /boot
# update-initramfs -c -k 3.12.5

Update Grub Configuration File (If It Was Not Updated Automatically)

Do this only if grub was not updated automatically! Backup the current grub configuration file. We can always use a LiveCD to restore the old but working grub.cfg.org file over the new but broken one:

# cp /boot/grub/grub.cfg /boot/grub/grub.cfg.org

Once done, run command to update grub:

# update-grub

Check grub configuration file to see if the new kernel’s menu entry is there. If not, you may need to open the file and modify it manually:

# vim /boot/grub/grub.cfg

Lines in blue are an existing grub configuration, lines in red were added manually to point to the newly installed kernel 3.12.5. Modify the grub config file to look as below and save changes.

[...]
menuentry 'Debian GNU/Linux, with Linux 3.2.0-4-686-pae' --class debian --class gnu-linux --class gnu --class os {
        load_video
        insmod gzio
        insmod part_msdos
        insmod ext2
        set root='(hd0,msdos1)'
        search --no-floppy --fs-uuid --set=root 47acf9c3-cc2f-47eb-9c8b-18ace566bb40
        echo    'Loading Linux 3.2.0-4-686-pae ...'
        linux   /vmlinuz-3.2.0-4-686-pae root=UUID=cdd66e16-cfc0-4f98-99a0-3efc92fea00f ro  quiet
        echo    'Loading initial ramdisk ...'
        initrd  /initrd.img-3.2.0-4-686-pae
}
menuentry 'Debian GNU/Linux, with Linux 3.12.5' --class debian --class gnu-linux --class gnu --class os {
        load_video
        insmod gzio
        insmod part_msdos
        insmod ext2
        set root='(hd0,msdos1)'
        search --no-floppy --fs-uuid --set=root 47acf9c3-cc2f-47eb-9c8b-18ace566bb40
        echo    'Loading Linux 3.12.5 ...'
        linux   /vmlinuz-3.12.5 root=UUID=cdd66e16-cfc0-4f98-99a0-3efc92fea00f ro  quiet
        echo    'Loading initial ramdisk ...'
        initrd  /initrd.img-3.12.5
}
[...]

Reboot the System

Assuming all was configured properly, we can now reboot the system to boot the new kernel:

# reboot

System will boot into the new kernel automatically:

$ uname -rvm
3.12.5 #1 SMP Sun Dec 15 17:18:55 GMT 2013 i686