Chapter 18. Building a kernel

Table of Contents

18.1. Introduction
18.2. Configuration
18.3. Compilation
18.4. Installation

18.1. Introduction

The Linux kernel is shortly discussed in Section 2.1, “What is Linux?”. One of the advantages of Linux is that the full sources are available (as most of the Slackware Linux system). This means that you can recompile the kernel. There are many situations in which recompiling the kernel is useful. For example:

  • Making the kernel leaner: One can disable certain functionality of the kernel, to decrease its size. This is especially useful in environments where memory is scarce.

  • Optimizing the kernel: it is possible to optimize the kernel. For instance, by compiling it for a specific processor type.

  • Hardware support: Support for some hardware is not enabled by default in the Linux kernel provided by Slackware Linux. A common example is support for SMP systems.

  • Using custom patches: There are many unofficial patches for the Linux kernel. Generally speaking it is a good idea to avoid unofficial patches. But some third party software, like Win4Lin, require that you install an additional kernel patch.

  • Making the proper headers and build infrastucture available to build third-party modules.

This chapter focuses on the default kernel series used in Slackware Linux 12.0, Linux 2.6. Compiling a kernel is not really difficult, just keep around a backup kernel that you can use when something goes wrong. Linux compilation involves these steps:

  • Configuring the kernel.

  • Building the kernel.

  • Building modules.

  • Installing the kernel and modules.

  • Updating the LILO configuration.

In this chapter, we suppose that the kernel sources are available in /usr/src/linux. If you have installed the kernel sources from the “k” disk set, the kernel sources are available in /usr/src/linux-kernelversion, and /usr/src/linux is a symbolic link to the real kernel source directory. So, if you use the standards Slackware Linux kernel package you are set to go.

In contrast to older kernel versions, it is not necessary to use a /usr/src/linux symbolink anymore. If you have extracted newer kernel sources in /usr/src, you can build the kernel in /usr/src/linux-<version>, and use that directory in the examples in this chapter.

18.2. Configuration

As laid out above, the first step is to configure the kernel source. To ease the configuration of the kernel, it is a good idea to copy the default Slackware Linux kernel configuration to the kernel sources. The Slackware Linux kernel configuration files are stored on the distribution medium as kernels/<kernelname>/config. Suppose that you want to use the hugesmp.s kernel configuration as a starting point (which is the default kernel), and that you have a Slackware Linux CD-ROM mounted at /mnt/cdrom, you can copy the Slackware Linux kernel configuration with:

# cp /mnt/cdrom/kernels/hugesmp.s/config /usr/src/linux/.config
    

The kernel configuration of a running kernel can also be retrieved as /proc/config.gz if the kernel was compiled with the CONFIG_IKCONFIG and CONFIG_IKCONFIG_PROC options. The default Slackware Linux kernels have these options enabled. So, if you would like to use the configuration of the running kernel, you could run:

# zcat /proc/config.gz > /usr/src/linux/.config
    

If you are using a configuration file that is for another kernel version than you are currently compiling, it is likely that both kernel versions do not have the same set of options. New options are often added (e.g., because newer drivers are added), and sometimes kernel components are removed. You can configure new options (and remove unused options) with the make oldconfig command:

# cd /usr/src/linux ; make oldconfig

This will ask you for options whether you would like to compile in support (Y), compile support as a module (M), or not include support (N). For example:

IBM ThinkPad Laptop Extras (ACPI_IBM) [N/m/y/?] (NEW)
    

As you can see, the possible options are shown, with the default choice as a capital. If you just press <Enter>, the capitalized option will be used. If you want more information about an option, you can enter the question mark (?):

    IBM ThinkPad Laptop Extras (ACPI_IBM) [N/m/y/?] (NEW) ?

This is a Linux ACPI driver for the IBM ThinkPad laptops. It adds
support for Fn-Fx key combinations, Bluetooth control, video
output switching, ThinkLight control, UltraBay eject and more.
For more information about this driver see <file:Documentation/ibm-acpi.txt>
and <http://ibm-acpi.sf.net/> .

If you have an IBM ThinkPad laptop, say Y or M here.

    IBM ThinkPad Laptop Extras (ACPI_IBM) [N/m/y/?] (NEW)
    

The output of this command can be a bit verbose, because the options that were used in the configuration file, and are available in the running kernel are also shown, but their configuration will be filled in automatically based on the configuration file.

At this point you can start to actually configure the kernel in detail. There are three configuration front-ends to the kernel configuration. The first one is config, which just asks you what you want to do for each kernel option. This takes a lot of time. So, normally this is not a good way to configure the kernel. A more user friendly approach is the menuconfig front-end, which uses a menuing system that you can use to configure the kernel. There is an X front-end as well, named xconfig. You can start a configuration front-end by changing to the kernel source directory, and executing make <front-end>. For example, to configure the kernel with the menu front-end you can use the following commands:

# cd /usr/src/linux
# make menuconfig
    

Of course, if you prefer, you can also edit the .config file directly with your favorite text editor.

As we have seen briefly before, in the kernel configuration there are basically three options for each choice: “n” disables functionality, “y” enables functionality, and “m” compiles the functionality as a module. The default Slackware Linux kernel configuration is a very good configuration, it includes the support for most common disk controllers and filesystems, the rest is compiled as a module. Whatever choices you make, you need to make sure that both the driver for the disk controller and support for the filesystem type holding your root filesystem is included. When they are not, the kernel will not able to mount the root filesystem, and the kernel will panic because it can not hand over initialization to the init program.

[Note] Note

It is always a good idea to keep your old kernel in modules around, in the case that you have made a configuration error. If the to be compiled kernel has the same version number as the running kernel, you should seriously consider modifying the CONFIG_LOCALVERSION option. The string specified in this option is appended to the version name. For example, if the kernel has version 2.6.21.6, and CONFIG_LOCALVERSION is set to "-smp-ddk", the kernel version will be 2.6.21.6-smp-ddk.

If you don't modify the version in this manner, the installation of modules from the new kernel will overwrite the modules from the running kernel. This is highly uncomfortable if you need to fall back to the old kernel.

18.3. Compilation

The kernel compilation used to consist of multiple steps, but 2.6 Linux kernels can be compiled be executing make in the kernel source directory. This will calculate dependencies, build the kernel, and will build and link kernel modules.

# cd /usr/src/linux
# make
    

After the compilation is finished, the tree contains the compiled modules, and a compressed kernel image named bzImage in /usr/src/linux/arch/i386/boot. You can now continue with the installation of the kernel and its modules.

18.4. Installation

18.4.1. Installing the kernel

The next step is to install the kernel and the kernel modules. We will start with installing the kernel modules, because this can be done with one command within the kernel source tree:

# make modules_install
      

This will install the modules in /lib/modules/<kernelversion>. If you are replacing a kernel with the exactly the same version number, it is a good idea to remove the old modules before installing the new ones. E.g.:

# rm -rf /lib/modules/2.6.21.5-smp
      

You can “install” the kernel by copying it to the /boot directory. You can give it any name you want, but it is a good idea to use some naming convention. E.g. vmlinuz-version. For instance, if you name it vmlinuz-2.6.21.5-smp-ddk, you can copy it from within the kernel source tree with:

# cp arch/i386/boot/bzImage /boot/vmlinuz-2.6.21.5-smp-ddk
      

At this point you are almost finished. The last step is to add the new kernel to the Linux boot loader (LILO) configuration.

18.4.2. Configuring LILO

LILO (Linux Loader) is the default boot loader that Slackware Linux uses. The configuration of LILO works in two steps; the first step is to alter the LILO configuration in /etc/lilo.conf. The second step is to run the lilo, which will write the LILO configuration to the boot loader. The LILO configuration already has an entry for the current kernel you are running. It is a good idea to keep this entry, as a fall-back option if your new kernel does not work. If you scroll down to the bottom of /etc/lilo.conf you will see this entry, it looks comparable to this:

# Linux bootable partition config begins
image = /boot/vmlinuz
  root = /dev/hda5
  label = Slack
  read-only # Non-UMSDOS filesystems should be mounted read-only for checking
# Linux bootable partition config ends
      

The easiest way to add the new kernel is to duplicate the existing entry, and then editing the first entry, changing the image, and label options. After changing the example above it would look like this:

# Linux bootable partition config begins
image = /boot/vmlinuz-2.6.21.5-smp-ddk
  root = /dev/hda5
  label = Slack
  read-only # Non-UMSDOS filesystems should be mounted read-only for checking

image = /boot/vmlinuz
  root = /dev/hda5
  label = SlackOld
  read-only # Non-UMSDOS filesystems should be mounted read-only for checking
# Linux bootable partition config ends
      

As you can see the first image entry points to the new kernel, and the label of the second entry was changed to “SlackOld”. LILO will automatically boot the first image. You can now install this new LILO configuration with the lilo command:

# lilo
Added Slack *
Added SlackOld
      

The next time you boot both entries will be available, and the “Slack” entry will be booted by default.

[Note] Note

If you want LILO to show a menu with the entries configured via lilo.conf on each boot, make sure that you add a line that says

prompt
	

to lilo.conf. Otherwise LILO will boot the default entry that is set with default=<name>, or the first entry when no default kernel is set. You can access the menu with entries at any time by holding the <Shift> key when LILO is started.