From Fedora Project Wiki

m (Correct link mistake: otherwise orig and new are always equal and the resulting patch will be empty)
(Fix backticks not showing inside <code> line for Configuring the kernel)
 
(93 intermediate revisions by 24 users not shown)
Line 1: Line 1:
[[Category:Documentation]][[Category:Tutorials]]
[[Category:Documentation]][[Category:Tutorials]]
{{autolang|base=yes}}
{{autolang|base=yes}}
== Building a Kernel from the source RPM ==
{{Admon/warning | Note these instructions *only* apply to Fedora 12 and later releases}}


This document provides instructions for advanced users who want to rebuild the kernel. Note, however, that when building or running any such kernel, one should NOT expect support from the Fedora kernel team, you're pretty much on your own here if something doesn't work as you'd hoped or expected. But hey, you're an advanced user, so you can handle it, right?  Anyway, advanced users build custom kernels for a variety of reasons:
This document provides instructions for advanced users who want to rebuild the kernel from some source. Note, however, that when building or running any such kernel, one should NOT expect support from the Fedora kernel team; you're pretty much on your own here if something doesn't work as you'd hoped or expected. But hey, you're an advanced user, so you can handle it, right?  Anyway, advanced users build custom kernels for a variety of reasons:
 
* To apply patches for testing that they either generated or obtained from another source
* To apply patches for testing that they either generated or obtained from another source
* To reconfigure the existing kernel
* To reconfigure the existing kernel
* To learn more about the kernel and kernel development
* To learn more about the kernel and kernel development


These instructions can also be used for simply preparing the kernel source tree.


Before starting, make sure the system has all the necessary packages installed, including the following:
== Dependencies for building kernels ==
Not all of these will apply to all methods but this provides a good dependency list of items to install
 
<code> # sudo dnf install fedpkg fedora-packager rpmdevtools ncurses-devel pesign grubby</code>
 
Give the following command from the top directory of the kernel source tree once you have checked it out
 
<code> # sudo dnf builddep kernel.spec</code>
 
if you plan to run 'make xconfig'


* <code>rpmdevtools</code>
<code> # sudo dnf install qt5-qtbase-devel libXi-devel gcc-c++</code>
* <code>yum-utils</code>


yum-utils is a default package. To install the other package, use the following command:
Also make sure you add the user doing the build to /etc/pesign/users and run the authorize user script:


<pre>su -c 'yum install rpmdevtools yum-utils'
<code># sudo /usr/libexec/pesign/pesign-authorize</code>
</pre>


If you plan to use <code>make menuconfig</code>, it will be necessary to install the additional packages:
It should be noted that pesign pesign-rh-test-certs gets pulled in automatically for some, but not for everyone, it depends on how you installed pesign.  It is best to make sure that you have it installed.
* <code>ncurses-devel</code>


Use the following command:
{{admon/note|pesign|Also note that <code>pesign</code> is applicable only for UEFI platforms (x86, arm, aarch64), it's not used on eg. ppc64le or s390x.}}
<pre>su -c 'yum install ncurses-devel'
</pre>


If you plan to use <code>make xconfig</code>, it will be necessary to install the additional packages:
{{admon/note|dnf versus yum|As of Fedora 22[https://docs.fedoraproject.org/en-US/Fedora/22/html/Release_Notes/] [[dnf]] has replaced [[yum]] as the default package manager. In the event you are building a kernel for an older system you will either have to install dnf or substitute <code>yum</code> for <code>dnf</code> and/or <code>yumdownloader</code> from the <code>yum-utils</code> package.}}
* <code>qt3-devel</code>
* <code>libXi-devel</code>
* <code>gcc-c++</code>


For Fedora 15, use the following command:
== Building a Kernel from the Fedora source tree ==
<pre>su -c 'yum install qt3-devel libXi-devel'
</pre>


Make sure you have installed all dependencies


=== Get the Source ===
<code> $ fedpkg clone kernel </code>
{{Admon/warning |Do Not Build Packages as <code>root</code>. | Building packages as <code>root</code> is inherently dangerous and not required, even for the kernel.  The following instructions allow any normal user to install and build kernels from the source packages.}}


# Prepare a RPM package building environment in your home directory.  Run the following command: <pre>rpmdev-setuptree</pre>This command creates different directories <code>${HOME}/rpmbuild/SOURCES</code>, <code>${HOME}/rpmbuild/SPECS</code>, and <code>${HOME}/rpmbuild/BUILD</code>. Where <code>${HOME}</code> is your home directory.
you will likely need to checkout the source anonymously unless you have an Fedora developer account
# Download the <code>kernel-<version>.src.rpm</code> file.  Enable the appropriate source repositories with the <code>--enablerepo</code> switch. (yumdownloader --enablerepo=repo_to_enable --source kernel)<pre>yumdownloader --source kernel</pre>
# Install build dependencies for the kernel source with the <code>yum-builddep</code> command (root is required to install these packages):<pre>su -c 'yum-builddep kernel-<version>.src.rpm'</pre>
# Install <code>kernel-<version>.src.rpm</code> with the following command:<pre>rpm -Uvh kernel-<version>.src.rpm</pre>This command writes the RPM contents into <code>${HOME}/rpmbuild/SOURCES</code> and <code>${HOME}/rpmbuild/SPECS</code>, where <code>${HOME}</code> is your home directory.  It is safe to ignore any messages similar to the following:
<pre>warning: user kojibuilder does not exist - using root
warning: group kojibuilder does not exist - using root
</pre>


{{Admon/warning | Space Required. The full kernel building process requires several gigabytes of extra space on the file system containing your home directory.}}
<code> $ fedpkg clone -a kernel </code>


=== Prepare the Kernel Source Tree ===
As of the time of this wiki writing, the kernel is managed using git. Each fedora release is a separate branch. rawhide tracks master. To get the tree for a particular release, you can use git checkout from the top of your newly created source tree.
This step expands all of the source code files for the kernel. This is required to view the code, edit the code, or to generate a patch.


1. Prepare the kernel source tree using the following commands:
e.g. for fedora 23,
<pre>cd ~/rpmbuild/SPECS
rpmbuild -bp --target=$(uname -m) kernel.spec
</pre>


The kernel source tree is now located in the <code>~/rpmbuild/BUILD/kernel-<version>/linux-<version>.<arch></code> directory.
<code> $ git checkout origin/f23 </code>


=== Copy the Source Tree and Generate a Patch ===
You can now make whatever changes / customizations you need before generating the rpms and installing them. To avoid conflicts you may want to consider changing
This step is for applying a patch to the kernel source. If a patch is not needed, proceed to "Configure Kernel Options".


{{admon/note|Advanced Users|There are tools such as 'quilt' that allow you to avoid copying the source tree.  For advanced users, such tools are often a time saver over the steps below|}}
<code> # define buildid .local </code>


Copy the source tree to preserve the original tree while making changes to the
to e.g.


<code> %define buildid .foobar </code>


<pre>
in <code>kernel.spec</code>.
export arch=x86_64 # replace x86_64 with your arch
export ver=3.7 # replace 3.1 with your kernel version
export subver=4-204
export fedver=fc16 # replace fc16 with your fedora version
cp -r ~/rpmbuild/BUILD/kernel-$ver.$fedver ~/rpmbuild/BUILD/kernel-$ver.$fedver.orig
cp -al ~/rpmbuild/BUILD/kernel-$ver.$fedver ~/rpmbuild/BUILD/kernel-$ver.$fedver.new
</pre>


{{Admon/warning | The second <code>cp</code> command hardlinks the <code>.orig</code> and <code>.new</code> trees to make <code>diff</code> run faster.  Most text editors know how to break the hardlink correctly to avoid problems. Vim does not break hard links by default, so don't use 'cp -al' use 'cp -r', or look into the 'breakhardlink' setting.}}
Whatever you choose instead of foobar will show up in the name of the generated rpm's and will also show up in the GRUB boot menu.


Using vim on FC14, it treated the hard link as a hard link and thus the above technique failed.  It was necessary to repeat the original copy used for the .orig directory for the .new directory.  Note that this uses twice the space.
When finished, generate the appropriate rpms with


Make changes directly to the code in the <code>.new</code> source tree, or copy in a modified file. This file might come from a developer who has requested a test, from the upstream kernel sources, or from a different distribution.
<code> $ fedpkg local </code>


After the <code>.new</code> source tree is modified, generate a patch. To generate the patch, run <code>diff</code> against the entire <code>.new</code> and <code>.orig</code> source trees with the following command:
The rpms will be generated in a subdirectory $ARCH which can then be installed:


<pre>
<pre>$ sudo dnf install --nogpgcheck \
cd ~/rpmbuild/BUILD
  ./x86_64/kernel-modules-core-$version.rpm \
diff -uNrp kernel-$ver.$fedver.orig kernel-$ver.$fedver.new > ../SOURCES/linux-$ver.$fedver-mynewpatch.patch
  ./x86_64/kernel-core-$version.rpm \
  ./x86_64/kernel-modules-$version.rpm \
  ./x86_64/kernel-$version.rpm
</pre>
</pre>


Replace 'linux-$ver.$fedver-mynewpatch.patch' with the desired name for the new patch.
After installing the packages, the kernel will appear in the GRUB menu after next reboot. To uninstall, boot into a kernel different from the one to be uninstalled and do
 
<code>
$ sudo dnf remove kernel-core-$version
</code>


Lastly edit the patch file to remove the leading directory, this is required because the kernel spec file applies patches with '-p1' only.
A complete walkthrough could look like this:


For example the following:
<pre>sudo dnf install fedpkg fedora-packager rpmdevtools ncurses-devel pesign grubby
<pre>
sudo dnf install qt5-qtbase-devel libXi-devel gcc-c++
--- kernel-3.8.fc18/linux-3.8.11-200.bz708406.fc18.x86_64/kernel/kexec.c        2013-02-18 18:58:34.000000000 -0500
sudo bash -c "echo $USER >> /etc/pesign/users"
+++ kernel-3.8.fc18.new/linux-3.8.11-200.bz708406.fc18.x86_64/kernel/kexec.c    1969-12-31 19:00:00.000000000 -0500
sudo /usr/libexec/pesign/pesign-authorize
fedpkg clone -a kernel
cd kernel
git fetch
git switch f34
sed -i 's/# define buildid .local/%define buildid .foobar/g' kernel.spec
sudo dnf builddep kernel.spec
fedpkg local
cd x86_64
sudo dnf install --nogpgcheck \
  kernel-core-5.17.12-100.foobar.fc34.x86_64.rpm \
  kernel-modules-5.17.12-100.foobar.fc34.x86_64.rpm \
  kernel-5.17.12-100.foobar.fc34.x86_64.rpm
</pre>
</pre>


Should be changed to:
<pre>
--- linux-3.8.11-200.bz708406.fc18.x86_64/kernel/kexec.c        2013-02-18 18:58:34.000000000 -0500
+++ linux-3.8.11-200.bz708406.fc18.x86_64/kernel/kexec.c    1969-12-31 19:00:00.000000000 -0500
</pre>


=== Building a non-debugging kernel ===
Branched kernels are built with debugging enabled by default in the early stages of the release to assist developers. To make a kernel with debugging information disabled, you can follow the above instructions to check out and do:
<code> $ make release </code>


{{Admon/warning | For more information on patching refer to the man pages for <code>diff(1)</code> and <code>patch(1)</code>.}}
<code> $ fedpkg local </code>


=== Configure Kernel Options ===
=== Enabling config options ===
This step is for modifying the options the kernel is configured with. This step is optional. If no configuration changes are needed, proceed to "Prepare Build Files".


{{admon/important|Small changes|If you only want to make a small number of configuration changes, you should simply set the options as desired in the config-local file. This will be sourced and override the remaining config-* files and avoids a lot of unnecessary work. You can skip the steps below if you use config-local}}
If there are configuration options that need to be adjusted for your build, you can add changes in the kernel-local file. These changes will get picked up when you build.


# Change to the kernel source tree directory:<pre>cd ~/rpmbuild/BUILD/kernel-$ver.$subver.$fedver/linux-$ver.$arch/</pre> If you only want to make minor changes to the default fedora kernel, skip to step 4., and use one of the two configuration tools to edit those minor changes into the default config file.
=== Updating ===
# Select the desired configuration file from <code>~/rpmbuild/BUILD/kernel-$ver.$fedver/linux-$ver.$arch/configs</code>. Copy the desired config file to <code>~/rpmbuild/BUILD/kernel-$ver.$fedver/linux-$ver.$arch/.config</code>: <pre>cp configs/<desired-config-file> .config</pre>
# Run the following command: <pre>make oldconfig</pre>
# Then run the following command, selecting and saving the desired kernel options from the text-based UI:<pre>make menuconfig</pre>
#* For a graphical UI, instead run: <pre>make xconfig</pre>
# Add a new line to the top of the config file that contains the hardware platform the kernel is built for (the output of <code>uname -i</code>). The line is preceded by a <code>#</code> sign. For example, an x86_64 machine would have the following line added to the top of the config file:<pre># x86_64</pre>
# Copy the config file to <code>~/rpmbuild/SOURCES/</code>: <pre>cp .config ~/rpmbuild/SOURCES/config-`uname -m`-generic</pre>
{{admon/important|32-bit x86 kernels|The 32-bit PAE kernel uses the config-i686-PAE configuration file.  If you are building a PAE kernel, you will need to copy your config file to <code>~/rpmbuild/SOURCES/</code>: <pre> cp .config ~/rpmbuild/SOURCES/config-i686-PAE</pre>  If you are building a non-PAE kernel, you will need to copy your config file to <pre> cp .config ~/rpmbuild/SOURCES/config-x86-32-generic</pre>.  Again, the use of config-local is encouraged unless you are making a large number of configuration changes.}}


=== Prepare Build Files ===
This step makes the necessary changes to the <code>kernel.spec</code> file. This step is required for building a custom kernel.


1. Change to the <code>~/rpmbuild/SPECS</code> directory:
* <code> $ cd kernel </code>
* <code> kernel $ git status </code>
** your tree will be dirty in the configs and kernel.spec
* <code> kernel $ git stash </code>
** puts aside your changes so your tree will be clean
* <code> kernel $ git pull origin </code>
** update to the latest tree from fedpkg git


<pre>cd ~/rpmbuild/SPECS
Now you can run whatever other commands you want (e.g. make release)
</pre>


2. Open the <code>kernel.spec</code> file for editing.<br>
== Building a kernel from the exploded git trees ==
3. Give the kernel a unique name. This is important to ensure the custom kernel is not confused with any released kernel. Add a unique string to the kernel name by changing the 'buildid' line. Optionally, change ".local" to your initials, a bug number, the date or any other unique string.


Change this line:
Fedora maintains a git tree containing Fedora patches applied on top of the vanilla sources.
<pre>
#% define buildid .local
</pre>


To this (note the extra space is removed in addition to the pound sign):
<code> $ git clone https://gitlab.com/cki-project/kernel-ark </code>
<pre>
%define buildid .<custom_text>
</pre>


4. If you generated a patch, add the patch to the <code>kernel.spec</code> file, preferably at the end of all the existing patches and clearly commented.
<code> $ git checkout -b my_branch kernel-4.7.4-200.fc24</code>


<pre># cputime accounting is broken, revert to 2.6.22 version
You can now build the kernel following regular kernel instructions. This tree is useful for generating patches that can be applied to the kernel.spec.
Patch2220: linux-2.6-cputime-fix-accounting.patch


Patch9999: linux-2.6-samfw-test.patch
== Building a Kernel from the source RPM ==
</pre>


The patch then needs to be applied in the patch application section of the spec file. Again, at the end of the existing patch applications and clearly commented.
Instructions for this are on a [[Building_a_custom_kernel/Source_RPM | separate page]]. In general, you should use one of the other methods for building the kernel which are much easier.


<pre>
== Building Only Kernel Modules (Out Of Tree Modules) ==
ApplyPatch linux-2.6-cputime-fix-accounting.patch


ApplyPatch linux-2.6-samfw-test.patch
{{Admon/warning | This section needs to be updated and fleshed out}}


This section is for users who are only interested in working on a kernel module, and who do not wish to build an entire custom kernel. It is not necessary to download and rebuild the entire kernel in order to build a module.  To build a module for the currently running kernel, only the matching <code>kernel-devel</code> package is required.  Run the following command to install the <code>kernel-devel</code> package using <code>dnf</code>.


<pre>su -c 'dnf install kernel-devel'
</pre>
</pre>


=== Build the New Kernel ===
{{Admon/note | You may need to install 'kernel-PAE-devel' if you are using the PAE kernel}}
This step actually generates the kernel RPM files. This step is required for building a custom kernel. For Fedora 10 or 11, for most purposes, it will be simplest to build with firmware included (see the last form below).


Use the <code>rpmbuild</code> utility to build the new kernel:
You can build against any kernel version, as long as you have <code>kernel</code> and <code>kernel-devel</code> packages installed for that version.  The rest of this section assumes we're building for the running kernel; if not, replace <code>`uname -r`</code> with the desired version number.
 
As a simple example, to build the <code>foo.ko</code> module from <code>foo.c</code>, create the following <code>Makefile</code> in the directory containing the <code>foo.c</code> file:
 
<pre>obj-m := foo.o
 
KDIR  := /lib/modules/$(shell uname -r)/build
PWD  := $(shell pwd)


* To build all kernel flavors:
default:
<pre>rpmbuild -bb --target=`uname -m` kernel.spec
[TAB]$(MAKE) -C $(KDIR) M=$(PWD) modules
</pre>
</pre>
[TAB] Denotes a tab character which must come first for makefile lines containing commands.
Then, issue the <code>make</code> command to build the <code>foo.ko</code> module.


* To disable specific kernel flavors from the build (for a faster build):
The above is a helpful local Makefile wrapper invoking kbuild; in general you can simply do things like


<pre>rpmbuild -bb --without <option> --target=`uname -m` kernel.spec
<pre># make -C /lib/modules/`uname -r`/build M=`pwd` modules
# make -C /lib/modules/`uname -r`/build M=`pwd` clean
# make -C /lib/modules/`uname -r`/build M=`pwd` modules_install
</pre>
</pre>


Valid values for "option" above include <code>xen</code>, <code>smp</code>, <code>up</code>, <code>pae</code>, <code>kdump</code>, <code>debug</code> and <code>debuginfo</code>. Specifying <code>--without debug</code> strips out some debugging code from the kernels, where specifying <code>--without debuginfo</code> disables the building of the <code>kernel-debuginfo</code> packages.
etc to build those targets.
 
== Building Vanilla upstream kernel ==


* To specify that only a specific kernel should be built:
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.


<pre>rpmbuild -bb --with <option> --target=`uname -m` kernel.spec
=== Existing Fedora Vanilla packages ===
</pre>


Valid values for "option" above include <code>xenonly</code>, <code>smponly</code>, and <code>baseonly</code>.
There is an effort underway for packaging vanilla kernels. [[Kernel_Vanilla_Repositories | See if this meets your needs first]]


* For example, to build just the kernel and kernel-devel packages, the command would be:
=== Getting the sources ===


<pre>rpmbuild -bb --with baseonly --without debuginfo --target=`uname -m` kernel.spec
Clone a kernel tree from kernel.org
</pre>


* To build with firmware included, do:
{{Admon/note | Tips for developing with kernel.org sources|The README file in the top-level directory provides very good build instructions, including how to direct the build to a particular directory, the necessary make targets, and the order in which to issue them. Save time by reviewing the Documentation directory and its sub-directories containing  informative ".txt" files. View the top level Makefile for kernel version information.}}


<pre>rpmbuild -bb --with baseonly --with firmware --without debuginfo \
<code> $ git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git </code>
--target=`uname -m` kernel.spec </pre>
This will clone the entire upstream tree. This may take a while depending on your connection speed. (While the tree is syncing, why not take the time to update some steps on this wiki that are inevitably out of date?)


The build process takes a long time to complete. A lot of messages will be printed to the screen. These messages can be ignored, unless the build ends with an error. If the build completes successfully, the new kernel packages will be located in the <code>~/rpmbuild/RPMS</code> directory.
<code> $ cd linux </code>


{{Admon/warning | TO DO | add a troubleshooting section}}
If you need the stable kernel releases, add the stable remote:


==== Following Generic Textbooks ====
<code> $ git remote add -f stable git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git </code>


Many of the tutorials, examples, and textbooks about Linux kernel development assume the kernel sources are installed under the <code>/usr/src/linux/</code> directory. If you make a symbolic link, as shown below, you should be able to use those learning materials with the Fedora packages. Install the appropriate kernel sources, as shown earlier, and then run the following command:
Double check what baseline is being used and check out a new one if necessary:


<pre>su -c 'ln -s /usr/src/kernels/<version>.<release>-<arch> /usr/src/linux'
<code> $ git checkout v4.5.2</code>
</pre>


Enter the <code>root</code> password when prompted.
=== Applying patches ===


=== Install the New Kernel ===
==== The patch method ====
This step actually installs the new kernel into the running system.
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..


To install the new kernel, use the <code>rpm -ivh</code> command, '''not''' the <code>-U</code> or <code>--upgrade</code> options:
<code> $ cat ~/testpatch.diff  | patch -p1 </code>


<pre>su -c "rpm -ivh --force $HOME/rpmbuild/RPMS/<arch>/kernel-<version>.<arch>.rpm"
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.
</pre>


If you changed the name of your kernel as requested, your firmware and kernel headers won't match. The simplest solution is to build new firmware as described in 'Build the New Kernel', then
==== The git method ====


<pre>su -c "rpm -ivh $HOME/rpmbuild/RPMS/<arch>/kernel-<version>.<arch>.rpm \
Most developers these days generate patches using git and you can use git to help apply patches. You can do:
      $HOME/rpmbuild/RPMS/<arch>/kernel-firmware-<version>.<arch>.rpm \
      $HOME/rpmbuild/RPMS/<arch>/kernel-headers-<version>.<arch>.rpm \
      $HOME/rpmbuild/RPMS/<arch>/kernel-devel-<version>.<arch>.rpm"
</pre>


These commands will install your kernel in /boot, create a new initramfs to bootstrap your kernel, and automatically add your new kernel to your grub bootloader "menu.lst".  At this point, you can reboot to give control to your new kernel.
<code> $ git am -3 <patch file> </code>


== Building Only Kernel Modules (Out Of Tree Modules) ==
This will create a git commit of a single patch in your tree.


{{Admon/warning | This section needs to be updated and fleshed out}}
=== Configuring the kernel ===
{{admon/note| Potential options to the instructions below|Consider using the make targets "mrproper" and "menuconfig" as specified in the top-level README file.  The "menuconfig" target is an alternative to "oldconfig" and pops up a menu that allows you to easily set virtually all build options. Accepting the defaults is generally fine, although you can use the "General Setup->Local version" option to append a label to your build instead of tweaking "EXTRAVERSION" in the .config file.}}


This section is for users who are only interested in working on a kernel module, and who do not wish to build an entire custom kernel. It is not necessary to download and rebuild the entire kernel in order to build a module. To build a module for the currently running kernel, only the matching <code>kernel-devel</code> package is required. Run the following command to install the <code>kernel-devel</code> package using <code>yum</code>.
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 <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.
* FIXME how to grab a rawhide config


<pre>su -c 'yum install kernel-devel'
With the config in place, you are now ready to move on to the next step.
</pre>


{{Admon/note | You may need to install 'kernel-PAE-devel' if you are using the PAE kernel}}
=== Building the kernel ===
<code> $EDITOR Makefile </code>
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)


You can build against any kernel version, as long as you have <code>kernel</code> and <code>kernel-devel</code> packages installed for that version.  The rest of this section assumes we're building for the running kernel; if not, replace <code>`uname -r`</code> with the desired version number.
<code> $ make oldconfig </code>


{{Admon/note | The kernel-doc package contains official Kbuild documentation - see files under Documentation/kbuild, in particular the modules.txt file. }}
<code> $ make bzImage </code>


As a simple example, to build the <code>foo.ko</code> module from <code>foo.c</code>, create the following <code>Makefile</code> in the directory containing the <code>foo.c</code> file:
<code> $ make modules </code>


<pre>obj-m := foo.o
(become root)


KDIR  := /lib/modules/$(shell uname -r)/build
<code> # make modules_install </code>
PWD  := $(shell pwd)


default:
<code> # make install </code>
[TAB]$(MAKE) -C $(KDIR) M=$(PWD) modules
</pre>
[TAB] Denotes a tab character which must come first for makefile lines containing commands.


Then, issue the <code>make</code> command to build the <code>foo.ko</code> module.
You have now built and installed a kernel.  It will show up in the grub menu next time you reboot.


The above is a helpful local Makefile wrapper invoking kbuild; in general you can simply do things like
=== 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.


<pre># make -C /lib/modules/`uname -r`/build M=`pwd` modules
=== Cleaning up ===
# make -C /lib/modules/`uname -r`/build M=`pwd` clean
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. (Be sure to get the kernel version correct!)  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)
# make -C /lib/modules/`uname -r`/build M=`pwd` modules_install
<pre>
rm -f /boot/config-2.6.*dave* /boot/initrd-2.6.*dave* /boot/vmlinuz-*dave* /boot/System.map-*dave* /boot/loader/entries/*dave*
rm -rf /lib/modules/2.6*dave*
</pre>
Finally, you will need to remove the kernel as an option to your bootloader. This will change from architecture to architecture. For x86, (as root), edit /boot/grub2/grub.cfg or /boot/efi/EFI/fedora/grub.cfg if you have EFI enabled and delete the four lines relating to your kernel (They should be easy to spot, they'll be the ones with your tag). They'll look something like this..
<pre>
title Fedora Core (2.6.22-rc3-dave)
root (hd0,0)
kernel /vmlinuz-2.6.22-rc3-dave ro root=/dev/md0
initrd /initrd-2.6.22-rc3-dave.img
</pre>
</pre>
etc to build those targets.

Latest revision as of 09:05, 22 July 2024

This document provides instructions for advanced users who want to rebuild the kernel from some source. Note, however, that when building or running any such kernel, one should NOT expect support from the Fedora kernel team; you're pretty much on your own here if something doesn't work as you'd hoped or expected. But hey, you're an advanced user, so you can handle it, right? Anyway, advanced users build custom kernels for a variety of reasons:

  • 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


Dependencies for building kernels

Not all of these will apply to all methods but this provides a good dependency list of items to install

# sudo dnf install fedpkg fedora-packager rpmdevtools ncurses-devel pesign grubby

Give the following command from the top directory of the kernel source tree once you have checked it out

# sudo dnf builddep kernel.spec

if you plan to run 'make xconfig'

# sudo dnf install qt5-qtbase-devel libXi-devel gcc-c++

Also make sure you add the user doing the build to /etc/pesign/users and run the authorize user script:

# sudo /usr/libexec/pesign/pesign-authorize

It should be noted that pesign pesign-rh-test-certs gets pulled in automatically for some, but not for everyone, it depends on how you installed pesign. It is best to make sure that you have it installed.

pesign
Also note that pesign is applicable only for UEFI platforms (x86, arm, aarch64), it's not used on eg. ppc64le or s390x.
dnf versus yum
As of Fedora 22[1] dnf has replaced yum as the default package manager. In the event you are building a kernel for an older system you will either have to install dnf or substitute yum for dnf and/or yumdownloader from the yum-utils package.

Building a Kernel from the Fedora source tree

Make sure you have installed all dependencies

$ fedpkg clone kernel

you will likely need to checkout the source anonymously unless you have an Fedora developer account

$ fedpkg clone -a kernel

As of the time of this wiki writing, the kernel is managed using git. Each fedora release is a separate branch. rawhide tracks master. To get the tree for a particular release, you can use git checkout from the top of your newly created source tree.

e.g. for fedora 23,

$ git checkout origin/f23

You can now make whatever changes / customizations you need before generating the rpms and installing them. To avoid conflicts you may want to consider changing

# define buildid .local

to e.g.

%define buildid .foobar

in kernel.spec.

Whatever you choose instead of foobar will show up in the name of the generated rpm's and will also show up in the GRUB boot menu.

When finished, generate the appropriate rpms with

$ fedpkg local

The rpms will be generated in a subdirectory $ARCH which can then be installed:

$ sudo dnf install --nogpgcheck \
   ./x86_64/kernel-modules-core-$version.rpm \
   ./x86_64/kernel-core-$version.rpm \
   ./x86_64/kernel-modules-$version.rpm \
   ./x86_64/kernel-$version.rpm

After installing the packages, the kernel will appear in the GRUB menu after next reboot. To uninstall, boot into a kernel different from the one to be uninstalled and do

$ sudo dnf remove kernel-core-$version

A complete walkthrough could look like this:

sudo dnf install fedpkg fedora-packager rpmdevtools ncurses-devel pesign grubby
sudo dnf install qt5-qtbase-devel libXi-devel gcc-c++
sudo bash -c "echo $USER >> /etc/pesign/users"
sudo /usr/libexec/pesign/pesign-authorize
fedpkg clone -a kernel
cd kernel
git fetch
git switch f34
sed -i 's/# define buildid .local/%define buildid .foobar/g' kernel.spec
sudo dnf builddep kernel.spec
fedpkg local
cd x86_64
sudo dnf install --nogpgcheck \
  kernel-core-5.17.12-100.foobar.fc34.x86_64.rpm \
  kernel-modules-5.17.12-100.foobar.fc34.x86_64.rpm \
  kernel-5.17.12-100.foobar.fc34.x86_64.rpm


Building a non-debugging kernel

Branched kernels are built with debugging enabled by default in the early stages of the release to assist developers. To make a kernel with debugging information disabled, you can follow the above instructions to check out and do:

$ make release

$ fedpkg local

Enabling config options

If there are configuration options that need to be adjusted for your build, you can add changes in the kernel-local file. These changes will get picked up when you build.

Updating

  • $ cd kernel
  • kernel $ git status
    • your tree will be dirty in the configs and kernel.spec
  • kernel $ git stash
    • puts aside your changes so your tree will be clean
  • kernel $ git pull origin
    • update to the latest tree from fedpkg git

Now you can run whatever other commands you want (e.g. make release)

Building a kernel from the exploded git trees

Fedora maintains a git tree containing Fedora patches applied on top of the vanilla sources.

$ git clone https://gitlab.com/cki-project/kernel-ark

$ git checkout -b my_branch kernel-4.7.4-200.fc24

You can now build the kernel following regular kernel instructions. This tree is useful for generating patches that can be applied to the kernel.spec.

Building a Kernel from the source RPM

Instructions for this are on a separate page. In general, you should use one of the other methods for building the kernel which are much easier.

Building Only Kernel Modules (Out Of Tree Modules)

This section needs to be updated and fleshed out

This section is for users who are only interested in working on a kernel module, and who do not wish to build an entire custom kernel. It is not necessary to download and rebuild the entire kernel in order to build a module. To build a module for the currently running kernel, only the matching kernel-devel package is required. Run the following command to install the kernel-devel package using dnf.

su -c 'dnf install kernel-devel'
You may need to install 'kernel-PAE-devel' if you are using the PAE kernel

You can build against any kernel version, as long as you have kernel and kernel-devel packages installed for that version. The rest of this section assumes we're building for the running kernel; if not, replace uname -r with the desired version number.

As a simple example, to build the foo.ko module from foo.c, create the following Makefile in the directory containing the foo.c file:

obj-m := foo.o

KDIR  := /lib/modules/$(shell uname -r)/build
PWD   := $(shell pwd)

default:
[TAB]$(MAKE) -C $(KDIR) M=$(PWD) modules

[TAB] Denotes a tab character which must come first for makefile lines containing commands.

Then, issue the make command to build the foo.ko module.

The above is a helpful local Makefile wrapper invoking kbuild; in general you can simply do things like

# make -C /lib/modules/`uname -r`/build M=`pwd` modules
# make -C /lib/modules/`uname -r`/build M=`pwd` clean
# make -C /lib/modules/`uname -r`/build M=`pwd` modules_install

etc to build those targets.

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

Existing Fedora Vanilla packages

There is an effort underway for packaging vanilla kernels. See if this meets your needs first

Getting the sources

Clone a kernel tree from kernel.org

Tips for developing with kernel.org sources
The README file in the top-level directory provides very good build instructions, including how to direct the build to a particular directory, the necessary make targets, and the order in which to issue them. Save time by reviewing the Documentation directory and its sub-directories containing informative ".txt" files. View the top level Makefile for kernel version information.

$ 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. (While the tree is syncing, why not take the time to update some steps on this wiki that are inevitably out of date?)

$ cd linux

If you need the stable kernel releases, add the stable remote:

$ git remote add -f stable git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git

Double check what baseline is being used and check out a new one if necessary:

$ git checkout v4.5.2

Applying patches

The patch method

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

$ cat ~/testpatch.diff | patch -p1

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.

The git method

Most developers these days generate patches using git and you can use git to help apply patches. You can do:

$ git am -3 <patch file>

This will create a git commit of a single patch in your tree.

Configuring the kernel

Potential options to the instructions below
Consider using the make targets "mrproper" and "menuconfig" as specified in the top-level README file. The "menuconfig" target is an alternative to "oldconfig" and pops up a menu that allows you to easily set virtually all build options. Accepting the defaults is generally fine, although you can use the "General Setup->Local version" option to append a label to your build instead of tweaking "EXTRAVERSION" in the .config file.

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

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.

  • FIXME how to grab a rawhide config

With the config in place, you are now ready to move on to the next step.

Building the kernel

$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

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

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. (Be sure to get the kernel version correct!) 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)

rm -f /boot/config-2.6.*dave* /boot/initrd-2.6.*dave* /boot/vmlinuz-*dave* /boot/System.map-*dave* /boot/loader/entries/*dave*
rm -rf /lib/modules/2.6*dave*

Finally, you will need to remove the kernel as an option to your bootloader. This will change from architecture to architecture. For x86, (as root), edit /boot/grub2/grub.cfg or /boot/efi/EFI/fedora/grub.cfg if you have EFI enabled and delete the four lines relating to your kernel (They should be easy to spot, they'll be the ones with your tag). They'll look something like this..

title Fedora Core (2.6.22-rc3-dave)
root (hd0,0)
kernel /vmlinuz-2.6.22-rc3-dave ro root=/dev/md0
initrd /initrd-2.6.22-rc3-dave.img