How to compile a vanilla kernel on Linux.

Post date: 03-May-2010 07:35:31

Introduction

Compiling your own kernel is in fact very easy and not at all a daunting project for the average user. Of course for most people there's not much point in doing this apart from being an educational exercise but it's good to learn a bit more about the kernel plus where the various modules and files are installed.

The hardest part of compiling is configuring the kernel as there are so many options to choose from. A vanilla kernel already has many default settings so in many cases you could just compile the default setup and probably get a working kernel.

From there you can try experimenting a bit as you get more comfortable and start to remove modules and features that you have no need for, for example there no point compiling bluetooth support if you computer doesn't have bluetooth hardware.

Why do this?

One of the main advantages is that you can customise the kernel for your computer, for example my computer uses the Intel ipw2100 wireless module and has a Intel Pentium M processor so I can set the kernel configuration to be optimized for my computer. In the case of the kernel modules these are only loaded as required but there's no need for me to compile a module for the ipw2200 wireless device since I don't have one, this will reduce the compile time.

For more advanced users it's possible to add support for more experimental features or for hardware not supported in the kernel supplied with your distribution, even though this is becoming rarer as new distributions are released.

Requirements.

This guide uses Fedora with GRUB as the bootloader, the compiling is the same for any Linux distribution but if you use Lilo as your bootloader you will have to read the documentation to add a new entry for your new kernel.

Other than that any Linux distribution should already have the tools required to compile and install custom kernel. If you wish to see the current requirements in detail read the file /Documentation/Changes after decompressing the kernel tree.

Recommendations.

Finally before you start you should not have already compiled a kernel of the same name before or the modules_install step will try to install your newly complied modules into the same folder under /lib/modules. To avoid this you can open the Makefile located in the tree root and edit the top lines showing the version number, change the EXTRAVERSION to something unique.

VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 22 EXTRAVERSION = .-1

Also I would recommend always leaving a working kernel available to boot into if it all goes wrong, at least then you can reboot into the old kernel and start over again.

Download a vanilla kernel.

These can be downloaded from kernel.org. For a first try I would recommend using the latest stable version linked from the front page, I'll be using 2.6.22.1 as an example.

Knowing which download to use can be a little confusing at first as there are many downloads available from the kernel.org front page. This screen shot of the front page should help you decide.

If we only look at the first line 'The latest stable version of the Linux kernel is:' I would recommend you use this as a first step.

At the right there are many options available:

2.6.22.1 2007-07-10 19:24 UTC F V C Changelog

Clicking on the main 2.6.22.1 link will download a patch to be applied to a 2.6.22 kernel tree, clicking on 'F' will download the full kernel source for a 2.6.22.1 kernel. As a first try you should probably use the 'F' (full download) link.

Finally the 'V' link is a patch to be applied to a 2.6.22 tree with a listing of the changes made and the 'VI' link is a incremental patch so for example a 2.6.22.1 kernel can be patched to a 2.6.22.2 kernel using this patch. This will be the patch type you would use if after compiling the 2.6.22.1 you wish to compile a 2.6.22.2 kernel when that is released.

Compiling the kernel

Assuming you downloaded the full source tree save this file into your home directory and untar the file there. It's recommended to compile the kernel in your home directory as we will be running most of the commands as a normal user, not as root so we need a location writeable by your usual user.

$ tar -xjvf linux-2.6.22.1.tar.bz2

This will create a new directory called linux-2.6.22.1 in your home directory, next cd into this new directory.

$ cd ~/linux-2.6.22.1

Note- it seems that lots of guides recommend downloading and compiling the source in /usr/src/, this is not necessary and then required compiling as root which is also not necessary. The kernel can easily (and maybe should be) compiled as a normal user. In fact if you read the README in the kernel source directory you will see the following note.

Do NOT use the /usr/src/linux area! This area has a (usually incomplete) set of kernel headers that are used by the library header files. They should match the library, and not get messed up by whatever the kernel-du-jour happens to be.

Configure your kernel.

This is the hardest part! There are many tools you can use to configure your kernel. To get a list open a terminal and type:

$ make help

Look for the section below to see the different configuration options:

Configuration targets: config - Update current config utilising a line-oriented program menuconfig - Update current config utilising a menu based program xconfig - Update current config utilising a QT based front-end gconfig - Update current config utilising a GTK based front-end oldconfig - Update current config utilising a provided .config as base silentoldconfig - Same as oldconfig, but quietly randconfig - New config with random answer to all options defconfig - New config with default answer to all options allmodconfig - New config selecting modules when possible allyesconfig - New config where all options are accepted with yes allnoconfig - New config where all options are answered with no

Personally I recommend using menuconfig, this is a terminal type layout but is very easy to use and is very reliable. Even if you are more used to graphical interfaces and maybe tempted to use gconfig for a GTK+ front end in my experience this is more difficult to use and I've had problems selecting various options.

To use menuconfig open a terminal and type:

$ make menuconfig

This will give the following screen in the terminal window.

Beginners

There are a multitude of possible configurations to choose from, initially I would try accepting the default options, save the settings and try compiling the 'default' vanilla kernel. At least this way you will learn if the build and install process works so you won't have wasted time carefully configuring a kernel that you can't compile.

Advanced

For more advanced users the most useful tools to find out what's needed are:

$ /sbin/lsmod

to list all kernel modules currently loaded and (as root):

$ cat /proc/cpuinfo

to get your processor info. Using these two outputs it's possible to only compile those modules required for your machine and to customise it for your processor instead of a generic x86 processor.

Load a current config file

It's also possible to load a saved or current config from your currently running kernel. If you look in the /boot directory you will see current config files for your installed kernels. To load these run menuconfig and select 'Load an Alternate Configuration File', then enter the full path and name of the file to use.

After configuring the kernel as you wish be sure to save the changes and exit the program. The configuration you just created will be in a file called .config in the root of the folder tree.

Make the kernel and modules.

To make the kernel do the following (you DO NOT need to be root to do this).

$ make bzImage

When it's finished you will see a message something like this:

$ Kernel: arch/i386/boot/bzImage is ready (#1)

To make the kernel modules do the following (again you DO NOT need to be root to do this).

$ make modules

Next to install the modules you need to become root and type.

make modules_install

This command will copy the modules you compiled into a folder called /usr/lib/2.6.22.1 in our example, this must be done as root since we need write access to the /lib/modules directory.

Copy the kernel to the boot directory.

This needs to be done as root.

$ cp arch/i386/boot/bzImage /boot/vmlinuz-2.6.22.1

Note that I changed the name to vmlinuz-2.6.22.1, the name is not important since in the next step we edit GRUB to point to the new kernel, I could equally call it bzImage-2.6.22.1 or any other name I choose.

Create an initrd ramdisk.

You can read a summary by looking at the initrd man pages but it is also well explained on the IBM website , quoting from the above site.

The Linux® initial RAM disk (initrd) is a temporary root file system that is mounted during system boot to support the two-state boot process. The initrd contains various executables and drivers that permit the real root file system to be mounted, after which the initrd RAM disk is unmounted and its memory freed. In many embedded Linux systems, the initrd is the final root file system.

To create the file just run the following as root:

$ /sbin/mkinitrd /boot/initrd-2.6.22.1.img 2.6.22.1

Where you just replace the numbers with your kernel version, this command creates the file initrd-2.6.22.1.img in your boot directory.

Copy the System.map

For a guide on the function of the System.map file see this page. As root run copy the System.map file to your /boot directory:

$ cp System.map /boot/System.map-2.6.22.1

Edit GRUB.

This will add a new entry to the GRUB menu allowing us to boot into the new kernel. Open any text editor as root and open the file /etc/grub.conf at the end of the file add an entry like the following.

title Fedora (vanilla-2.6.22.1) root (hd0,2) kernel /vmlinuz-2.6.22.1 ro root=/dev/VolGroup00/LogVol00 initrd /initrd-2.6.22.1.img

For the 'root (hd0,2)' part and 'root=/dev/VolGroup00/LogVol00' section just copy an existing entry in the file, the title can be anything you wish that identifies the new kernel. The kernel and initrd paths are just the paths to the kernel you compiled and the ramdisk created in the previous step.

Boot into he new kernel

To test the new kernel just reboot your computer and select the new kernel from the GRUB menu, if all goes well you'll not notice much difference from before :-) If not then you can always reboot into an older working kernel and try again.

Starting again.

If you wish to remove all the files created including the config file to start afresh just use the command:

$ make mrproper

To just start again without removing the config file use the command:

$ make clean

You will now have a clean kernel tree to start configuring and compiling from again.

Ref: http://bobpeers.com/linux/kernel_compiling