Techniques for upgrading and customizing the Linux kernel
If you work with third-party hardware drivers, or even if you just need to fix a broken system, someday you might need to upgrade the Linux kernel.
A technical expert will tell you that the kernel is the Linux – the Hardware Abstraction Layer and everything else you see on your screen is mostly application software from the GNU collection. Linux is the operating system core that makes a computer usable in a Unix-like way. On the technical level, a kernel consists of the following basic components:
- support for hardware and corresponding drivers;
- a so-called scheduler, which distributes available computing power (CPU cycles) and hardware resources among application programs, thus allowing the programs to run independently of each other without causing deadlocks or conflicts;
- a virtual memory and filesystem manager that makes memory and disk space available to programs.
Most users just accept the kernel that comes with their Linux distro without seriously tinkering with it. However, if you happen to need a driver or system component that isn't built into your Linux system, or even if you just like tinkering, you might one day face the task of replacing, rebuilding, or extending the kernel running on your system. In this article, I describe some techniques for working with the Linux kernel.
Kernel 2.6.28 is released, and when you read through the changelogs, you notice a vast number of bug fixes and feature enhancements that create an impression of huge performance and stability benefits with a simple package update. Unfortunately, the reality is not quite so simple. Because of the rapid kernel development process, new releases appear almost every month. Most new releases do not provide a major change unless you are looking for something very specific. And, even if a new component or subsystem is announced in the news, it is unlikely that you will find the latest kernel version ready to install in your distro's repository. Most distributions provide stable and well-tested snapshots that might contain some selected new features and improvements of newer releases but keep the old version number for compatibility with third-party modules. If you are looking for the newest (and probably not well-tested) version, you will have to compile the kernel yourself.
Why would anyone even bother to upgrade the Linux kernel? If you spend a lot of time hacking your Linux system, you might find yourself needing to repair a system that broke because you forgot to activate an important option. Or, in some cases, a new kernel might contain a driver or support a module that offers improved hardware support. In other situations, the update might address an urgent security problem.
Checking Kernel Version
To find out which kernel is currently running on your system, open a shell and type
which should output something such as:
Linux eeepc 220.127.116.11-eeepc #13 PREEMPT Thu Oct 9 04:04:42 CEST 2008 i686 GNU/Linux
provides additional information on the compiler used to build the kernel.
As you will learn, this information comes in handy when you are working with kernel modules:
Linux version 18.104.22.168-eeepc (knopper@Koffer) (gcc version 4.3.2 (Debian 4.3.2-1) ) #13 PREEMPT Thu Oct 9 04:04:42 CEST 2008
The preceding output reveals several facts about the system:
- The kernel is in the 2.6 kernel series.
- The minor release version is 26.
- The patch level (mostly for bug fixes) is 5.
- It was presumably compiled for an Eee PC system, although this setting can be any text string specified as EXTRAVERSION in the kernel Makefile.
- The system architecture is based on i686, which supports the machine instruction sets of Pentium 2 and higher, but not older 386- or 486-based computers.
- The GCC compiler version used when compiling the kernel from its source was version 4.3.2 on a Debian system. The resulting binary was the 13th time the compiler was run for this source, and the compile was performed on Thursday October 9, 2008.
- This kernel is preemptible. That is, the system is optimized as a desktop system with a quick interactive response rather than as a compute server.
This detailed information on the state of the current system provides a starting point for understanding how to proceed with a kernel upgrade.
Hard Disk Drivers
For some hardware, two alternative drivers might both work fine, but you still have to choose one of them. IDE hard disk controllers, for instance, work with both the traditional IDE block device drivers and the newer PATA interface, which is connected to SATA. For controllers that have both SATA and IDE ports, the SATA/PATA combination is most likely the best choice. Enabling both the IDE and SATA/PATA driver at the same time for the same controller can sometimes work: As soon as interrupt and I/O resources are blocked by one driver, the other driver silently fails. Sometimes it does not go so well, and each driver block parts of the other, so direct memory access (DMA) becomes unavailable, hard disks slow down or disappear, or timeouts and resets occur.
If you decide to use the SATA/PATA driver for a hard disk controller instead of the IDE driver you used before, make sure to change /dev/hda to /dev/sda in /etc/fstab because PATA treats IDE hard disks like SCSI disks. The same precaution applies to the root=/dev/hda1 lines in the lilo.conf or menu.lst bootloader files.
Most Linux distributions provide an easy means for upgrading the kernel through a package management system. If you don't need a customized or optimized kernel, updating the kernel through your distro's package system is often much easier than compiling and manually installing the kernel on your own.
Here, I describe how to upgrade your kernel through the Debian-based Aptitude package management system. The concepts are similar for other systems. If your distro uses an alternative package tool, consult the vendor documentation.
The Debian kernel packages used to have the name kernel-image. This name has recently changed to linux-image. Command-line gourmets will prefer to install the new kernel image with a text-based command
aptitude install linux-image-686
instead of with a GUI-based package manager; in either case, the steps executed are basically the same:
- The package is decompressed and unpacked into a new location. The static part of the kernel goes to /boot/vlinuz-versionnumber-architecture; kernel modules go to /lib/modules/versionnumber.
- Scripts check to see whether an initial ramdisk is necessary for your system; if it is, the necessary modules are set up in a file called /boot/initrd.img-versionnumber-architecture. The system tool mkinitramfs is responsible for this step. Its configuration files are at /etc/initramfs-tools/*, which is where you will go to make certain configuration changes, such as changing the ramdisk configuration. Unless the module names have changed, or unless you plan to activate software RAID or LVM, you should not have to do much there on your own.
- The bootloader is made aware of the new kernel as a choice for booting. Unless the old kernel is removed (which should not happen automatically), it will still be in the bootloader configuration file, which allows you to switch back to the old kernel interactively as the system starts.
Before you reboot the system, check the following:
- Did you previously have to install or recompile additional kernel modules for the system to start? In the rare case that your primary boot medium controller needs a driver that is not part of the kernel or ramdisk, you will have to compile and install the necessary module before you reboot; otherwise, it might be difficult to get the system up and running with the new kernel.
- Is the bootloader correctly prepared for the new kernel? For instance, LILO (the Linux Loader – one of the first filesystem-independent bootloaders for Linux) should have entries similar to Listing 1 in the /etc/lilo.conf file.
01 image=/vmlinuz 02 initrd=/initrd.img 03 label=Linux 04 image=/vmlinuz.old 05 initrd=/initrd.img.old 06 label=Linux -old
If you are using the GRUB bootloader, the /boot/grub/menu.lst file will need entries similar to those in Listing 2.
01 title=Linux 02 root (hd0,0) 03 kernel /vmlinuz 04 root=/dev/hda1 05 initrd /initrd.img 06 07 title=Linux-old 08 root (hd0,0) 09 kernel /vmlinuz.old root=/dev/hda1 10 initrd /initrd.img.old
In Listing 1, note that /vmlinuz.old and /initrd.img.old are symbolic links to the old but still-existing kernel and initrd files in /boot. This approach makes it possible to boot the old kernel if the new one isn't working as expected. If you change /etc/lilo.conf manually, run the lilo command as root before rebooting, because the LILO bootloader needs to update its record of the kernel file location. The GRUB bootloader, on the other hand, can find the files on its own using its own filesystem driver.
If it seems that your system is ready for the new kernel, reboot to see that everything works. If the new kernel doesn't start for some reason, select the old kernel in the boot menu to restore the previous configuration.
The kernel has some interactive qualities – you can boot the system with the use of kernel options that affect the way some part of the kernel works and even change certain kernel settings during run time without rebooting. Technically oriented users often enjoy just browsing through the new kernel's options to look for new settings to play with.
Buy this article as PDF