From Fedora Project Wiki

(Update instructions for modern kernels)
(sbsigntools is now in Fedora (F27+))
 
(10 intermediate revisions by one other user not shown)
Line 7: Line 7:
First, as root, install the tools we'll need.
First, as root, install the tools we'll need.
<pre>
<pre>
dnf install git gcc ccache openssl-devel fedpkg
dnf install git gcc ccache openssl-devel fedpkg kernel-devel elfutils-libelf-devel
</pre>
</pre>


Line 16: Line 16:
git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
</pre>
</pre>
This will clone the entire upstream tree. This may take a while depending on your connection speed.
 
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 <code>--depth 1</code>.


<pre>
<pre>
Line 24: Line 25:
= Applying patches =
= Applying patches =
If you were asked to apply any patches by the developer, this is the stage at which we would do so.
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 a command something like..
These would typically be applied using [https://www.kernel.org/pub/software/scm/git/docs/git-apply.html git apply]
<pre>
<pre>
cat ~/testpatch.diff | patch -p1
git apply ~/testpatch.diff
</pre>
</pre>


If you have to try multiple different patches individually, you can unapply the previous one after testing by adding -R on the end of the above command.
If you have to try multiple different patches individually, you can use [https://www.kernel.org/pub/software/scm/git/docs/git-reset.html git reset] to remove any applied patches:
<pre>
git reset --hard
</pre>


= Configuring the kernel =
= Configuring the kernel =
Line 36: Line 40:
* If the developer has pointed you at a specific config file to use, save it in the linux directory with the filename .config
* 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 <code>cp /boot/config-`uname -r` .config</code>
* You can take your existing .config file by using the command <code>cp /boot/config-`uname -r` .config</code>
When you run the next step, 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.
* 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.
* 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.
<pre>
<pre>
Line 46: Line 49:
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.
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 in place, you are now ready to move on to the next step.
With the .config file in place, you are now ready to move on to the next step.


= Building the kernel =
= 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.
<pre>
<pre>
$EDITOR Makefile
$EDITOR Makefile
</pre>
</pre>
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)
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).
<pre>
<pre>
make oldconfig
make oldconfig
Line 58: Line 63:
make modules
make modules
</pre>
</pre>
These make commands can take a while. If your machine has multiple processors, you can speed up the build by appending the option <code>-j4</code> to them (where 4 is the number of processors your machine has).


(become root)
(become root)
Line 64: Line 71:
make install
make install
</pre>
</pre>


You have now built and installed a kernel.  It will show up in the grub menu next time you reboot.
You have now built and installed a kernel.  It will show up in the grub menu next time you reboot.
Line 69: Line 77:
= Rebuilding =
= 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. A <code>make clean</code> is recommended between builds. This will leave the .config in place, so you can skip that step above and proceed straight to the <code>make bzImage</code> 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.
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 <code>make clean</code> is recommended between builds. This will leave the .config in place, so you can skip that step above and proceed straight to the <code>make bzImage</code> 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 [[User:Pjones/SecureBootSelfSigning|pesign]] or the <code>sbsign</code> tool. The sbsign method is described here.
== Generate a Machine Owner Key ==
This can be done with <code>openssl</code>. 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.
<pre>
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
</pre>
As root:
<pre>
mokutil --import mok.cer
</pre>
This registers your public MOK with the system, on reboot you'll be asked to complete the enrollment at the UEFI console.
== Install sbsign ==
<pre>
dnf install sbsigntools
</pre>
== Sign the kernel ==
<pre>
sbsign --key <mok.key path> --cert <mok.crt path> <kernel path> --output kernel.signed
</pre>
Where <code><mok.key path</code> is the path to mok.key you created, <code><mok.crt path></code> is the path to the mok.crt and <code><kernel path></code> 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:
<pre>
mv kernel.signed <kernel path>
</pre>
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.


= Cleaning up =
= 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 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 'dave' with whatever tag you chose). As root:
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).
 
<pre>
rm -rf /boot/initramfs-*-rc5-dave* /boot/vmlinuz-*-rc5-dave* /boot/System.map-*-rc5-dave* /lib/modules/*-rc5-dave*
</pre>


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):
<pre>
<pre>
rm -f /boot/initramfs-*dave* /boot/vmlinuz-*dave* /boot/System.map-*dave* /lib/modules/*dave*
ln -fs /boot/vmlinuz-$VERSION.$ARCH /boot/vmlinuz
ln -fs /boot/System.map-$VERSION.$ARCH /boot/System.map
</pre>
</pre>



Latest revision as of 17:57, 13 April 2018

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 --depth 1.

cd linux

Applying patches

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.

$EDITOR Makefile

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).

(become root)

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.

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. 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

As root:

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.

Install sbsign

dnf install sbsigntools

Sign the kernel

sbsign --key <mok.key path> --cert <mok.crt path> <kernel path> --output kernel.signed

Where <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.

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 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

Otherwise:

grub2-mkconfig -o /boot/grub2/grub.cfg