Creating Custom Kernel RPMs

Creating custom CentOS kernel RPMs

Are you sure? CentOS is designed to function as a complete environment. If you replace a critical component, it may very well affect how the rest of the system acts.

ARE YOU ABSOLUTELY SURE? Seriously, 99.9999% of users no longer need to rebuild their own kernel. You may simply just need to build a module, in which case see I need the kernel source.

Okay, last warning.. if you break the kernel or your machine, you get to keep it, and as a bonus, you get to keep all the associated crying about how your kernel doesn't build.

Is the functionality you need in the plus kernel located in Repositories/CentOSPlus

Is the functionality you need available as a separate module to the current kernel?

There are two ways to build a custom kernel for centos. One is to build a vanilla kernel of the most recent version, and the other is to build a kernel with custom options from the centos source rpm.

If you want to build a more recent kernel, see http://howtoforge.com/kernel_compilation_centos. This site is not endorsed as to its build method, however, as it builds the SRPM as root, which is unsafe, and basically flawed in approach. See, more correctly, building as non-root

This tutorial will cover rebuilding the centos source rpm with your own options or modifications.

These actions are for your own personal use only. Custom kernels are not supported, as the development team has no control over the build environment, options chosen etc. If you chose to build your own kernel, you will be responsible for continuing to maintain it for security updates, new releases, the second coming of $DEITY, and any other possible scenario which may warrant an update.

Build Prep

You're going to need a few packages to build a kernel properly.

yum groupinstall "Development Tools" #This is overkill, but will make sure you have all the needed packages to build.

yum install qt-devel #only necessary if you want to use make xconfig instead of make menuconfig

Now you'll need to run fedora-buildrpmtree. This will create a .rpmmacros for your user, and create an rpm buildroot in ~/rpmbuild. Now, as your user you need to install the kernel source rpm. You can do this directly from within rpm if you wish. Simply rpm -i <url to the most recent kernel source package>. See the example below:

The uname -m value sets --target to the arch of your current kernel. This is generally accepted and most people will have either i686 or x86_64.
Configuring your kernel

Now that we've got the buildroot set up, it's time to start modifying the kernel to suit your needs. First we need to put the current config into place. To do this copy the appropriate config from the buildroot's SOURCES directory to the build directory. See the example below.

There are several config files to choose from in the SOURCES directory (you may also look in the configs/ directory, where there are config files for your current $ARCH). Make sure you use the one appropriate for you that matches the arch value used above in the uname -m command.

From here, you're ready to run make menuconfig or make xconfig and any other changes you see fit (if you copied down config files from the SOURCES directory, and not the configs/ directory to .config, you will need to run make oldconfig prior to make menuconfig or make xconfig). If you patch the kernel source here, you need to make sure to generate a patch, or keep the patch you're using because we're not going to build the kernel here. We're generating a new source package and configs to generate a new kernel rpm. To those of you saying 'but I can just run make rpm!' you certainly can, but it will not generate the initrd, so you may have issues booting, and you'll have to modify grub to handle your image. Trust me, this way is a little more work, but it's the proper way.

Note: For CentOS-5 kernels, you need to add a line to the top of the .config file before you copy it back to the SOURCES directory that contains the Hardware Platform (uname -i) that you are building the kernel for. That is i386 for i[3,4,5,6]86 arches, x86_64 for the x86_64 arch. It needs to be remarked out with a # and be the first line of the .config file.

For CentOS 5 only, add this as the first line of the .config file

# i386

or

# x86_64

Once you've finished making all the changes you need and saved your modifyed config, it's time to build a new package. First we need to copy your modified config back into place. This is basically the opposite of the copy command previously run.

[user@host]$ cp .config ~/rpmbuild/SOURCES/kernel2.6.9-i686.config

If you have added any kernel patches, copy them to the SOURCES directory as well.

Now it's time to modify the kernel spec file to accept the changes that we've made.

[user@host]$ cd ~/rpmbuild/SPECS
[user@host]$ vim kernel-2.6.spec

In the kernel-2.6.spec file, you'll see the release line, which you must alter to avoid a conflict with the currently installed kernel. Change the line in similar manner to the example below:

%define release 42.0.3.EL

becomes

%define release 42.0.3.1.custom

If you have any patches to apply, you need to do that here in the spec file as well. To add your patch, scroll down to around line 1315 or so, which should be near the end of the patch declarations and add yours, starting around number 40000 so that your patches are in no danger of conflicting with the RHEL/CentOS kernel patch space.

Patch40000: my-custom-kernel.patch

If you're adding a patch, there's still one part left. Scroll down a little further to around line 3258, and add the line to apply your patch here as well. If you used -p1, or -p0 as the option to patch during your source mod, use that here as well. All you need to add is the patch number you declared earlier, and rpm will automagically apply it for you.

%patch40000 -p1

Note: For CentOS-5 kernels there is a generic templating section that will overwrite config file changes. This is an upstream function, and this section of the spec file has to be removed or remarked out before you can rebuild a modified CentOS-5 kernel. The code in question is at the beginning of the %prep section of the spec file.

We're just about done now, and you're only a couple short steps from your own custom kernel. Now we need to put the build into motion.

[user@host SPECS]$ rpmbuild -ba --target=`uname -m` kernel-2.6.spec

Now just sit back and wait for your build to finish. When your build completes, you will have a set of custom kernel rpms waiting for you in ~/rpmbuild/RPMS/<arch>/

Make sure that you install these rpms using yum localinstall, or rpm -ivh kernel-*.rpm.

UNDER NO CIRCUMSTANCES install your kernel rpms with rpm -Uvh, as this will update and overwrite the current kernel install, so if you have a problem with your version, you will not be able to roll back.