Computing and Networks

Kernel patch and compile the Fedora way

Compiling a custom kernel in the open source world of Linux is pretty much a given and an underrated privilege.   This can be a simple or convoluted process depending on work flow and technique.

Each distribution has a preferred way which tends to result in a nice reusable packaged compatible to specific package management system.  For this scenario I’ll focus on Fedora 27 (I don’t know elements of this will work with Centos 7, I’ll confirm next time I run up a Centos VM) and:

a) Patch using the ACS patch commonly used to fix IOMMU grouping for many motherboards so PCIe devices can be passed through to VM’s.

b) Compile the customised kernel using an official fedora kernel src.rpm resulting in reusable and manageable rpm packages complete with official fedora signed modules and additional errata patches (hello meltdown and Intel microcode)

I’ve compiled this compendium mainly for my own use from some confusing or outdated methods that had varying degrees of success or frustration (i.e. fedoraproject) and from an assortment of other blogs and forum posts  So this is neither definitive or for all use cases, but it works for me

STEP ONE: Gather the tools and setup the environment:

$ sudo dnf update
$ sudo dnf install -y rpmdevtools numactl-devel pesign
$ sudo dnf groupinstall "Development Tools"
$ sudo dnf build-dep kernel

*NOTE: To see what packages get installed with a “groupinstall” command, just do:
$ sudo dnf group info “Development Tools”

Now create the RPM build environment witrh

$ rpmdev-setuptree

This will create a directory called rpmbuild in your $HOME root and an accompanying sub directory filesystem structure. Move into the rpmbuild/SOURCES directory and download the official Fedora kernel source and unpack it. The default is to download the kernel source for the currently running kernel.

$ cd ~/rpmbuild/SOURCES
$ sudo dnf download --source kernel
$ rpm2cpio kernel-* | cpio -i --make-directories
$ mv kernel-*.src.rpm ../SRPMS

do a $ ls ~/rpmbuild/SOURCES and the output will show a multitude of new files and directories. You can see all the *.patch files that get compiled in to the official Fedora kernel

STEP TWO (optional): Patch the kernel.

If applying a patch to your kernel, copy the patch file to ~/rpmbuild/SOURCE (giving it a suffex of .patch is not mandatory, just a good practice for easy identification). In this case I will copy over the add-acs-overrides.patch downloaded from github ** and move the kernel.spec file from ~/rpmbuildd/SOURCES to ~/rpmbuild/SPECS in preperation for editing.

** (This patch is reported to no longer work with newer versions i.e. fedora 29 up. use THIS ONE instead)

Now change directory to the ~/rpmbuild/SPECS directory and edit the .kernel.spec file.

$ cp ~/Downloads/add-acs-overrides.patch ~/rpmbuild/SOURCES
$ mv ~/rpmbuild/SOURCES/kernel.spec ~/rpmbuild/SPECS
$ cd ~/rpmbuild/SPECS
$ vi kernel.spec

change
# define buildid .local
to
%define buildid ACS.local

If patching, declare the patch in the same kernel.spec file. Search for # END OF PATCH DEFINIIONS
and just above that line, add:
PATCH900: add-acs-overrides.patch

STEP THREE: Build and install time.

Use rpmbuild command to compile the kernel using the edited kernel.spec file and then build the .rpm packages.  This will take some considerable time to complete with an equal considerable amount of output.

$ rpmbuild -ba ~/rpmbuild/SPECS/kernel.spec

If you don’t require specialty kernels (e.g.pae) or debug symbols, you can save considerable compile time with

$ rpmbuild -ba --without debug --without doc --without perf \
--without tools --without debuginfo --without kdump \
--without bootwrapper --without cross_headers ~/rpmbuild/SPECS/kernel.spec

The freshly built .rpm files can be found in ~/rpmbuild/RPMS/x86_64/. a $ ls ~/rpmbuild/RPMS/x86_64 will show that the rpmbuild -ba command builds more then just a standard kernel.

Now install the kernel .rpm files that you require. At a minimum do:

$ cd ../RPMS/x86_64
$ sudo dnf install -y kernel-core*.rpm kernel-devel*.rpm kernel-headers*.rpm kernel-modules*.rpm

I’ve used this technique a few times now testing patches and kernel features with sucess, so I’ve not had the opportunity of resolving errors that aren’t related to what I testing

FINAL STEP: Reboot and use.

After backing up important files, or varifing existing backup strategy. to start using the new kernel install, reboot the machine and select the new kernel version or ensure it is the default kernel to load at boot.

$ sudo reboot

Beer and profit.

11 thoughts on “Kernel patch and compile the Fedora way

  1. PATCH900: add-acs-overides.patch

    I believe it’s:

    PATCH900: add-acs-overrides.patch

    (It ain’t much but it’s honest work meme)

  2. Hey I am getting this error when starting the install “sudo dnf install -y kernel-core*.rpm kernel-devel*.rpm kernel-headers*.rpm kernel-modules*.rpm”

    “Can not load RPM file: kernel-headers*.rpm.
    Could not open: kernel-headers*.rpm”

    I’ve looked online and nothing says how to fix this…

    1. Hi Ben, thanks for dropping by and working through my guide and potentially finding any issues. What version of fedora are you using? Also could you give me the output of a ls ~/rpmbuild/RPMS/x86_64 just to see if a headers rpm was compiled and packaged. We’re there any errors that you can recall?

      I’m away atm so won’t have a chance to to spin up a VM with a more recent version of fedora to test this guide and maybe do a refresh.

      I did a quick search and found
      https://forums.fedoraforum.org/showthread.php?183766-help-how-to-build-my-own-kernel-header-rpm-package
      I don’t know if this will be any help to you in the meantime.

      Webby

  3. I first tried it on 29, but I just updated to 30 and got the same header error. Here is my output you wanted:
    “kernel-5.0.9-301.patched.fc30.x86_64.rpm
    kernel-core-5.0.9-301.patched.fc30.x86_64.rpm
    kernel-debug-5.0.9-301.patched.fc30.x86_64.rpm
    kernel-debug-core-5.0.9-301.patched.fc30.x86_64.rpm
    kernel-debug-debuginfo-5.0.9-301.patched.fc30.x86_64.rpm
    kernel-debug-devel-5.0.9-301.patched.fc30.x86_64.rpm
    kernel-debuginfo-5.0.9-301.patched.fc30.x86_64.rpm
    kernel-debuginfo-common-x86_64-5.0.9-301.patched.fc30.x86_64.rpm
    kernel-debug-modules-5.0.9-301.patched.fc30.x86_64.rpm
    kernel-debug-modules-extra-5.0.9-301.patched.fc30.x86_64.rpm
    kernel-devel-5.0.9-301.patched.fc30.x86_64.rpm
    kernel-modules-5.0.9-301.patched.fc30.x86_64.rpm
    kernel-modules-extra-5.0.9-301.patched.fc30.x86_64.rpm”

    I had done this on 29 and didnt see header.rpm either. I tried the build command on the website you provided and got the same error when going to install. I will keep trying tho!

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.