Recompiling the kernel


 

 

 

 

 

Introduction to this web page

This web page is about recompiling the kernel on Red Hat Linux 9 - the recompiling was started as an experiment in order to see if the performance of the firewall could be improved - ie - improving the speed of wanted packets through the firewall.

However it turned out to be a rather complicated process, so most of the information in this web page is general information about recompiling the kernel in Red Hat Linux 9, rather than configuring a kernel specifically for use in a network firewall.

 

Problems

There have been a lot of problems in trying to do this recompilation, such as :-

  • The stuff written in books about recompiling the kernel is either so lacking in information that it would have been better not putting it in at all, or the instructions given have the steps in the wrong order.

  • There are a lot of steps to be taken to recompile a kernel, I haven`t found any book or documentation that has them all.

  • Red Hat doesn`t use standard kernels, it hacks them quite a lot. Red Hat Linux 9 uses kernel version 2.4.20-8 - this is a modified version of 2.4.20. So if you want to recompile the kernel on Red Hat Linux 9, you either have to work out all the patching required on standard kernels, or stick with Red Hat provided kernels. It is also possible that Red Hat have hacked the kernel in their own way, ie, not just through standard kernel patches.

  • I had problems with the compilation process producing corrupted folders, and having to manually run "fsck" to clear several hundred file system errors, including a lot of inode errors. I tried running Linux on both an ext2 filesystem, and on an ext3 filesystem, but it didn`t make any difference. Eventually I installed a new hard drive, and started with a new installation of Red Hat Linux 9 - this cured the problem.

  • I also had several occurences of a problem with X-Windows - I don`t normally use the Gnome desktop much, I normally work from the command line in Run Level 3. However in order to use xconfig, it is neccessary to use an X-Windows environment. If "startx" is used fairly soon after starting up Linux, it loaded okay. But if I had been using Run Level 3 for some time, and then ran "startx" to run Gnome, the X-windows startup failed, and it was difficult to get Linux out of its hung state. And once X-Windows had hung once, it was corrupted, and wouldn`t run again, even after a reboot.

 

Introduction to the recompiling process

What follows is a step by step procedure for recompiling the kernel that worked for me. It is based on recompiling the 2.4.20-8 kernel that Red Hat Linux 9 is built on.

It is nearly all done through the command line environment, and extensively uses an application called "Make".

Make is a project management tool, that can be used for various kinds of software development projects, usually involving the C programming code.

Make uses a series of instructions contained in "Makefiles", and these Makefiles are written by the kernel developers, and are bundled with the kernel source code, one Makefile per folder.

Make uses several applications and services that must be installed on the computer :-

  • gcc - the GNU version of the cc compiler

  • tcl and tk - needed for the GUI based configuration tool "xconfig"

  • GUI environment - again, needed for xconfig

There are without doubt several others, but these ones are ones I have met so far.

You can do the whole compilation process without a GUI environment, but xconfig is the easiest configuration tool to use, out of the three that are available.

The easiest way to set up Linux so that it is possible to do kernel recompilation is to install the "Development Tools" option when doing the Linux installation - this installs the compiler software.

As said above, the processes listed here are based on the use of the 2.4.20-8 kernel supplied with Red Hat Linux 9. The source code for this kernel is loaded during the installation of Red Hat Linux 9 provided you also install the "Kernel Development" option, and once loaded, it can be found in /usr/src/linux-2.4.20-8. This option also installs the tk GUI toolkit for tcl.

It is not a good idea to base the recompilation process on the /usr/src/linux-2.4.20-8 folder in case it gets corrupted. So the source code is copied, and worked on elsewhere.

 

Summary of the recompiling process

Here is the whole compilation process in summary - there`s quite a lot to it, and you have to work very methodically to end up with a successful recompilation.

    cd /

    mkdir /kernel/

    cp -r /usr/src/linux-2.4.20-8 /kernel/

    cd /kernel/

    mv linux-2.4.20-8 linux-2.4.20-new

    cd linux-2.4.20-new

    vi Makefile

    make clean

    make mrproper

    cd /boot

    cp config-2.4.20-8 /kernel/linux-2.4.20-new/.config

    cd /kernel/linux-2.4.20-new

    make config / menuconfig / xconfig

    make dep

    make bzImage

    cp arch/i386/boot/bzImage /boot/vmlinuz-2.4.20-new

    make modules

    make modules_install

    mkinitrd /boot/initrd-2.4.20-new.img 2.4.20-new

    cd /etc

    vi grub.conf   

Apart from methodically working through the whole process, you also have to be careful with the naming convention you use to name new folders or files. The compilation process expects a particular naming convention, and will fail if it isn`t followed.

For a start, you can`t use the string "2.4.20-8", as a kernel has already been built with names based on that string.

There has to be a match between the string used in folder and file names, and the information inserted into Makefiles or other configuration files.

The process described here is performed around the string "2.4.20-new" as the string which identifies this particular kernel build.

 

The compilation process in detail

Here is the reasoning behind all the steps in the compilation process shown above in summary.

My preference is to build new kernels well away from the original source code, so I create a new folder "/kernel" in the root of the file system, and then build in that.

    cd /   
    mkdir /kernel/   

Copy the original source code from /usr/src into the new folder.

    cp -r /usr/src/linux-2.4.20-8 /kernel/   

Change context to the new /kernel/ folder, and rename the source code folder to a name that uses our chosen identification string.

    cd /kernel/   
    mv linux-2.4.20-8 linux-2.4.20-new   

All the steps that involve Make must be initiated from the root folder of the source code folder structure, so we need to change directory to that root folder.

    cd linux-2.4.20-new/   

Located in this root folder is the highest level Makefile - we have to edit it so that it contains the same identity as our chosen "2.4.20-new" string.

Open the Makefile in your favourite text editor ( I use vi )

    vi Makefile   

Change the fourth line that reads

    Extraversion = -8custom  

so that it says

    Extraversion = -new  

Save and exit.

Having set up the Makefile so that it knows the identity of this new kernel version, we can start using Make. We first of all need to clean up the source code to get rid of any files that may exist from a previous compilation process.

As an aside, if you look inside the Makefile with a text viewer, about a quarter way through the Makefile, you will see the set of instructions that Make follows, when processing the "make clean" and the "make mrproper" commands.

    make clean   
    make mrproper   

Having cleaned up the source code, we now have to think about how we want the kernel to be configured.

The configuration file contains a large number of settings, many of these are critical to the operation of the kernel, or to the running of Linux. So it is best to start with a known working set. We can extract the existing set from a file in the /boot/ folder, and use this as our starting point.

    cd /boot/   
    cp config-2.4.20-8 /kernel/linux-2.4.20-new/.config   

As before, we have to do every Make function from the root folder of the source code.

    cd /kernel/linux-2.4.20-new   

We now have a start point for our configuration in the .config file.

And we now have a choice of tools to use for doing our configuration :-

  • make config

  • make menuconfig

  • make xconfig

The first one, "make config", is not recommended, you can`t backtrack if you want to change your mind about a setting.

The second one, "make menuconfig", works okay, settings are made through key strokes, and starts by default by importing the existing .config file. It also defaults to saving to the .config file, so will overwrite the original .config file. You can choose to save elsewhere.

The third one, "make xconfig", uses X-windows, and has to be run from the terminal screen in the Gnome desktop. Running it from the command line fails. Remember to change context in the Terminal window to /kernel/linux-2.4.20-new before running "make xconfig". It is slightly easier to use than "make menuconfig". By default it saves to the .config file, but also produces a .config.old file, so that the original .config file is preserved under a different name.

So by one of these means, the configuration of the kernal can now be setup.

Because my interest is in the performance of the kernel in a firewall, I removed support for things like sound, firewire, Amateur Radio, IrDA, Bluetooth, and ISDN.

    make config / menuconfig / xconfig   

Fortunately, the kernel developers don`t trust us to configure a kernel correctly, so we now run a command to check that our configuration doesn`t have obvious problems. It doesn`t correct all problems, however, so don`t rely on it. The command "make dep" can take several minutes to finish.

    make dep   

Now we get to the actual compilation of the "C" source code into a composite kernel. With this command we are producing a compressed kernel. The compilation can take minutes or hours depending on the speed of the computer and the size of the kernel.

    make bzImage   

The compilation process places the compressed image in the /kernel/linux-2.4.20-new/arch/i386/boot/ folder. We need to copy this new image to the /boot/ folder, so that it can be used for running Linux.

We also need to rename it in the /boot/ folder, so we can do both things at once. Note the same text string as before is used to identify this kernel in the /boot/ folder

    cp arch/i386/boot/bzImage /boot/vmlinuz-2.4.20-new   

Having done the kernel itself, we now have to compile all the kernel modules. Once again, Make does the work for us. This compilation process places all the resultant .o object files in the same folders as the source code .c files from which the .o file is produced. Again this can take minutes or hours depending on how many kernel modules you are compiling, and the speed of your computer.

    make modules   

The kernel needs to have these modules located in a specific place in order to find and use them. Once again Make does this for us - it copies the .o files to /lib/modules/2.4.20-new/, and creates the required folder structure below this folder.

We don`t have to create the folder /lib/modules/2.4.20-new/, Make creates it, and of course it uses the same text string as before to identify it.

    make modules_install   

We now have to create an initial ramdisk for use during booting up. This process will fail if the required modules are not correctly located in the specified /lib/modules/ sub folder.

The resultant .img file is placed in the /boot/ folder ready for use.

    mkinitrd /boot/initrd-2.4.20-new.img 2.4.20-new   

We should now have the kernel and .img file in the /boot/ folder, and the kernel modules stored in /lib/modules/. The kernel is now ready for use, the last step is to edit the Grub configuration file so that it appears as an option, or as the default boot-up kernel.

The Grub configuration file is "/etc/grub.conf", so this is opened with your favourite text editor, and another section added to this file. I used vi.

    cd /etc   
    vi grub.conf   

If your Linux installation is fairly standard, there should be a section of four lines which refer to the existing kernel. Copy these four lines, and change them so that the four lines become eight, and should say :-

    title Red Hat Linux (2.4.20-8)
           root (hd0,0)
           kernel /vmlinuz-2.4.20-8 ro root=LABEL=/
           initrd /initrd-2.4.20-8.img
    title Red Hat Linux (2.4.20-new)
           root (hd0,0)
           kernel /vmlinuz-2.4.20-new ro root=LABEL=/
           initrd /initrd-2.4.20-new.img   

Save and exit.

Reboot and try the new kernel !!!!

 


© 2004 Ron Turner


Return to the Index page