Compiling the Linux Kernel

At the time I was writing this article, the Linux kernel 2.4.17 was released only 3 days ago and these holly days you may find some more time to experiement with it. The following article includes step-by-step instructions on how to compile a Linux 2.4.X kernel, an article mostly targetting people who have never dared to compile their own kernel yet. Read on and we promise, it is not that hard to do so.First of all, let’s start by mentioning only some of the reasons why you may want to upgrade your current stock kernel, which possibly came pre-compiled and pre-configured by your Linux distribution:

  • You can enable optimizations which can make your kernel faster (for example, if you have a PII, you can specifically compile for ‘i686’ a way which can take advantage of PII’s special instruction set and/or capabilities).

  • Suddenly, it may become known that a security or other important vulnerability/bug was discovered in your current version of your kernel, which does not leave you other choice but to upgrade your kernel to a version that has fixed the problem.

  • To support more specific hardware that your stock kernel does not support by default.

  • To take advantage of the new features or driver versions that a newer kernel has to offer.

  • To apply specific patches that are not part of the standard kernel feature set, but you feel that you want to toy with.

  • To compile the kernel with only the hardware setup of your machine (instead of the full spectrum of support that comes with stock kernels) so your kernel file will be smaller and maybe even faster.

  • The first thing you have to do is to download the source code of the new kernel from or one of its mirror web sites, in order to compile it. These days, the Linux kernel .tar.gz file is about 30 MB (130 MB uncompressed), so if you are on a slower connection, it will take a while to download. The tarball above is so big because it contains in it (along with the main kernel code) all the drivers for all the Linux-supported devices, a number of devices that, naturally and thankfully, grows to be bigger and bigger as the time passes. When you finish compiling your own custom kernel as shown below, you will discover that the newly produced kernel is actually pretty small compared to the source code tarball you downloaded.

    Step 1. Let’s make a boot disk of the existing system, so if we are unsuccesfull with our upgrade, at least we will have a bootable disk to boot up with, log into the system and fix any mistakes we made. To make a bootable floppy disk of your current Linux system type:

    mkbootdisk –device /dev/fd0 x.x.x

    This assumes some things. Your floppy drive needs to be already “mounted” in the Linux filesystem in order to be able to write in the floppy disk. You need to substitute your kernel version for x.x.x. An example would be something like 2.4.8 for a stock distribution, or 2.4.8-5mdk for Linux Mandrake 8.1 etc. You can look up which version you have on some programs with the relevant information screen or under the /usr/src/ folder.

    Step 2. We assume you downloaded kernel version 2.4.17. Now, let’s extract the tarball:

    tar -zxvf linux-2.4.17.tar.gz

    This will extract the above tarball to a folder called ‘linux’ in your working directory (for example, if you extracted this under /home/JoeUser/ the extracted files will be found on /home/JoeUser/linux/).

    Step 3. Now we will have to move the ‘linux’ directory to a more appropriate place in the Linux filesystem. From now on, you may want to become the super user called ‘root’ (give the command on the terminal: su –) in order the system to allow you to perform the rest of the steps. Also, do not forget that Linux is case sensitive, so make sure you enter the commands in the terminal exactly as shown (without any quotes though).

    mv linux /usr/src/linux-2.4.17

    and then:

    cd /usr/src/linux-2.4.17

    Step 4. If you want to patch your kernel with some additional patches/features that do not come with the default kernel, for example, Alan Cox’s low latency patches, or the preemptible patch (which improves the UI responsiveness), or if you want to add support for the XFS or Be’s BFS filesystems, this is the time to do it:

    gzip -cd /path_of_the_patch/filename_of_the_patch.gz | patch -p0


    bzip2 -dc /path_of_the_patch/filename_of_the_patch.bz2 | patch -p0

    Depending with what the author of the patch has compressed his patches, it will be either .gz or .bz2, so pick the appropriate one.

    Step 5. This is the most tricky part of the whole attempt. Type:

    make xconfig

    (or ‘make menuconfig‘ if you prefer text mode, but the xconfig is recommended).

    This will compile and load for you the ‘xconfig’ program where you will be able to choose which modules and configuration you want for your new kernel. Be careful, to choose the exact hardware you have, because if you are not sure what hardware you are running on (motherboard chipset, cpu model, if you want multiprocessing (SMP) or not, exact ide/scsi controller models, sound card chipsets and even revisions, tv card chipsets etc etc) you better stop right here. If you do know your hardware configuration better than your own palm, pick from all the screen presented to you the hardware you have and uncheck the ones you don’t have (however, do leave unchanged some of the ‘weird’ options if you are not sure if you have such hardware or not). Some of your hardware will be able to be compiled as module (the module option will have a radio button called ‘m’ in the screens of xconfig), but be careful what you assign as module and what as standard kernel driver (by the way, if you have an nVidia graphics card, better check out the nVidia README before choosing ‘agpgart’ or when compiling your kernel in general).

    Step 6. After you finished with xconfig and saved your choices, go back to your command line and type:
    make dep

    Depending on how fast machine you got, the kernel compilation can take from 2-3 minutes (2 Ghz P4) up to more than 1 hour (i386) to compile.

    Step 7. Now, let’s clean all these .o object files the compilation process just created:

    make clean

    Step 8. Now let’s create a bootable Linux image (this is our actual kernel file):

    make bzImage

    Your optimized new kernel file should now only be, give or take, around 1 MB, depending how much and what you chose to compile into it. The above command will create the kernel file in this directory:

    Step 9. Now we will have to make our modules:
    make modules

    Step 10. After a while, when the compilation finishes, type:
    make modules_install

    Step 11. Now we will have to move the bzImage file to the right location where all our rest of the kernels live:
    mv /usr/src/linux-2.4.17/arch/i386/boot/bzImage /boot/vmlinuz-2.4.17

    Step 12. Now we will need to tell to the Linux boot manager, called LILO, where to find the new kernel. So, edit the file /etc/lilo.conf with your favorite text editor and add the following lines under a section that looks similar to the following:

    The above ‘root=/dev/hda3’ assumes that your Linux /boot (or /) partition is on the third partition of the primary master IDE hard drive. Please change that ‘hda3’ with your own Linux partition setup. For example, it can be hdb1 (the first partition of primary slave IDE drive) or sdc6 (6th partition on your SCSI secondary master drive). It is *h*d(a/b/c/d)XXX for IDE drives and *s*d(a/b/c/d)XXX for SCSI drives. If you are not sure in which partition your Linux is installed, just look up on that lilo.conf file to see how it is already setuped for your current default kernel or you can also look it up on your /etc/fstab file.

    Worry not, if something is wrong, you already have a boot disk, plus the previous entry for LILO that can allow you to choose your older kernel. You see, your older kernel has not been overwritten, you just added a new one (you can have many kernels installed and load whichever you want each time), and LILO will ask you which kernel you want to boot up next time Linux will start to boot. The main distributions, include a program called ‘linuxconf’, which is great to configure LILO itself. I know that Mandrake also has a tab on its Drake Tools to let you configure LILO some more. You can ask LILO to wait 5 or 10 seconds (or indefinetely) before you pick which kernel you want to boot, you can tell LILO which kernel is the default one to boot if, let’s say, after 10-15 seconds you have not specified anything etc etc. Mandrake 8+ also comes with a graphical interface of LILO, which is rather nice to select what you want to boot each time by using your arrow keys.

    Step 13. Now that we saved down the lilo.conf file with our changes, we should run the lilo program, to make it aware of the changes. Depending on your Linux distribution, one of the two should do the trick:

    Step 14. That’s it! Reboot your machine with a ‘shutdown -h now‘ (leave no disks in the floppy drive) and when you reboot, you should be selecting and rebooting the new kernel.

    Good luck everyone!


    1. 2001-12-24 8:46 am
    2. 2001-12-24 10:45 am
    3. 2001-12-24 2:00 pm
    4. 2001-12-24 5:20 pm
    5. 2001-12-24 9:39 pm
    6. 2001-12-25 12:09 pm
    7. 2001-12-26 7:39 am
    8. 2001-12-26 9:19 am