Building a Custom Kernel

This page has been converted from the Fedora Project Wiki and cleaned up for publishing here on the Fedora Docs Portal, but it has not yet been reviewed for technical accuracy. This means any information on this page may be outdated or inaccurate. Reviews for technical accuracy are greatly appreciated. If you want to help, see the README file in the source repository for instructions.

This document provides instructions for advanced users who want to rebuild the kernel from some source.

When building or running a custom kernel, one should not expect support from the Fedora kernel team.

Some common reasons to build a custom kernel are:

  • 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

Get the Dependencies

The easiest way to install all the build dependencies for the kernel is to use the Fedora kernel spec file:

sudo dnf install fedpkg
fedpkg clone -a kernel
cd kernel
sudo dnf builddep kernel.spec

If you want to use make xconfig, you’ll need some additional packages:

sudo dnf install qt3-devel libXi-devel gcc-c++

Secure boot

Make sure you add the user doing the build to /etc/pesign/users and run the authorize user script:

sudo /usr/libexec/pesign/pesign-authorize

Create a new Machine Owner Key (MOK) to import to UEFI:

openssl req -new -x509 -newkey rsa:2048 -keyout "key.pem" \
        -outform DER -out "cert.der" -nodes -days 36500 \
        -subj "/CN=<your name>/"

Import the new certificate into your UEFI database:

You will be asked to authorize the import at next boot.
mokutil --import "cert.der"

Create a PKCS #12 key file:

openssl pkcs12 -export -out key.p12 -inkey key.pem -in cert.der

You can then import the certificate and key into the nss database:

certutil -A -i cert.der -n "<MOK certificate nickname>" -d /etc/pki/pesign/ -t "Pu,Pu,Pu"
pk12util -i key.p12 -d /etc/pki/pesign

Once the certificate and key are imported into your nss database, you can build the kernel with the selected key by adding %define pe_signing_cert <MOK certificate nickname> to the kernel.spec file or calling rpmbuild directly with the --define "pe_signing_cert <MOK certificate nickname>" flag.

While bugzilla bug #1651020 is open you might need to edit the line that starts with %pesign in the kernel spec file and substitute it with pesign -c %{pe_signing_cert} --certdir /etc/pki/pesign/ -s -i $KernelImage -o vmlinuz.signed.

It’s also recommended that you install ccache, which can help speed up rebuilds:

sudo dnf install ccache

Building a Kernel from the Fedora dist-git

The kernel, like any other Fedora package, has a branch per Fedora release. master corresponds to Rawhide and each version of Fedora has a branch called f<version>. For example, to build a Fedora 28 kernel, you would first need to check out that branch with:

  1. Check out the branch for which you would like to build a kernel (master corresponds to Rawhide):

    [source,bash]
    ----
    git checkout origin/f28
    ----
  2. To avoid conflicts with existing kernels, you can set a custom buildid by changing # define buildid .local to %define buildid .<your_custom_id_here> in kernel.spec.

  3. Make whatever changes or customizations you need.

  4. Build the RPMs:

    [source,bash]
    ----
    fedpkg local
    ----
  5. Install the new kernel:

    [source,bash]
    ----
    sudo dnf install --nogpgcheck ./x86_64/kernel-$version.rpm
    ----

Building a non-debugging kernel

Most Rawhide kernels are built with debugging enabled by default. To make a kernel with debugging options disabled, you can follow the above instructions, but before you run fedpkg local, disable the debugging options with:

make release

Enabling configuration options

If there are configuration options that need to be adjusted for your build, you can add changes in the kernel-local file. These changes will get picked up when you build.

Building a kernel from the exploded git trees

Fedora keeps a git tree containing Fedora patches applied on top of the vanilla sources.

git clone git://git.kernel.org/pub/scm/linux/kernel/git/jwboyer/fedora.git
git checkout -b my_branch kernel-4.7.4-200.fc24

You can now build the kernel following regular kernel instructions. This tree is useful for generating patches that can be applied to the kernel.spec.

Building a vanilla upstream kernel

Sometimes a Fedora developer may ask you to try building and installing an upstream kernel (possibly with a patch added) for testing. If there are multiple iterations, it may be quicker for you to do this than for the developer to turn around several RPMs.

There is an effort underway for packaging vanilla kernels. See if this meets your needs first

Getting the Sources

Clone the kernel tree from kernel.org. If you don’t know what tree you need, you should get Linus' tree:

git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
cd linux

You may also want the stable tree (4.y.z releases), which you can add with:

git remote add -f stable git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git

Applying patches

To apply patch files, you can use git-am:

git am -3 <patch file>

Configuring the kernel

If the developer has pointed you at a specific config file to use, save it in the linux directory with the filename .config

Otherwise, you’ll need to pick a configuration file to start from. The Linux kernel has thousands of configuration options, so you don’t want to start from scratch unless you know what you’re doing.

Starting from an installed kernel configuration

If you want to tweak the configuration of a kernel you already have installed, you can start with its configuration which is stored in /boot/. For example, to start with the configuration of the currently running kernel:

cp /boot/config-`uname -r`* .config

Starting from dist-git

If you want to use the configuration for a kernel you do not have installed, you can get the configuration from the Fedora dist-git repository. For example, to start with the latest Rawhide configuration:

cd <dist-git directory>
git checkout master
./build_configs.sh # Ensure the latest configuration files are generated
cp kernel-<arch>.config <linux kernel directory>.config

The debug versions of the configuration files are in kernel-<arch>-debug.config if you would like to build a kernel with debugging options enabled.

Changing the configuration

There are several ways to change the configuration. You can run make help and look at the Configuration targets for the full list, but make menuconfig is a good place to start. You can also just edit the .config file directly.

One configuration option you may want to set is CONFIG_MODULE_COMPRESS, which compresses the modules (with gzip by default) when installing them. Without this setting, the modules can be very large.

Building the kernel

Once you’ve configured the kernel, you’re ready to build it. Before you do so, you’ll want to change the EXTRAVERSION in the Makefile to something you’ll recognize later. For example, if it reads EXTRAVERSION = -rc5 change it to EXTRAVERSION = -rc5-dave:

$EDITOR Makefile

Now you’re ready to build the kernel:

make oldconfig
make bzImage
make modules

Installing the kernel

Installing the kernel is as simple as:

sudo make modules_install
sudo make install

Rebuilding

If you have been asked to try several different things, the procedure once you have already built the tree once is mostly the same. Running make clean is recommended between builds. This will leave the .config in place, so you can skip that step above and proceed straight to the make bzImage part of the steps above. Because we installed ccache in the first step, subsequent builds may go a lot faster as the compiler hits files that haven’t changed since the last time it built them.

Cleaning up

Once you have tested the kernel, and you’ve booted back to one of your kernels installed from an RPM, you can clean up the files that the above procedure installed.

When running the following commands, be sure to get the kernel version correct!

Because you changed EXTRAVERSION in the Makefile to add a 'tag', all the files it installed will have this as part of the filename. So you should be able to use wildcards to delete them safely using commands similar to those below (just replace 'dave' with whatever tag you chose):

rm -f /boot/config-2.6.*dave* /boot/initrd-2.6.*dave* /boot/vmlinuz-*dave* /boot/System.map-*dave*
rm -rf /lib/modules/2.6*dave*

Finally, you will need to remove the kernel as an option to your bootloader. This will change from architecture to architecture. For x86, (as root), edit /boot/grub2/grub.cfg or /boot/efi/EFI/fedora/grub.cfg if you have EFI enabled and delete the four lines relating to your kernel (They should be easy to spot, they’ll be the ones with your tag). They’ll look something like:

title Fedora Core (2.6.22-rc3-dave)
root (hd0,0)
kernel /vmlinuz-2.6.22-rc3-dave ro root=/dev/md0
initrd /initrd-2.6.22-rc3-dave.img