Building a Custom Fedora Based Kernel with Local Patches

How can I create a binary kernel RPM that has patches that have not yet merged into the mainline kernel? One approach to building the Kernel RPM is to use the Makefile option provided with the Kernel. While we typically do this, it does not provide us with the user land tools like perf and its libraries used to test certain patches.

An alternative approach is to take the Fedora Kernel Source RPM that matches the targeted upstream Kernel version, and modify it to apply the set of patches. Here is a walk-through of the process I just got to succeed.

My starting point is a tarball that contains series of patches and quilt series file that enumerates them.

cd ~/rpmbuild/SOURCES

tar -zxf $BUILDDIR/patches-kernel-v6.10-amp-ftk-ac04-general-66B3AFA6.tgz

I convert the series files in the Patches using awk:

for PATCH in `awk '/^0/ {count++; print "Patch" count ":",  $0}' ../SOURCES/patches-kernel-v6.10-local/series ` ;do  sed "/%if !%{nopatches}/i $PATCH"  kernel.spec  > kernel.spec.2; mv -f kernel.spec.2 kernel.spec ; done

I could add an offset if I needed to deconflict, but that does not seem to be the case so far.
TODO: this puts a newline between Patch# and the file name. Must be removed by hand. I want to fix the bash to not do this. To do it manually, I went in to vim and used

qa
Jj
q

To record a macro joining a line to the line below it and then moving the cursor down a line. and then execute that macros 241 (one per patch) times:

241@a

We are going to want the get the Fedora dependencies

yum install yum-utils
yum-builddep kernel.spec

Our patches are generated from git –format patch and their names look like this one:

0207-perf-scripts-python-Ensure-stop-address-of-objdump-r.patch

These are not going to conflict with the patch naming scheme from Fedora, so we can expand this series of patches in the SOURCES directory.

To automatically apply the patches, add a %autopatch line after the %setup so the file segment looks like this

If I was just doing straight patches, this would be enough, but we do config fragments, and thus I need to merge them into the main config file. The configuration is generated using this command:

%{make} ARCH=$Arch olddefconfig >/dev/null

For now I will hardcode the list like this:

   %{make} ARCH=$Arch ampere-topic-cspmu.config ampere-topic-mctp.config ampere-topic-ras2-scrub.config olddefconfig >/dev/null

In the future we can automatically generate this lines based on the file names.

There is an earlier check that stops the build. There is a call to the file process_configs.sh. If we run as is we get the error:

“Found unset config items in x86_64 x86_64, please set them to an appropriate value”

Which is due to process_configs. We need to skip that stage for now by setting

 %define with_configchecks 0

With those changes made, running

rpmbuild -ba kernel.spec 

Leads to the following RPMS generated for aarch64

bpftool-6.10.5-100.fc40.aarch64.rpm
bpftool-debuginfo-6.10.5-100.fc40.aarch64.rpm
kernel-6.10.5-100.fc40.aarch64.rpm
kernel-core-6.10.5-100.fc40.aarch64.rpm
kernel-debug-6.10.5-100.fc40.aarch64.rpm
kernel-debug-core-6.10.5-100.fc40.aarch64.rpm
kernel-debug-debuginfo-6.10.5-100.fc40.aarch64.rpm
kernel-debug-devel-6.10.5-100.fc40.aarch64.rpm
kernel-debug-devel-matched-6.10.5-100.fc40.aarch64.rpm
kernel-debuginfo-6.10.5-100.fc40.aarch64.rpm
kernel-debuginfo-common-aarch64-6.10.5-100.fc40.aarch64.rpm
kernel-debug-modules-6.10.5-100.fc40.aarch64.rpm
kernel-debug-modules-core-6.10.5-100.fc40.aarch64.rpm
kernel-debug-modules-extra-6.10.5-100.fc40.aarch64.rpm
kernel-debug-modules-internal-6.10.5-100.fc40.aarch64.rpm
kernel-debug-uki-virt-6.10.5-100.fc40.aarch64.rpm
kernel-devel-6.10.5-100.fc40.aarch64.rpm
kernel-devel-matched-6.10.5-100.fc40.aarch64.rpm
kernel-modules-6.10.5-100.fc40.aarch64.rpm
kernel-modules-core-6.10.5-100.fc40.aarch64.rpm
kernel-modules-extra-6.10.5-100.fc40.aarch64.rpm
kernel-modules-internal-6.10.5-100.fc40.aarch64.rpm
kernel-selftests-internal-6.10.5-100.fc40.aarch64.rpm
kernel-tools-6.10.5-100.fc40.aarch64.rpm
kernel-tools-debuginfo-6.10.5-100.fc40.aarch64.rpm
kernel-tools-libs-6.10.5-100.fc40.aarch64.rpm
kernel-tools-libs-devel-6.10.5-100.fc40.aarch64.rpm
kernel-uki-virt-6.10.5-100.fc40.aarch64.rpm
libperf-6.10.5-100.fc40.aarch64.rpm
libperf-debuginfo-6.10.5-100.fc40.aarch64.rpm
libperf-devel-6.10.5-100.fc40.aarch64.rpm
perf-6.10.5-100.fc40.aarch64.rpm
perf-debuginfo-6.10.5-100.fc40.aarch64.rpm
python3-perf-6.10.5-100.fc40.aarch64.rpm
python3-perf-debuginfo-6.10.5-100.fc40.aarch64.rpm
rtla-6.10.5-100.fc40.aarch64.rpm
rv-6.10.5-100.fc40.aarch64.rpm

To modify the rpm file name you have access to two variables. The first is dist, which is typically set the the Fedora version, or RHEL version, or other distribution. The expectation is that the Koji environment used to run the official packaging will set this to the target distribution. The other variable is buildid.his is typically not set. However, on my last run, I set mine like this:

< %define dist adam
< %define buildid .12345

and got packages that look like this

Wrote: /root/rpmbuild/SRPMS/kernel-6.10.5-100.12345adam.src.rpm
Wrote: /root/rpmbuild/RPMS/aarch64/kernel-devel-matched-6.10.5-100.12345adam.aarch64.rpm
Wrote: /root/rpmbuild/RPMS/aarch64/kernel-debug-devel-matched-6.10.5-100.12345adam.aarch64.rpm
Wrote: /root/rpmbuild/RPMS/aarch64/kernel-6.10.5-100.12345adam.aarch64.rpm

According to the Fedora standards, you are not supposed to hardcode dist. This probably does not apply for in-house distributions, but if you want to keep the spec file as close to upstream as possible, you can modify the rpm macro variable used to product dist.

Modifications of the build that should not be in the spec file can be put into the file ~/.rpmmacros. Here is mine, slightly edited:

%dist .MINE 

%buildid .A11111

# kernel-16k (aarch64 kernel with 16K page_size)
%_with_arm64_16k 1

%vendor younglogic

# kernel-64k (aarch64 kernel with 64K page_size)
#%define _without_arm64_64k: 1

At some point I will try building both the 16 and 64 page size kernels along with the 4K. What you see here is the way I am attempting to control those builds. I am currently checking to see if I get both the 4K and 16K builds side by side with these settings.

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.