mirror of
https://pagure.io/fedora-docs/quick-docs.git
synced 2024-11-24 21:35:17 +00:00
332 lines
9.2 KiB
Text
332 lines
9.2 KiB
Text
= Building a Custom Kernel
|
|
John Soros; Alessio; Brandon Nielsen
|
|
:revnumber: unspecified
|
|
:revdate: 2023-12-23
|
|
:category: Kernel
|
|
:tags: How-to, Kernel, Custom kernel
|
|
:page-aliases: kernel/build-custom-kernel.adoc
|
|
|
|
[abstract]
|
|
This document provides instructions for advanced users who want to rebuild the kernel from some source.
|
|
[NOTE]
|
|
====
|
|
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:
|
|
|
|
[source,bash]
|
|
----
|
|
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:
|
|
|
|
[source,bash]
|
|
----
|
|
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:
|
|
|
|
[source,bash]
|
|
----
|
|
sudo /usr/libexec/pesign/pesign-authorize
|
|
----
|
|
|
|
Create a new Machine Owner Key (MOK) to import to UEFI:
|
|
|
|
[source,bash]
|
|
----
|
|
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:
|
|
|
|
NOTE: You will be asked to authorize the import at next boot.
|
|
|
|
[source,bash]
|
|
----
|
|
mokutil --import "cert.der"
|
|
----
|
|
|
|
Create a PKCS #12 key file:
|
|
|
|
[source,bash]
|
|
----
|
|
openssl pkcs12 -export -out key.p12 -inkey key.pem -in cert.der
|
|
----
|
|
|
|
You can then import the certificate and key into the nss database:
|
|
|
|
[source,bash]
|
|
----
|
|
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.
|
|
|
|
NOTE: While https://bugzilla.redhat.com/show_bug.cgi?id=1651020[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:
|
|
|
|
[source,bash]
|
|
----
|
|
sudo dnf install ccache
|
|
----
|
|
|
|
== Building a Kernel from the Fedora dist-git
|
|
|
|
First, a checkout from the https://src.fedoraproject.org/rpms/kernel[Fedora kernel dist-git] is required:
|
|
|
|
[source,bash]
|
|
----
|
|
git clone https://src.fedoraproject.org/rpms/kernel.git
|
|
----
|
|
|
|
The kernel, like any other Fedora package, has a branch per Fedora release.
|
|
`rawhide` 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 switch to that branch with:
|
|
+
|
|
[source,bash]
|
|
----
|
|
git switch f28
|
|
----
|
|
|
|
. 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`.
|
|
|
|
. Make whatever changes or customizations you need:
|
|
|
|
.. Kernel configuration options can be overriden by modifying the `kernel-local` file.
|
|
|
|
.. Existing patches can be added to `linux-kernel-test.patch`, they will be
|
|
picked up during the build automatically.
|
|
|
|
.. Patches can also be kept in seperate files and added to `kernel.spec` with
|
|
`Patch2: foo.patch`, `Patch3: bar.patch`, etc. Matching `ApplyOptionalPatch foo.patch`,
|
|
`ApplyOptionalPatch bar.patch` lines must be added to apply the patches during
|
|
the build process.
|
|
|
|
.. To make your own modifications to the kernel source, retrieve the kernel
|
|
sources for your current dist-git branch with `fedpkg sources`, then make
|
|
your desired changes to the kernel source and generate a patch, e.g. with
|
|
`diff -rupN kernel_src_folder kernel_src_folder_patched > mypatch.patch`.
|
|
The patch can then be added to `linux-kernel-test.patch` or the specfile.
|
|
|
|
. Build the RPMs:
|
|
+
|
|
[source,bash]
|
|
----
|
|
fedpkg local
|
|
----
|
|
|
|
. Install the new kernel:
|
|
+
|
|
[source,bash]
|
|
----
|
|
sudo dnf install --nogpgcheck ./x86_64/kernel-$version.rpm
|
|
----
|
|
|
|
|
|
== 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.
|
|
|
|
[NOTE]
|
|
====
|
|
There is an effort underway for packaging vanilla kernels.
|
|
https://fedoraproject.org/wiki/Kernel_Vanilla_Repositories[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:
|
|
|
|
[source,bash]
|
|
----
|
|
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:
|
|
|
|
[source,bash]
|
|
----
|
|
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:
|
|
|
|
[source,bash]
|
|
----
|
|
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:
|
|
|
|
[source,bash]
|
|
----
|
|
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:
|
|
|
|
[source,bash]
|
|
----
|
|
cd <dist-git directory>
|
|
git checkout rawhide
|
|
./generate_all_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.
|
|
|
|
[NOTE]
|
|
|
|
====
|
|
|
|
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`:
|
|
|
|
[source,bash]
|
|
----
|
|
$EDITOR Makefile
|
|
----
|
|
|
|
Now you're ready to build the kernel:
|
|
|
|
[source,bash]
|
|
----
|
|
make oldconfig
|
|
make bzImage
|
|
make modules
|
|
----
|
|
|
|
=== Installing the kernel
|
|
|
|
Installing the kernel is as simple as:
|
|
|
|
[source,bash]
|
|
----
|
|
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.
|
|
|
|
[WARNING]
|
|
====
|
|
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):
|
|
|
|
[source,bash]
|
|
----
|
|
rm -f /boot/config-*dave* /boot/initramfs-*dave* /boot/vmlinuz-*dave* /boot/System.map-*dave*
|
|
rm -rf /lib/modules/*dave*
|
|
----
|
|
|
|
Finally, you will need to remove the kernel as an option in your bootloader.
|
|
Assuming your system is running grub2, this can be done by removing the
|
|
bootloader specification entries and rebuilding the grub config:
|
|
|
|
[source,bash]
|
|
----
|
|
rm -f /boot/loader/entries/*dave*
|
|
grub2-mkconfig -o /boot/grub2/grub.cfg
|
|
----
|