Compiling a custom kernel on Fedora and CentOS Linux hosts


I have been experimenting with lxc-containers, which use a number of features in the latest 2.6 kernels (specifically, namespaces). To ensure that I have the latest bug fixes and performance enhancements, I have been rolling my own kernels. This has been remarkably easy, since the Makefile that ships with the kernel has an option to build RPM packages. To build a kernel and create an RPM, you will first need to download and extract the kernel source code:

$ cd /var/tmp

$ wget http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.30.tar.bz2

$ cd /usr/src

$ tar jxvf /var/tmp/linux-2.6.30.tar.bz2

$ cd linux-2.6.30

Once the source code is extracted, you can create a kernel configuration file with ‘make menuconfig’:

$ make menuconfig

If you have built a kernel previously, you should run ‘make mrproper’ to clean up old object and configuration files:

$ make mrproper

If all goes well, you should now have a clean set of kernel source and a kernel configuration file. To create an RPM that contains the kernel and map files, you can type ‘make rpm’:

$ make rpm

After the various object files are compiled and linked, you will see a
message similar to the following:

Processing files: kernel-2.6.30-1.x86_64
Provides: kernel-2.6.30
Requires(rpmlib): rpmlib(CompressedFileNames) <= 3.0.4-1
rpmlib(FileDigests) <= 4.6.0-1 rpmlib(PayloadFilesHavePrefix) <=
4.0-1
Checking for unpackaged file(s): /usr/lib/rpm/check-files
/root/rpmbuild/BUILDROOT/kernel-2.6.30-1.x86_64
Wrote: /root/rpmbuild/SRPMS/kernel-2.6.30-1.src.rpm
Wrote: /root/rpmbuild/RPMS/x86_64/kernel-2.6.30-1.x86_64.rpm
Executing(%clean): /bin/sh -e /var/tmp/rpm-tmp.5PPYZh
+ umask 022
+ cd /root/rpmbuild/BUILD
+ cd kernel-2.6.30
+ rm -rf /root/rpmbuild/BUILDROOT/kernel-2.6.30-1.x86_64
+ exit 0
rm ../kernel-2.6.30.tar.gz

To install the kernel, you can run rpm with the “-i” option:

$ rpm -ivh /root/rpmbuild/SRPMS/kernel-2.6.30-1.src.rpm

This will install a kernel into /boot, but won’t generate the initrd image that is required to boot the machine. To create the image, you can run mkinitrd with the location to write the initrd image to, and the kernel version to generate the image for:

$ mkinitrd /boot/initrd-2.6.30.img 2.6.30

Once these files are in place, you can use the grubby tool to install a grub menu entry:

$ grubby --add-kernel=/boot/vmlinux-2.6.30.bz2

--title="Linux Kernel 2.6.30"
--initrd=/boot/initrd-2.6.30.img
--args="ro root=UUID=48bfe6a8-b9d3-4c98-a288-365501aa9ff0"

I tend to stay away from creating custom kernels, but occasionally they are needed to work around bugs and performance regressions. The example above showed how to build and install a 2.6.30 kernel, but this procedure will work with any kernel version assuming you adjust the versions in the commands listed above.

This article was posted by Matty on 2009-07-29 11:10:00 -0400 -0400