I Need to Build a Custom Kernel
Currently maintained by: AlanBartlett and AkemiYagi
Contents
- 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.9% of users no longer need to rebuild their own kernel. You may simply need to build a kernel module, in which case just see How to Build Kernel Modules.
- Is the functionality you need available as a separate module to the current kernel?
Is the functionality you need in the plus kernel located in The CentOSPlus Repository?
Last warning . . . If you break the kernel, or your system, you get to keep it and, as a bonus, you get to keep all the pieces & the associated crying about how your system doesn't boot.
There are two ways to build a custom kernel for CentOS. One is to build a kernel with custom options from the CentOS source rpm and the other is to build a vanilla kernel using sources available from The Linux Kernel Archive.
This tutorial will cover the building a kernel from the CentOS source rpm with your own options or modifications. It is written primarily for CentOS-5. Look out for the
sign for notes regarding the building of other versions of CentOS kernels.
(If you wish to build a vanilla kernel, see Building Source RPM as non-root under CentOS. Do not follow How To Compile A Kernel. This site is not endorsed, as it builds as root, which is unsafe and is basically flawed in its approach. A good reference is Linux Kernel in a Nutshell.)
These actions are for your own personal use. Custom kernels are not supported by the development team as they have no control over your build environment, the options chosen, etc. If you choose 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 such maintainance. |
1. Build preparation
You're going to need a few packages to build a kernel properly.
yum groupinstall "Development Tools" # This is overkill but it will make sure you have all the packages required for the build.
yum install qt-devel # This is only necessary if you want to use make xconfig instead of make gconfig or make menuconfig.
The full kernel source tree. Follow the instructions in Section 2 of I Need the Kernel Source.
If you have any kernel patches to add, copy them to the SOURCES directory now.
2. Configuring your kernel
|
If you are not modifying the kernel configuration, you can omit this section. |
|
With the buildroot correctly set up, it's time to modify the kernel configuration. Change directory to ~/rpmbuild/BUILD/kernel-2.6.18/linux-2.6.18.`uname -m`/ and copy either the appropriate type of configuration file (base, xen; if 32-bit architecture, PAE (for CentOS-5) or base, smp, xenU; if 32-bit architecture, hugemen; if 64-bit architecture, largesmp (for CentOS-4)) from the ./configs/ directory or that of the currently running kernel from /boot/config-`uname -r` to the .config file in this directory.
See the example below (
Replace 2.6.18 with 2.6.9 throughout the rest of this tutorial, if building a CentOS-4 kernel.):
[user@host]$ cd ~/rpmbuild/BUILD/kernel-2.6.18/linux-2.6.18.`uname -m` [user@host]$ cp configs/kernel-2.6.18-`uname -m`[-type].config .config
- or -
[user@host]$ cp /boot/config-`uname -r` .config
First run make oldconfig. Now you should run either make menuconfig, make gconfig or make xconfig to customize the kernel configuration. Once complete, remember to save your configuration changes.
|
If you have installed the full kernel source to build a kernel module, you can stop at this point. Please now refer to How to Build Kernel Modules. |
|
Next, add a line that contains the Hardware Platform (equivalent to uname -i) to the top of the .config file just before you copy it back to the configs/ directory. This will either be i386 for the 32-bit architecture or x86_64 for the 64-bit architecture. It needs to be commented out with a # and must be the first line of the file. (
This step is not required for CentOS-4 kernels.)
Add, as the first line of the .config file, either:
# i386
- or -
# x86_64
Copy the .config file back to the configs/ directory. This is basically the opposite of the earlier copy command:
[user@host]$ cp .config configs/kernel-2.6.18-`uname -m`[-type].config
The final step is to copy the entire contents of the configs/ directory to the ~/rpmbuild/SOURCES/ directory.
[user@host]$ cp configs/* ~/rpmbuild/SOURCES
3. Modifying the kernel spec file
Now you will need to modify the kernel spec file.
|
The line numbers mentioned in this section relate to the current CentOS-5 kernel specification file only. |
|
[user@host]$ cd ~/rpmbuild/SPECS [user@host SPECS]$ cp kernel-2.6.spec kernel-2.6.spec.distro [user@host SPECS]$ vi kernel-2.6.spec
The following four changes apply for kernels >= 2.6.18-53.el5 only.
At line 23, change:
%define with_debug %{?_without_debug: 0} %{!?_without_debug: 1}
to:
%define with_debug 0
At line 29, change:
%define with_debuginfo %{?_without_debuginfo: 0} %{!?_without_debuginfo: 1}
to:
%define with_debuginfo 0
At line 32, change:
%define with_kabichk %{?_without_kabichk: 0} %{?!_without_kabichk: 1}
to:
%define with_kabichk 0
The above change disables the kABI (kernel Application Binary Interface) checking and, therefore, is not necessary if you know that your customization will not result in a kernel that will be at variance with the published kABI. Otherwise, if kABI breakage occurs, the build process will fail at a very late stage.
At line 69, the definition of buildid is commented out. This must be uncommented and given a value to avoid a conflict with your currently installed kernel. Change the line in similar manner to the example below:
%define buildid .your_identifier
|
There should be no space between the "%" and the word "define". |
|
Starting at line 4828, there are 26 lines of code that have to be commented out. This block of code begins with #if a rhel kernel, apply the rhel config options. Comment out these lines to build customised CentOS-5 kernels (
This step is not required to build customised CentOS-4 kernels.):
#if a rhel kernel, apply the rhel config options
%if 0%{?rhel}
for i in %{all_arch_configs}
do
mv $i $i.tmp
$RPM_SOURCE_DIR/merge.pl $RPM_SOURCE_DIR/config-rhel-generic $i.tmp > $i
rm $i.tmp
done
%ifarch ppc64 noarch
#CONFIG_FB_MATROX is disabled for rhel generic but needed for ppc64 rhel
for i in kernel-%{kversion}-ppc64.config
do
mv $i $i.tmp
$RPM_SOURCE_DIR/merge.pl $RPM_SOURCE_DIR/config-rhel-ppc64-generic $i.tmp > $i
rm $i.tmp
done
%endif
%endif
#if a olpc kernel, apply the olpc config options
%if 0%{?olpc}
for i in %{all_arch_configs}
do
mv $i $i.tmp
$RPM_SOURCE_DIR/merge.pl $RPM_SOURCE_DIR/config-olpc-generic $i.tmp > $i
rm $i.tmp
done
%endif
The following two changes apply for kernels >= 2.6.18-92.el5 only.
Comment out line 5073, so that:
%_sourcedir/kabitool -b . -d %{_tmppath}/kernel-$KernelVer-kabideps -k $KernelVer -w $RPM_BUILD_ROOT/kabi_whitelist
becomes:
# %_sourcedir/kabitool -b . -d %{_tmppath}/kernel-$KernelVer-kabideps -k $KernelVer -w $RPM_BUILD_ROOT/kabi_whitelist
After line 5107, append a line touch symsets-$KernelVer.tar.gz so that:
if [ -e $RPM_BUILD_ROOT/Module.kabi ]; then
mv $RPM_BUILD_ROOT/Module.kabi $RPM_BUILD_ROOT/lib/modules/$KernelVer/build
fi
cp symsets-$KernelVer.tar.gz $RPM_BUILD_ROOT/lib/modules/$KernelVer/build
becomes:
if [ -e $RPM_BUILD_ROOT/Module.kabi ]; then
mv $RPM_BUILD_ROOT/Module.kabi $RPM_BUILD_ROOT/lib/modules/$KernelVer/build
fi
touch symsets-$KernelVer.tar.gz
cp symsets-$KernelVer.tar.gz $RPM_BUILD_ROOT/lib/modules/$KernelVer/build
Finally, if you have any patches to apply, you need to make reference to them by adding two lines for each patch. After line 2428, which should be near the end of the patch declarations, add your declaration starting with the number 40000, so that your patch is not in any danger of conflicting with the RHEL/CentOS kernel patch space. For example:
Patch40000: my-custom-kernel.patch
After line 4804 add the line to apply your patch. All you need to do is add is the patch number you declared earlier and rpmbuild will automagically apply it for you. For example:
%patch40000 -p1
4. Building your new kernel
Start the build:
[user@host SPECS]$ rpmbuild -bb --target=`uname -m` kernel-2.6.spec 2> build-err.log | tee build-out.log
You can add some useful options to the rpmbuild command using the --with and/or --without flags. (
These options are available for kernels >= 2.6.18-53.el5 only.)
For example:
[user@host SPECS]$ rpmbuild -bb --target=`uname -m` --with baseonly kernel-2.6.spec 2> build-err.log | tee build-out.log
will build only the base kernel & its corresponding kernel-devel rpm files, whilst
[user@host SPECS]$ rpmbuild -bb --target=`uname -m` --with xenonly kernel-2.6.spec 2> build-err.log | tee build-out.log
will build only the xen kernel & its corresponding kernel-xen-devel rpm files and
[user@host SPECS]$ rpmbuild -bb --target=`uname -m` --without up --without xen kernel-2.6.spec 2> build-err.log | tee build-out.log
will build only the PAE kernel & its corresponding kernel-PAE-devel rpm files.
When the build completes, your custom kernel rpm files will be found in the ~/rpmbuild/RPMS/`uname -m`/ directory. Make sure that you install those files, as root, using a rpm -ivh kernel-*.rpm command. Note: If you have built a kernel version that is older than a currently installed version you will have to use the --oldpackage flag with the rpm command.
UNDER NO CIRCUMSTANCES use a rpm -Uvh command to install your kernel as this will update (overwrite) the currently installed version. Hence if you have a problem with your custom kernel, you will not be able to revert to the previous, working, version.
