7.2. Recompiling the Kernel
The thought of recompiling the kernel strikes fear into far too many Linux geeks. While you have to perform each step in order and wait for the process to finish, and while mistakes can force you to try again or backtrack to an earlier kernel, the process is not as bad as it seems. Assuming that you have the source code and tools installed, as described in the previous annoyance, you can just follow the basic steps I describe here. Variations are possible, depending on your kernel version and distribution. For more information, see the README file in the directory with your source code, usually /usr/src/linux. (For Fedora Core 3 and above, the standard source code directory is a subdirectory of /usr/src/redhat/BUILD.)
7.2.1. Configuring the Kernel
The following are general steps associated with getting to the kernel customization menu. Depending on your configuration, there may be variations:
Navigate to the directory with the kernel source. If you've compiled your kernel in the past, you should have a .config file in this directory. If you want to start over, you can delete this .config file and make sure that the source code is clean with the following command:
Create a .config file in the local directory. If you're recompiling the current kernel, just copy it from the config-`uname -r` file in the /boot directory. For example, if your current kernel is version 2.6.11, run the following command:
cp /boot/config-2.6.11 /usr/src/linux/.config
When you include the `uname -r` string in another command, it embeds the version number of the current kernel. It's useful, as many kernel-related files and directories use the version number of the current kernel.
Customize the Makefile in the directory with your source code. Modified correctly, this helps identify the new kernels that you create. The key is the fourth variable in the Makefile, EXTRAVERSION, which gets appended to the end of the new kernel files. On my Debian computer, I've set EXtrAVERSION to -mj1; when I modified my 2.6.8 Linux kernel, the new kernel was named vmlinuz-2.6.8-mj1. If I recompile this kernel again for different features, I'd change EXTRAVERSION to -mj2; that kernel would be named vmlinuz-2.6.8-mj2.
Now you can modify the kernel as needed. With the thousands of options available, it's more efficient to make modifications with a graphical interface. If you have the proper ncurses development libraries installed, you can start a menu similar to Figure 7-1 with the make menuconfig command.
Figure 7-1. The ncurses kernel menu
If you're running GNOME and have one of the libraries described in the previous section installed, you can start a menu similar to that shown in Figure 7-2 with the make gconfig command.
Figure 7-2. The gconfig kernel menu
If you use the KDE desktop and have the QuickTime libraries, you can open the qconf kernel configuration menu shown in Figure 7-3 with the make xconfig command. (The xconfig menu had a substantially different look and feel for kernel version 2.4.)
Figure 7-3. The xconfig kernel 2.6 menu
With SUSE, you need to set the environment and display defaults to correspond to the root account before opening a kernel configuration tool with the make xconfig or make gconfig commands. If you've logged in to the SUSE GUI with a normal account, open a command-line terminal interface and log in to the root account with the following command, which transfers your account's X environment directives to root for this session:
# sux - root
Now you can customize the kernel with the settings of your choice. Unless you're working with an embedded device, you should almost always enable loadable module support. You then have three choices for many features: to exclude it, compile it into the core kernel, or compile it as a module.
The variety of options in kernel configuration is annoying, and unfortunately beyond the scope of this book. An advantage of reusing the /boot/config-`uname -r` file is that you can probably get away with just adding a single module or making a few limited changes (hopefully well documented by a README file when you downloaded the kernel or patch). When you save your settings, you're creating a new .config file. Once compiled, the result should be saved to the /boot directory.
This is where the Debian process diverges from the commands you can use on Red Hat/Fedora and SUSE; I'll describe both processes in the following sections. In either case, the commands required to compile the kernel can take several minutes, or even hours, depending on your hardware.
7.2.2. Preparing the Source for Fedora/Red Hat
Starting with Fedora Core 3, Red Hat has eliminated the kernel-source package. But you can build the source code from the source RPM, which is called kernel-`uname -r`.src.rpm in the SRPMS directory.
For example, if you download the original kernel source .src.rpm for Fedora Core 3 (version 2.6.9-1.667), you need to take the following steps to get to the kernel customization menu:
Install the source RPM with the rpm -ivh kernel-2.6.9-1.667.src.rpm command.
Navigate to the directory with the kernel SPEC filenormally, /usr/src/redhat/SPECS.
Build the source code. The following command builds it in an appropriate directory. The `uname -m` option provides the architecture associated with your system:
rpmbuild -bp --target=`uname -m` /usr/src/redhat/SPECS/kernel-2.6.9-2.6.spec
Install the development tools. The easiest way to do so is by installing the Development Tools package group via the system-config-packages or pirut utility.
Install the graphical tools required for the kernel configuration tool of your choice. Generally, if you use the GNOME Desktop Environment, run make gconfig, which requires the GNOME Development Tools package group. If you use the KDE Desktop Environment, run make xconfig, which requires the KDE Development Tools package group.
Whatever distribution you use, many packages assume that your source code is in the /usr/src/linux directory. If your distribution uses a different directory, it can help to create a symbolic link from /usr/src/linux to the directory with the kernel source code.
7.2.3. Processing a Red Hat/Fedora or SUSE Kernel
Once the kernel is configured, you can start the build process. Once you've customized your .config kernel configuration file, the following are basic steps associated with recompiling the kernel. Depending on your configuration, there may be variations:
The following command checks your .config settings against any dependencies and processes your kernel source code accordingly:
Before you start compiling the source code, it's a good idea to make sure no files exist from previous builds with the following command. Otherwise, they might get mixed in with your new build and cause havoc:
Now you can compile your source code into a binary kernel. The following command creates a binary kernel in the arch/i386/boot subdirectory. If you have something other than a 32-bit CPU, the directory name will contain a string denoting that processor in place of i386:
Assuming you've configured loadable modules, you'll need to process and install the modular drivers associated with your new kernel:
make modules make modules_install
You should find your newly customized modules in the /lib/modules/`uname -r` directory.
Finally, you're ready to process your new kernel. The following command creates an Initial RAM disk, copies it and the new kernel to your /boot directory, and updates the active bootloader:
Naturally, you should check the result in the /boot (and in some cases, the top-level root) directory, as well as in your bootloader configuration file. If the bootloader configuration was not updated, you can do it yourself using the information in Chapter 6.
7.2.4. Processing a Debian Kernel
The Debian kernel build process is relatively simple because it involves making your own custom Debian package; most of the grunt work is done for you automatically by this package. This section of the chapter assumes you've modified your .config file with one of the kernel configuration tools described earlier. The following are basic steps associated with recompiling a Debian kernel:
Install the Debian package known as kernel-package, which includes a number of scripts that can help process the Debian kernel. Then run the following command to create a Debian kernel package:
make-kpkg buildpackage -rev mine kernel-image
If this is successful, you'll find your package with a .deb extension in your /usr/src directory. In my case, I found the kernel-image-2.6.8-mj1_mine_i386.deb package in that directory. (Debian Etch uses the linux-image package name.)
Install the kernel package with the following command:
dpkg -i kernel-image-2.6.8-mj1_mine_i386.deb
Make sure this command updates your active bootloader in the appropriate configuration file. Alternatively, you can update the bootloader configuration file yourself using the information in "Rooting Out the Bootloader" in Chapter 6.
Make sure this command updates the soft links from the top-level root directory (/) for the Initial RAM disk and the kernel (vmlinuz). As an example, the following lines are excepts from an ls -l command on my Debian computer (dates have been removed due to line space constraints):
lrwxrwxrwx 1 root root 22 vmlinuz -> boot/vmlinuz-2.6.8-mj1 lrwxrwxrwx 1 root root 24 vmlinuz.old -> boot/vmlinuz-2.6.8-1-386
If any of these files point to the wrong kernel, that can lead to one of the most annoying problems of all, a kernel panic. This is the subject of the following annoyance.