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