Builing the Linux Kernel

To build the linux kernel, you must,
  1. download sources,
  2. configure the build,
  3. build kernel and modules,
  4. install kernel and modules,
  5. create initrd and modify bootloader options,
  6. reboot.

Sources

The kernel sources are at www.kernel.org. Identify the appropriate release, such as 2.6.17 and use wget to get the compressed tar file.
    ? cd /usr/src
    ? wget http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.17.tar.gz
    ? tar xzvf linux-2.6.17.tar.gz
After this you should have the sources in the Right Place for a build, which is, /usr/src/<revision>.

If you have installed a minimal Linux system on which to do this build, you do not have enough of a system to continue the build. You need gcc, the gnu compiler, and ncurses, a package for menu display on a terminal (this is needed to build the configuration file). Use yum to download and install these packages.

    ? yum install gcc.i386
    ? yum install ncurses.i386
    ? yum install ncurses-devel.i386

Configure

The build is done from the /usr/src/<revision> directory. First, edit the Makefile to add something like -myname to the end of the line EXTRAVERSION =. This means that the kernel, its configuration, the modules subdirectory, all will be named <revision>-myname.

Note: The command uname is useful to figure out the name of a running kernel. Option uname -a should give the full kernel name, and uname -r gives just the revision number. Use this command to figure you what kernel is running on a system.

After editing the Makefile, you need to create a .config file. This is the hardest part. If you can find a configuration file that works, start with that. For reasons that I don't understand, you can't just copy a configuration to .config in this directory, and there doesn't seem to be an easy tool to do this from the command line.

   ? make menuconfig
But you can use the make target menuconfig to do this, and then going to the bottom of the presented menu, find load configuration file. Choosing this, point to the configuration file that works, enter, and exit, saving. Now .config is a copy of the working configuration, and whatever other magic had to occur has occured.

You can now build.

Build

From the build direction do make.
    ? make 
Now two things will happen. The kernel will be built, and the modules will be built.

Installation

The kernel and modules must be moved to special locations in order to be used,
    ? make modules_install
    ? make install
The first will create the /lib/modules/<revision> directory and place the modules there. The second make target will,
  1. Move the kernel, bzImage, to /boot and rename it vmlinuz-<revision>,
  2. Move the System.map to /boot,
  3. Create initrd.img-<revision>
  4. Copy .config to /boot, renaming it to config-<revision>
  5. Modifies the boot loader configuration file /boot/grub/menu.lst so that the new kernel is listed on the boot menu.
However, things sometimes work differently. On 2.6.17 the config file isn't copied and renamed. In other cases, the initrd image is not created automatically.

Initrd is a temporary filesystem used just in the early stage of the boot. It is immediately swaped out for the real filesystem as soon as the kernel has been sufficiently assembled from modules to support the real filesystem. If it isn't created, well, that's going to cause some suffering. On Debian, try,

    ? mkinitrd -o /boot/initrd.img-<revision> <revision>
On other Linux variants, you don't need the -o option. It seems that you must name the img file absolutely, with the starting slash.

N.B.: On 5 Sep 2007, booting to 2.6.22, got error message Enforcing mode requested but no policy loaded. Halting now. The answer was to turn off enforcing mode. Either use "e" during boot to edit the kernel line, or make the change permanent by editing /boot/grub/menu.lst. Google enforcing mode requested.

# grub.conf generated by anaconda
#
# Note that you do not have to rerun grub after making changes to this file
# NOTICE:  You have a /boot partition.  This means that
#          all kernel and initrd paths are relative to /boot/, eg.
#          root (hd0,0)
#          kernel /vmlinuz-version ro root=/dev/VolGroup00/LogVol00
#          initrd /initrd-version.img
#boot=/dev/hda
default=1
timeout=5
splashimage=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
title Fedora Core (2.6.22)
       root (hd0,0)
       kernel /vmlinuz-2.6.22 ro root=/dev/VolGroup00/LogVol00 rhgb quiet enforcing=0
       initrd /initrd-2.6.22.img
title Fedora Core (2.6.11-1.1369_FC4)
       root (hd0,0)
       kernel /vmlinuz-2.6.11-1.1369_FC4 ro root=/dev/VolGroup00/LogVol00 rhgb quiet
       initrd /initrd-2.6.11-1.1369_FC4.img

Reboot

Assuming that /boot/grub/menu.lst is properly modified, you will be offered to boot to the new kernel. When the grub menu appears, hit the space bar to halt the progress of the automatic reboot. Select the kernel you wish to boot and hit enter.

You can also type e to edit the instructions for the selected boot. The several lines will appear, and they can be individually selected and edited, using the arrows and typing e. For instance, you can add the word single to the end of the line beginning with the word kernel. This will halt the boot process in linux single user mode. This is a useful mode when the kernel is working, but some other part of the system is broken. You can boot to single user, get a shell, and start trying to figure out what is going wrong.