1.3. Routine Kernel Recompilation

1.3.1. Source Extraction

The kernel source is stored in the /usr/src/linux directory tree, which is a symbolic link to the /usr/src/kernel-version directory. When extracting a new kernel source archive it is recommended to:

  • remove the symbolic link to the old kernel source directory tree

    rm linux

    Kernel sources which have been packaged as an RPM often create a link called linux-2-4

  • extract the new source archive (e.g linux-2.4.20.tar.bz2)

    tar xjf linux-2.4.29.tar.bz2
    [Note]Note

    The archived 2.2 series kernels create a directory called linux instead of linux-version. This is why the first step is important, otherwise you may overwrite an old source tree with the new one. Since kernel 2.4 the name of the directory is linux-version.

  • create a symbolic link called linux from the newly created directory

    ln -s linux-2.4.20 linux
  • The kernel is almost ready to be configured now, but first we need to make sure that all old binary files are cleared out of the source tree, and this is done with the make mrproper command.

    [Warning]Warning

    This command will also delete the kernel configuration file .config discussed later.

    cd /usr/src/linux
    make mrproper
    
    [Note]Note

    mrproper is a Scandinavian brand of cleaner that gets things "cleaner than clean", it is one step beyond "make clean"

1.3.2. Kernel Configuration

First edit the Makefile and make sure that the EXTRAVERSION variable is different from the existing version:

VERSION = 2
PATCHLEVEL = 4
SUBLEVEL = 20
EXTRAVERSION = -test

The kernel is now ready to be configured. This essentially means creating a configuration file called .config. This is done from the kernel source tree directory /usr/src/linux with any of the following:

  • make menuconfig

  • make xconfig

  • make config

All these methods will save the configuration file as /usr/src/linux/.config

It is often easier to configure a new kernel using an older .config file by using the make oldconfig command. This will prompt the user only for new features in the kernel source tree (if the kernel is newer or has been patched).

[Note]Note

Some distributions such as RedHat have a configs subdirectory containing files to be used as .config files with predefined configurations.

To enable kernel features (with make menuconfig) you will enter the top level category by moving with the arrow keys and pressing ENTER to access the desired category. Once in the particular category, pressing the SPACE bar will change the kernel support for a feature or driver.

Possible support types are:

  • supported (statically compiled) [*]

  • module (dynamically compiled) [M]

  • not supported [ ]

The same choices are available with the other menu editors config and xconfig.

[Note]Troubleshooting

The make menuconfig target needs the ncurses header files. These are provided by the ncurses-devel package and must be installed for this target to work

Figure 1.3. The make xconfig top level menu

The make xconfig top level menu

1.3.3. Kernel Compilation

make clean

The make command gets instructions from the Makefile and will build what is needed. If some files are already present make will use them as is. In particular files with *.o extensions. To make sure that all the configuration options in .config are used to rebuild the files needed one has to run make clean (this deletes *.o files).

[Note]Note

You do not need to do make clean at this stage if you already prepared the source directory with make mrproper

make dep

Once the kernel configuration is complete, it is necessary to reflect these choices in all the subdirectories of the kernel source tree. This is done with the make dep command. The files named .depend containing paths to header files present in the kernel source tree (/usr/src/linux/include) are generated this way.

[Note]2.6 Kernels

When compiling a 2.6 kernels the make dep stage doesn't exist

The kernel itself is compiled compiled with one of the commands:

make zImage
make bzImage

When the command exits without any errors, there will be a file in the /usr/src/linux/ directory called vmlinux. This is the uncompressed kernel.

Depending on the make targets above (zImage or bzImage) an additional file is created in /usr/src/linux/arch/i386/boot/ called zImage or bzImage respectively. These are compressed kernels. The zImage is compressed with gzip in an attempt to fit the kernel on a floppy disk. The bzImage kernel is a bigger zImage and allows users to create larger kernels without the size constraint of a floppy disk. See Section 1.3.4, “Installing a New Kernel” to find out how to proceed with these files.

make modules

The modules are compiled with make modules.

make modules_install

Once the modules are compiled they need to be copied to the corresponding subdirectory in /lib/modules. The make modules_install command will do that.

The sequence of commands are depicted in Figure 1.4, “Kernel compilation commands:”.

Figure 1.4. Kernel compilation commands:

make dep
make clean
make bzImage
make modules
make modules_install

Finally

make install

completes the installation by performing the following steps:

  • copy the kernel image to the corret location

  • update the bootloader with an entry for the new kernel

  • create if needed an initial root device

Instead of running this target we will perform these steps manually in the next section.

1.3.4. Installing a New Kernel

The new kernel can be found in /usr/src/linux/arch/i386/boot/bzImage, depending on your architecture of your system. This file must be copied to the /boot directory, and named vmlinuz-full-kernel-version.

cp /usr/src/linux/arch/i386/boot/bzImage  \ 
   /boot/vmlinuz-full-kernel-version

Next the /etc/lilo.conf or /boot/grub/grub.conf file needs to be edited to add our newly compiled kernel to the boot menu. Copy the image section from your existing kernel and add a new image section at the bottom of the file, as shown below:

Figure 1.5. Editing the /etc/lilo.conf file

prompt
timeout=50
message=/boot/message

image=/boot/vmlinuz
        label=linux
        root=/dev/hda6          #      Existing section
        read-only


image=/boot/vmlinuz-full-kernel-version
        label=linux-new
        root=/dev/hda6           #    Added section
        read-only

The symbol table for the various kernel procedures can be copied to the /boot directory:

cp /usr/src/linux/System.map \ 
        /boot/System.map-full-kernel-version

1.3.5. The Full Kernel Version

On a system, the version of the running kernel can be printed out with

uname -r

This kernel version is also displayed on the virtual terminals if the \k option is present in /etc/issue.

1.3.6. Initial Ramdisks

If any dynamically compiled kernel modules are required at boot time (e.g a scsi driver, or the filesystem module for the root partition) they will be loaded using an initial ramdisk.

The initial ramdisk is created with the mkinitrd command which only takes two parameters: the filename, and the kernel version number.

If you use an initial ramdisk then you will need to add an initrd= line in your /etc/lilo.conf

mkinitrd /boot/initrd-full-version.img full-version

1.3.7. Optional

It is recommended to copy the /usr/src/linux/.config file to /boot/config-full-kernel-version, just to keep track of the capabilities for the different kernels that have been compiled.

1.3.8. Re-installing LILO

Finally lilo needs to be run in order to update the boot loader. First lilo can be run in test mode to see if there are any errors in the configuration file:

[Important]Important

The LILO bootloader needs to be updated using lilo every time a change is made in /etc/lilo.conf