kernel build exercise

What ingredients, where from?

As with open source software generally, there are 2 broad approaches to upgrading to a new kernel on a linux system: 1) download and install its precompiled binary or 2) download and compile its source code. And, again generally, method 1 is easier but method 2 affords fine-grained control. Having that control is the reason for building a kernel from source.

Kernel source's place of origin is www.kernel.org. New, plain vanilla kernels are placed there there periodically by Linus Torvalds and the distributed team of kernel maintainers that has grown around him. Then distributions like Fedora modify/extend/improve/patch these kernels, thus maintaining their own versions of kernel source. This is reflected in the separate version numbers for kernel itself versus the distributions that incorporate it. Fedora version 10 for example is based on kernel version 2.6.27.

Suppose you have a Fedora 10 machine. You installed it from a Fedora 10 installation DVD. You want to upgrade to kernel 2.6.18. If you are not interested in compiling from source, the shortcut is to get the precompiled binary, in rpm form, and install that. You would find it at, for example,

http://mirror.hmc.edu/fedora/linux/updates/10/i386/kernel-2.6.27.24-170.2.68.fc10.i586.rpm

After downloading it, just install it as usual with "rpm -Uvh" and  next time you boot you'll have a new option on your GRUB bootloader menu. The adjustments are all made for you. Easier and lazier still,

yum install kernel

will do the same, for whatever kernel version is the latest in Fedora's yum repositories. However forget that, because you are interested in compiling from source. You could find the source at kernel.org as

ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.27.24.tar.bz2

or get Fedora's version from any Fedora mirror

http://mirror.hmc.edu/fedora/linux/updates/10/SRPMS/kernel-2.6.27.24-170.2.68.fc10.src.rpm

The many mirrors all have the same file-tree structure. Note precompiled binary is in .../updates/10/i386/ while source is in .../updates/10/SRPMS/.

Doing the job

There are two broad tasks. First, getting the source code tree in place. Second, performing the procedures to process it. There is more than one way to place the code. Here, we use a fedora-specific approach (or here). We will follow that approach up to the point at which its documentation states "The kernel source tree is now located in the ~/rpmbuild/BUILD/kernel-<version>/linux-<version>.<arch> directory." There we will depart from the fedora-specific recipe and cut over to the  longstanding, traditional formula for kernel compilation. It is documented in the README that comes with the source. If will be found at /usr/src/linux/README once we reach the cutover point.

Make sure a couple of tools are installed. As user root:

yum  install  yum-utils  rpmdevtools

As user student:

cd
rpmdev-setuptree

This creates the following file tree:

[student@localhost ~]$ tree rpmbuild
rpmbuild
|-- BUILD
|-- RPMS
|-- SOURCES
|-- SPECS
`-- SRPMS

5 directories, 0 file

View it on your machine:

tree  rpmbuild

Obtain the linux source code. As user student:

yumdownloader  --source  kernel

The source code comes packaged in the form of an rpm file, namely kernel-2.6.27.24-170.2.68.fc10.src.rpm.

Using su to execute as user root:

su -c 'yum-builddep kernel-2.6.27.24-170.2.68.fc10.src.rpm'

a list of package names appears followed by the message "no uninstalled build requires". Unpack/install the source code:

rpm  -Uvh  kernel-2.6.27.24-170.2.68.fc10.src.rpm

Ignore error messages about non-existent user(s). The unpacked material has been placed in the tree you created above. Then it was empty. Observe that now it is populated:

tree  rpmbuild  |  more

In particular observe the large file rpmbuild/SOURCES/linux-2.6.27.tar.bz2. It's about 50MB in size and holds the bulk of the source code. Beyond that it holds a lot of files containing patches, to be applied to the source in that file to bring it up to date. Apply the patches and otherwise prepare the source code tree. First, determine your system's machine type (e.g., i386, i486...):

uname  -m

Use the result, let's assume it's "i686", in the following command sequence:

cd  rpmbuild/SPECS
rpmbuild  -bp  --target=i686  kernel.spec

Become user root and look around:

su  -
cd /home/student/rpmbuild/BUILD/kernel-2.6.27/
ls

Note there are two directories there (linux-2.6.27.i686 and vanilla-2.6.27). Move one of them:

mv linux-2.6.27.i686/ /usr/src

And create a symbolic link to it, so it can be referred to as "/usr/src/linux":

cd /usr/src
ln -s /usr/src/linux-2.6.27.i686/ /usr/src/linux

At this point we adopt the traditional formula for kernel compilation, roughly following that formula as documented in /usr/src/linux/README. Take a look at it:

less  /usr/src/linux/README

This file was originally written and till recently maintained by Linus Torvalds. Proceed:

cd  linux
make  mrproper
make menuconfig

You are in an interactive program. You can Exit immediately, saving configuration, which amounts to accepting all defaults. Or you can make some configuration changes if you want, before saving. (For example, you might express the decision to include a driver for the ntfs filesystem if this copy of linux will run on a machine in possession of a disk partition that contains ntfs. Otherwise, you'll lack the software to read that partition.) This produces a file named  .config that tells what components to incorporate and compile in to the to-be-produced kernel.

make  clean
make  vmlinux

The result is file named vmlinux in /usr/src/linux which contains the compiled kernel.

make  modules  (time consuming)
make  modules_install

make
make install

At this point you are done. You should note in /boot a new file vmlinuz-2.6.27.24 and in the bootloader's configuration file /boot/grub/grub.conf an inserted stanza headed "title Fedora (2.6.27.24)". The former is the freshly minted substance of the new kernel; the latter is the handle mechanism putting a new option on the bootloader menu, by which to invoke it.

Reboot to the GRUB bootloader menu, choose the label you see there for the new kernel, and boot it. Once booted, log in and verify that you are using the 2.6.27.24 kernel:

uname  -r

or by exercising any option you might have explicitly elected to include while setting the .config file when you ran "make menuconfig". (For example, you might mount an examine an ntfs filesystem.)