Building a Kernel from the source RPM

Note these instructions *only* apply to Fedora 12 and later releases

This document provides instructions for advanced users who want to rebuild the kernel. Note, however, that when building or running any such kernel, one should NOT expect support from the Fedora kernel team, you're pretty much on your own here if something doesn't work as you'd hoped or expected. But hey, you're an advanced user, so you can handle it, right? Anyway, advanced users build custom kernels for a variety of reasons:

To apply patches for testing that they either generated or obtained from another source

To reconfigure the existing kernel

To learn more about the kernel and kernel development

These instructions can also be used for simply preparing the kernel source tree.

Before starting, make sure the system has all the necessary packages installed, including the following:

rpmdevtools

yum-utils

yum-utils is a default package. To install the other package, use the following command:

su -c 'yum install rpmdevtools yum-utils'

If you plan to use make xconfig, it will be necessary to install the additional packages:

qt3-devel

libXi-devel

For Fedora 15, use the following command:

su -c 'yum install qt3-devel libXi-devel'

Get the Source

Do Not Build Packages as root. Building packages as root is inherently dangerous and not required, even for the kernel. The following instructions allow any normal user to install and build kernels from the source packages.

Prepare a RPM package building environment in your home directory. Run the following command:

rpmdev-setuptree

This command creates different directories ${HOME}/rpmbuild/SOURCES, ${HOME}/rpmbuild/SPECS, and ${HOME}/rpmbuild/BUILD. Where ${HOME} is your home directory.

The second cp command hardlinks the .orig and .new trees to make diff run faster. Most text editors know how to break the hardlink correctly to avoid problems.

Using vim on FC14, it treated the hard link as a hard link and thus the above technique failed. It was necessary to repeat the original copy used for the .orig directory for the .new directory. Note that this uses twice the space.

Make changes directly to the code in the .new source tree, or copy in a modified file. This file might come from a developer who has requested a test, from the upstream kernel sources, or from a different distribution.

After the .new source tree is modified, generate a patch. To generate the patch, run diff against the entire .new and .orig source trees with the following command:

Replace 'linux-$ver.$fedver-mynewpatch.patch' with the desired name for the new patch. On FC14 it was necessary to copy the above patch name to linux-$ver.$fedver-mynewpatch.patch in ~/rpmbuild/SOURCES as well in order for rpmbuild to find it.

For more information on patching refer to the man pages for diff(1) and patch(1).

Configure Kernel Options

This step is for modifying the options the kernel is configured with. This step is optional. If no configuration changes are needed, proceed to "Prepare Build Files".

Small changesIf you only want to make a small number of configuration changes, you should simply set the options as desired in the config-local file. This will be sourced and override the remaining config-* files and avoids a lot of unnecessary work. You can skip the steps below if you use config-local

Change to the kernel source tree directory:

cd ~/rpmbuild/BUILD/kernel-$ver.$fedver/linux-$ver.$arch/

If you only want to make minor changes to the default fedora kernel, skip to step 4., and use one of the two configuration tools to edit those minor changes into the default config file.

Then run the following command, selecting and saving the desired kernel options from the text-based UI:

make menuconfig

For a graphical UI, instead run:

make xconfig

Add a new line to the top of the config file that contains the hardware platform the kernel is built for (the output of uname -i). The line is preceded by a # sign. For example, an x86_64 machine would have the following line added to the top of the config file:

# x86_64

Copy the config file to ~/rpmbuild/SOURCES/:

cp .config ~/rpmbuild/SOURCES/config-`uname -m`-generic

PAE kernelsThe 32-bit PAE kernel uses the config-i686-PAE configuration file. If you are building a PAE kernel, you will need to copy your config file to ~/rpmbuild/SOURCES/:

cp .config ~/rpmbuild/SOURCES/config-i686-PAE

Prepare Build Files

This step makes the necessary changes to the kernel.spec file. This step is required for building a custom kernel.

1. Change to the ~/rpmbuild/SPECS directory:

cd ~/rpmbuild/SPECS

2. Open the kernel.spec file for editing.
3. Give the kernel a unique name. This is important to ensure the custom kernel is not confused with any released kernel. Add a unique string to the kernel name by changing the 'buildid' line. Optionally, change ".local" to your initials, a bug number, the date or any other unique string.

Change this line:

#% define buildid .local

To this (note the extra space is removed in addition to the pound sign):

%define buildid .<custom_text>

4. If you generated a patch, add the patch to the kernel.spec file, preferably at the end of all the existing patches and clearly commented.

Build the New Kernel

This step actually generates the kernel RPM files. This step is required for building a custom kernel. For Fedora 10 or 11, for most purposes, it will be simplest to build with firmware included (see the last form below).

Use the rpmbuild utility to build the new kernel:

To build all kernel flavors:

rpmbuild -bb --target=`uname -m` kernel.spec

To disable specific kernel flavors from the build (for a faster build):

rpmbuild -bb --without <option> --target=`uname -m` kernel.spec

Valid values for "option" above include xen, smp, up, pae, kdump, debug and debuginfo. Specifying --without debug strips out some debugging code from the kernels, where specifying --without debuginfo disables the building of the kernel-debuginfo packages.

To specify that only a specific kernel should be built:

rpmbuild -bb --with <option> --target=`uname -m` kernel.spec

Valid values for "option" above include xenonly, smponly, and baseonly.

For example, to build just the kernel and kernel-devel packages, the command would be:

The build process takes a long time to complete. A lot of messages will be printed to the screen. These messages can be ignored, unless the build ends with an error. If the build completes successfully, the new kernel packages will be located in the ~/rpmbuild/RPMS directory.

TO DO add a troubleshooting section

Following Generic Textbooks

Many of the tutorials, examples, and textbooks about Linux kernel development assume the kernel sources are installed under the /usr/src/linux/ directory. If you make a symbolic link, as shown below, you should be able to use those learning materials with the Fedora packages. Install the appropriate kernel sources, as shown earlier, and then run the following command:

These commands will install your kernel in /boot, create a new initramfs to bootstrap your kernel, and automatically add your new kernel to your grub bootloader "menu.lst". At this point, you can reboot to give control to your new kernel.

Building Only Kernel Modules (Out Of Tree Modules)

This section needs to be updated and fleshed out

This section is for users who are only interested in working on a kernel module, and who do not wish to build an entire custom kernel. It is not necessary to download and rebuild the entire kernel in order to build a module. To build a module for the currently running kernel, only the matching kernel-devel package is required. Run the following command to install the kernel-devel package using yum.

su -c 'yum install kernel-devel'

You may need to install 'kernel-PAE-devel' if you are using the PAE kernel

You can build against any kernel version, as long as you have kernel and kernel-devel packages installed for that version. The rest of this section assumes we're building for the running kernel; if not, replace `uname -r` with the desired version number.

The kernel-doc package contains official Kbuild documentation - see files under Documentation/kbuild, in particular the modules.txt file.

As a simple example, to build the foo.ko module from foo.c, create the following Makefile in the directory containing the foo.c file: