Building an 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.
Installing the necessary tools
First, as root, install the tools we'll need.
dnf install git gcc ccache openssl-devel fedpkg kernel-devel elfutils-libelf-devel
Then as a non-root user, perform these steps..
Getting the sources
git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
This will clone the entire upstream tree. This may take a while depending on your connection speed. To make it faster, if you only need the latest snapshot use the option
If you were asked to apply any patches by the developer, this is the stage at which we would do so. These would typically be applied using git apply
git apply ~/testpatch.diff
If you have to try multiple different patches individually, you can use git reset to remove any applied patches:
git reset --hard
Configuring the kernel
Chances are that the kernel you are running is older than the one you are about to configure. This means there will be new options. There are several possibilities here.
- If the developer has pointed you at a specific config file to use, save it in the linux directory with the filename .config
- You can take your existing .config file by using the command
cp /boot/config-`uname -r` .config
- Get a .config from rawhide. This is a little convoluted, but is the best method to get a 'fedora' .config for the kernel. Because rawhide tracks upstream very closely, chances are it'll have an up to date .config file. To check out and generate the config, do this.
git clone git://pkgs.fedoraproject.org/kernel cd kernel make prep
The generated .config file is now in (approximately) kernel-$VERSION/linux-$VERSION-$ARCH/.config where $VERSION is the kernel version ("4.10-rc4") and $ARCH is the architecture ("x86_64"). For example: kernel-4.9.fc26/linux-4.10.0-0.rc4.git0.1.fc26.x86_64/.config.
With the .config file in place, you are now ready to move on to the next step.
Building the kernel
You'll be asked (potentially lots of) questions about all the new options. Just hitting return 'should' always pick the safe decision for each option. However, it's worth taking care and reading each option, as this isn't always the case, and they may introduce new features your distro isn't capable of running, which may result in a non-booting system.
Change the EXTRAVERSION line to add something on the end. For example, if it reads "EXTRAVERSION = -rc5" change it to "EXTRAVERSION = -rc5-dave" (what you choose is only relevant for the final part of this procedure).
make oldconfig make bzImage make modules
These make commands can take a while. If your machine has multiple processors, you can speed up the build by appending the option
-j4 to them (where 4 is the number of processors your machine has).
make modules_install make install
You have now built and installed a kernel. It will show up in the grub menu next time you reboot.
If you have been asked to try several different things, the procedure once you have already built the tree once is mostly the same. A
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.
Sign the kernel for Secure Boot
If your machine has secure boot enabled, you'll need to generate a Machine Owner Key (MOK), register them with the system and cryptographically sign the kernel in order for it to work. This is much easier than it sounds.
To sign your newly created kernel, you can use pesign or the
sbsign tool. The sbsign method is described here.
Generate a Machine Owner Key
This can be done with
openssl. To avoid being prompted by openssl for additional user information the -subj argument is given with the common name property: ("CN=Your Name Here"). You can replace the "Your Name Here" text if you want, but it's optional. The second command converts the PEM formatted certificate into a binary encoded certificate.
openssl req -x509 -newkey rsa:2048 -keyout mok.key -out mok.crt -subj "/CN=Your Name Here/" openssl x509 -in mok.crt -out mok.cer -outform DER
mokutil --import mok.cer
This registers your public MOK with the system, on reboot you'll be asked to complete the enrollment at the UEFI console.
dnf install sbsigntools
Sign the kernel
sbsign --key <mok.key path> --cert <mok.crt path> <kernel path> --output kernel.signed
<mok.key path is the path to mok.key you created,
<mok.crt path> is the path to the mok.crt and
<kernel path> is the path to your newly created kernel under /boot/vm-linuz-$VERSION-$ARCH.
This will create a signed version of the kernel called kernel.signed in the current working directory. The final step is to replace the unsigned kernel in /boot with kernel.signed. As root:
mv kernel.signed <kernel path>
Now reboot your machine - if you haven't done so already, you should be prompted to complete the UEFI enrollment of your public certificate. Afterwards, you should be able to select your newly built kernel from the GRUB 2 bootloader menu.
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 by becoming root, and calling these commands. Remember above, we changed EXTRAVERSION to add a 'tag' to the kernel ? 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 '-rc5-dave' with whatever tag you chose).
rm -rf /boot/initramfs-*-rc5-dave* /boot/vmlinuz-*-rc5-dave* /boot/System.map-*-rc5-dave* /lib/modules/*-rc5-dave*
Now update the vmlinuz and System.map syminks to point to a different kernel (where $VERSION is the kernel version and $ARCH the architecture you want to use):
ln -fs /boot/vmlinuz-$VERSION.$ARCH /boot/vmlinuz ln -fs /boot/System.map-$VERSION.$ARCH /boot/System.map
Finally, regenerate the GRUB 2 config. For UEFI installations:
grub2-mkconfig -o /boot/efi/EFI/fedora/grub.cfg
grub2-mkconfig -o /boot/grub2/grub.cfg