| .. SPDX-License-Identifier: (GPL-2.0+ OR CC-BY-4.0) | 
 | .. [see the bottom of this file for redistribution information] | 
 |  | 
 | ========================================= | 
 | How to verify bugs and bisect regressions | 
 | ========================================= | 
 |  | 
 | This document describes how to check if some Linux kernel problem occurs in code | 
 | currently supported by developers -- to then explain how to locate the change | 
 | causing the issue, if it is a regression (e.g. did not happen with earlier | 
 | versions). | 
 |  | 
 | The text aims at people running kernels from mainstream Linux distributions on | 
 | commodity hardware who want to report a kernel bug to the upstream Linux | 
 | developers. Despite this intent, the instructions work just as well for users | 
 | who are already familiar with building their own kernels: they help avoid | 
 | mistakes occasionally made even by experienced developers. | 
 |  | 
 | .. | 
 |    Note: if you see this note, you are reading the text's source file. You | 
 |    might want to switch to a rendered version: it makes it a lot easier to | 
 |    read and navigate this document -- especially when you want to look something | 
 |    up in the reference section, then jump back to where you left off. | 
 | .. | 
 |    Find the latest rendered version of this text here: | 
 |    https://docs.kernel.org/admin-guide/verify-bugs-and-bisect-regressions.html | 
 |  | 
 | The essence of the process (aka 'TL;DR') | 
 | ======================================== | 
 |  | 
 | *[If you are new to building or bisecting Linux, ignore this section and head | 
 | over to the* ':ref:`step-by-step guide <introguide_bissbs>`' *below. It utilizes | 
 | the same commands as this section while describing them in brief fashion. The | 
 | steps are nevertheless easy to follow and together with accompanying entries | 
 | in a reference section mention many alternatives, pitfalls, and additional | 
 | aspects, all of which might be essential in your present case.]* | 
 |  | 
 | **In case you want to check if a bug is present in code currently supported by | 
 | developers**, execute just the *preparations* and *segment 1*; while doing so, | 
 | consider the newest Linux kernel you regularly use to be the 'working' kernel. | 
 | In the following example that's assumed to be 6.0, which is why its sources | 
 | will be used to prepare the .config file. | 
 |  | 
 | **In case you face a regression**, follow the steps at least till the end of | 
 | *segment 2*. Then you can submit a preliminary report -- or continue with | 
 | *segment 3*, which describes how to perform a bisection needed for a | 
 | full-fledged regression report. In the following example 6.0.13 is assumed to be | 
 | the 'working' kernel and 6.1.5 to be the first 'broken', which is why 6.0 | 
 | will be considered the 'good' release and used to prepare the .config file. | 
 |  | 
 | * **Preparations**: set up everything to build your own kernels:: | 
 |  | 
 |     # * Remove any software that depends on externally maintained kernel modules | 
 |     #   or builds any automatically during bootup. | 
 |     # * Ensure Secure Boot permits booting self-compiled Linux kernels. | 
 |     # * If you are not already running the 'working' kernel, reboot into it. | 
 |     # * Install compilers and everything else needed for building Linux. | 
 |     # * Ensure to have 15 Gigabyte free space in your home directory. | 
 |     git clone -o mainline --no-checkout \ | 
 |       https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git ~/linux/ | 
 |     cd ~/linux/ | 
 |     git remote add -t master stable \ | 
 |       https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git | 
 |     git switch --detach v6.0 | 
 |     # * Hint: if you used an existing clone, ensure no stale .config is around. | 
 |     make olddefconfig | 
 |     # * Ensure the former command picked the .config of the 'working' kernel. | 
 |     # * Connect external hardware (USB keys, tokens, ...), start a VM, bring up | 
 |     #   VPNs, mount network shares, and briefly try the feature that is broken. | 
 |     yes '' | make localmodconfig | 
 |     ./scripts/config --set-str CONFIG_LOCALVERSION '-local' | 
 |     ./scripts/config -e CONFIG_LOCALVERSION_AUTO | 
 |     # * Note, when short on storage space, check the guide for an alternative: | 
 |     ./scripts/config -d DEBUG_INFO_NONE -e KALLSYMS_ALL -e DEBUG_KERNEL \ | 
 |       -e DEBUG_INFO -e DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT -e KALLSYMS | 
 |     # * Hint: at this point you might want to adjust the build configuration; | 
 |     #   you'll have to, if you are running Debian. | 
 |     make olddefconfig | 
 |     cp .config ~/kernel-config-working | 
 |  | 
 | * **Segment 1**: build a kernel from the latest mainline codebase. | 
 |  | 
 |   This among others checks if the problem was fixed already and which developers | 
 |   later need to be told about the problem; in case of a regression, this rules | 
 |   out a .config change as root of the problem. | 
 |  | 
 |   a) Checking out latest mainline code:: | 
 |  | 
 |        cd ~/linux/ | 
 |        git switch --discard-changes --detach mainline/master | 
 |  | 
 |   b) Build, install, and boot a kernel:: | 
 |  | 
 |        cp ~/kernel-config-working .config | 
 |        make olddefconfig | 
 |        make -j $(nproc --all) | 
 |        # * Make sure there is enough disk space to hold another kernel: | 
 |        df -h /boot/ /lib/modules/ | 
 |        # * Note: on Arch Linux, its derivatives and a few other distributions | 
 |        #   the following commands will do nothing at all or only part of the | 
 |        #   job. See the step-by-step guide for further details. | 
 |        sudo make modules_install | 
 |        command -v installkernel && sudo make install | 
 |        # * Check how much space your self-built kernel actually needs, which | 
 |        #   enables you to make better estimates later: | 
 |        du -ch /boot/*$(make -s kernelrelease)* | tail -n 1 | 
 |        du -sh /lib/modules/$(make -s kernelrelease)/ | 
 |        # * Hint: the output of the following command will help you pick the | 
 |        #   right kernel from the boot menu: | 
 |        make -s kernelrelease | tee -a ~/kernels-built | 
 |        reboot | 
 |        # * Once booted, ensure you are running the kernel you just built by | 
 |        #   checking if the output of the next two commands matches: | 
 |        tail -n 1 ~/kernels-built | 
 |        uname -r | 
 |        cat /proc/sys/kernel/tainted | 
 |  | 
 |   c) Check if the problem occurs with this kernel as well. | 
 |  | 
 | * **Segment 2**: ensure the 'good' kernel is also a 'working' kernel. | 
 |  | 
 |   This among others verifies the trimmed .config file actually works well, as | 
 |   bisecting with it otherwise would be a waste of time: | 
 |  | 
 |   a) Start by checking out the sources of the 'good' version:: | 
 |  | 
 |        cd ~/linux/ | 
 |        git switch --discard-changes --detach v6.0 | 
 |  | 
 |   b) Build, install, and boot a kernel as described earlier in *segment 1, | 
 |      section b* -- just feel free to skip the 'du' commands, as you have a rough | 
 |      estimate already. | 
 |  | 
 |   c) Ensure the feature that regressed with the 'broken' kernel actually works | 
 |      with this one. | 
 |  | 
 | * **Segment 3**: perform and validate the bisection. | 
 |  | 
 |   a) Retrieve the sources for your 'bad' version:: | 
 |  | 
 |        git remote set-branches --add stable linux-6.1.y | 
 |        git fetch stable | 
 |  | 
 |   b) Initialize the bisection:: | 
 |  | 
 |        cd ~/linux/ | 
 |        git bisect start | 
 |        git bisect good v6.0 | 
 |        git bisect bad v6.1.5 | 
 |  | 
 |   c) Build, install, and boot a kernel as described earlier in *segment 1, | 
 |      section b*. | 
 |  | 
 |      In case building or booting the kernel fails for unrelated reasons, run | 
 |      ``git bisect skip``. In all other outcomes, check if the regressed feature | 
 |      works with the newly built kernel. If it does, tell Git by executing | 
 |      ``git bisect good``; if it does not, run ``git bisect bad`` instead. | 
 |  | 
 |      All three commands will make Git check out another commit; then re-execute | 
 |      this step (e.g. build, install, boot, and test a kernel to then tell Git | 
 |      the outcome). Do so again and again until Git shows which commit broke | 
 |      things. If you run short of disk space during this process, check the | 
 |      section 'Complementary tasks: cleanup during and after the process' | 
 |      below. | 
 |  | 
 |   d) Once your finished the bisection, put a few things away:: | 
 |  | 
 |        cd ~/linux/ | 
 |        git bisect log > ~/bisect-log | 
 |        cp .config ~/bisection-config-culprit | 
 |        git bisect reset | 
 |  | 
 |   e) Try to verify the bisection result:: | 
 |  | 
 |        git switch --discard-changes --detach mainline/master | 
 |        git revert --no-edit cafec0cacaca0 | 
 |        cp ~/kernel-config-working .config | 
 |        ./scripts/config --set-str CONFIG_LOCALVERSION '-local-cafec0cacaca0-reverted' | 
 |  | 
 |     This is optional, as some commits are impossible to revert. But if the | 
 |     second command worked flawlessly, build, install, and boot one more kernel | 
 |     kernel; just this time skip the first command copying the base .config file | 
 |     over, as that already has been taken care off. | 
 |  | 
 | * **Complementary tasks**: cleanup during and after the process. | 
 |  | 
 |   a) To avoid running out of disk space during a bisection, you might need to | 
 |      remove some kernels you built earlier. You most likely want to keep those | 
 |      you built during segment 1 and 2 around for a while, but you will most | 
 |      likely no longer need kernels tested during the actual bisection | 
 |      (Segment 3 c). You can list them in build order using:: | 
 |  | 
 |        ls -ltr /lib/modules/*-local* | 
 |  | 
 |     To then for example erase a kernel that identifies itself as | 
 |     '6.0-rc1-local-gcafec0cacaca0', use this:: | 
 |  | 
 |        sudo rm -rf /lib/modules/6.0-rc1-local-gcafec0cacaca0 | 
 |        sudo kernel-install -v remove 6.0-rc1-local-gcafec0cacaca0 | 
 |        # * Note, on some distributions kernel-install is missing | 
 |        #   or does only part of the job. | 
 |  | 
 |   b) If you performed a bisection and successfully validated the result, feel | 
 |      free to remove all kernels built during the actual bisection (Segment 3 c); | 
 |      the kernels you built earlier and later you might want to keep around for | 
 |      a week or two. | 
 |  | 
 | * **Optional task**: test a debug patch or a proposed fix later:: | 
 |  | 
 |     git fetch mainline | 
 |     git switch --discard-changes --detach mainline/master | 
 |     git apply /tmp/foobars-proposed-fix-v1.patch | 
 |     cp ~/kernel-config-working .config | 
 |     ./scripts/config --set-str CONFIG_LOCALVERSION '-local-foobars-fix-v1' | 
 |  | 
 |   Build, install, and boot a kernel as described in *segment 1, section b* -- | 
 |   but this time omit the first command copying the build configuration over, | 
 |   as that has been taken care of already. | 
 |  | 
 | .. _introguide_bissbs: | 
 |  | 
 | Step-by-step guide on how to verify bugs and bisect regressions | 
 | =============================================================== | 
 |  | 
 | This guide describes how to set up your own Linux kernels for investigating bugs | 
 | or regressions you intend to report. How far you want to follow the instructions | 
 | depends on your issue: | 
 |  | 
 | Execute all steps till the end of *segment 1* to **verify if your kernel problem | 
 | is present in code supported by Linux kernel developers**. If it is, you are all | 
 | set to report the bug -- unless it did not happen with earlier kernel versions, | 
 | as then your want to at least continue with *segment 2* to **check if the issue | 
 | qualifies as regression** which receive priority treatment. Depending on the | 
 | outcome you then are ready to report a bug or submit a preliminary regression | 
 | report; instead of the latter your could also head straight on and follow | 
 | *segment 3* to **perform a bisection** for a full-fledged regression report | 
 | developers are obliged to act upon. | 
 |  | 
 |  :ref:`Preparations: set up everything to build your own kernels <introprep_bissbs>`. | 
 |  | 
 |  :ref:`Segment 1: try to reproduce the problem with the latest codebase <introlatestcheck_bissbs>`. | 
 |  | 
 |  :ref:`Segment 2: check if the kernels you build work fine <introworkingcheck_bissbs>`. | 
 |  | 
 |  :ref:`Segment 3: perform a bisection and validate the result <introbisect_bissbs>`. | 
 |  | 
 |  :ref:`Complementary tasks: cleanup during and after following this guide <introclosure_bissbs>`. | 
 |  | 
 |  :ref:`Optional tasks: test reverts, patches, or later versions <introoptional_bissbs>`. | 
 |  | 
 | The steps in each segment illustrate the important aspects of the process, while | 
 | a comprehensive reference section holds additional details for almost all of the | 
 | steps. The reference section sometimes also outlines alternative approaches, | 
 | pitfalls, as well as problems that might occur at the particular step -- and how | 
 | to get things rolling again. | 
 |  | 
 | For further details on how to report Linux kernel issues or regressions check | 
 | out Documentation/admin-guide/reporting-issues.rst, which works in conjunction | 
 | with this document. It among others explains why you need to verify bugs with | 
 | the latest 'mainline' kernel (e.g. versions like 6.0, 6.1-rc1, or 6.1-rc6), | 
 | even if you face a problem with a kernel from a 'stable/longterm' series | 
 | (say 6.0.13). | 
 |  | 
 | For users facing a regression that document also explains why sending a | 
 | preliminary report after segment 2 might be wise, as the regression and its | 
 | culprit might be known already. For further details on what actually qualifies | 
 | as a regression check out Documentation/admin-guide/reporting-regressions.rst. | 
 |  | 
 | If you run into any problems while following this guide or have ideas how to | 
 | improve it, :ref:`please let the kernel developers know <submit_improvements>`. | 
 |  | 
 | .. _introprep_bissbs: | 
 |  | 
 | Preparations: set up everything to build your own kernels | 
 | --------------------------------------------------------- | 
 |  | 
 | The following steps lay the groundwork for all further tasks. | 
 |  | 
 | Note: the instructions assume you are building and testing on the same | 
 | machine; if you want to compile the kernel on another system, check | 
 | :ref:`Build kernels on a different machine <buildhost_bis>` below. | 
 |  | 
 | .. _backup_bissbs: | 
 |  | 
 | * Create a fresh backup and put system repair and restore tools at hand, just | 
 |   to be prepared for the unlikely case of something going sideways. | 
 |  | 
 |   [:ref:`details <backup_bisref>`] | 
 |  | 
 | .. _vanilla_bissbs: | 
 |  | 
 | * Remove all software that depends on externally developed kernel drivers or | 
 |   builds them automatically. That includes but is not limited to DKMS, openZFS, | 
 |   VirtualBox, and Nvidia's graphics drivers (including the GPLed kernel module). | 
 |  | 
 |   [:ref:`details <vanilla_bisref>`] | 
 |  | 
 | .. _secureboot_bissbs: | 
 |  | 
 | * On platforms with 'Secure Boot' or similar solutions, prepare everything to | 
 |   ensure the system will permit your self-compiled kernel to boot. The | 
 |   quickest and easiest way to achieve this on commodity x86 systems is to | 
 |   disable such techniques in the BIOS setup utility; alternatively, remove | 
 |   their restrictions through a process initiated by | 
 |   ``mokutil --disable-validation``. | 
 |  | 
 |   [:ref:`details <secureboot_bisref>`] | 
 |  | 
 | .. _rangecheck_bissbs: | 
 |  | 
 | * Determine the kernel versions considered 'good' and 'bad' throughout this | 
 |   guide: | 
 |  | 
 |   * Do you follow this guide to verify if a bug is present in the code the | 
 |     primary developers care for? Then consider the version of the newest kernel | 
 |     you regularly use currently as 'good' (e.g. 6.0, 6.0.13, or 6.1-rc2). | 
 |  | 
 |   * Do you face a regression, e.g. something broke or works worse after | 
 |     switching to a newer kernel version? In that case it depends on the version | 
 |     range during which the problem appeared: | 
 |  | 
 |     * Something regressed when updating from a stable/longterm release | 
 |       (say 6.0.13) to a newer mainline series (like 6.1-rc7 or 6.1) or a | 
 |       stable/longterm version based on one (say 6.1.5)? Then consider the | 
 |       mainline release your working kernel is based on to be the 'good' | 
 |       version (e.g. 6.0) and the first version to be broken as the 'bad' one | 
 |       (e.g. 6.1-rc7, 6.1, or 6.1.5). Note, at this point it is merely assumed | 
 |       that 6.0 is fine; this hypothesis will be checked in segment 2. | 
 |  | 
 |     * Something regressed when switching from one mainline version (say 6.0) to | 
 |       a later one (like 6.1-rc1) or a stable/longterm release based on it | 
 |       (say 6.1.5)? Then regard the last working version (e.g. 6.0) as 'good' and | 
 |       the first broken (e.g. 6.1-rc1 or 6.1.5) as 'bad'. | 
 |  | 
 |     * Something regressed when updating within a stable/longterm series (say | 
 |       from 6.0.13 to 6.0.15)? Then consider those versions as 'good' and 'bad' | 
 |       (e.g. 6.0.13 and 6.0.15), as you need to bisect within that series. | 
 |  | 
 |   *Note, do not confuse 'good' version with 'working' kernel; the latter term | 
 |   throughout this guide will refer to the last kernel that has been working | 
 |   fine.* | 
 |  | 
 |   [:ref:`details <rangecheck_bisref>`] | 
 |  | 
 | .. _bootworking_bissbs: | 
 |  | 
 | * Boot into the 'working' kernel and briefly use the apparently broken feature. | 
 |  | 
 |   [:ref:`details <bootworking_bisref>`] | 
 |  | 
 | .. _diskspace_bissbs: | 
 |  | 
 | * Ensure to have enough free space for building Linux. 15 Gigabyte in your home | 
 |   directory should typically suffice. If you have less available, be sure to pay | 
 |   attention to later steps about retrieving the Linux sources and handling of | 
 |   debug symbols: both explain approaches reducing the amount of space, which | 
 |   should allow you to master these tasks with about 4 Gigabytes free space. | 
 |  | 
 |   [:ref:`details <diskspace_bisref>`] | 
 |  | 
 | .. _buildrequires_bissbs: | 
 |  | 
 | * Install all software required to build a Linux kernel. Often you will need: | 
 |   'bc', 'binutils' ('ld' et al.), 'bison', 'flex', 'gcc', 'git', 'openssl', | 
 |   'pahole', 'perl', and the development headers for 'libelf' and 'openssl'. The | 
 |   reference section shows how to quickly install those on various popular Linux | 
 |   distributions. | 
 |  | 
 |   [:ref:`details <buildrequires_bisref>`] | 
 |  | 
 | .. _sources_bissbs: | 
 |  | 
 | * Retrieve the mainline Linux sources; then change into the directory holding | 
 |   them, as all further commands in this guide are meant to be executed from | 
 |   there. | 
 |  | 
 |   *Note, the following describe how to retrieve the sources using a full | 
 |   mainline clone, which downloads about 2,75 GByte as of early 2024. The* | 
 |   :ref:`reference section describes two alternatives <sources_bisref>` *: | 
 |   one downloads less than 500 MByte, the other works better with unreliable | 
 |   internet connections.* | 
 |  | 
 |   Execute the following command to retrieve a fresh mainline codebase while | 
 |   preparing things to add branches for stable/longterm series later:: | 
 |  | 
 |     git clone -o mainline --no-checkout \ | 
 |       https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git ~/linux/ | 
 |     cd ~/linux/ | 
 |     git remote add -t master stable \ | 
 |       https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git | 
 |  | 
 |   [:ref:`details <sources_bisref>`] | 
 |  | 
 | .. _stablesources_bissbs: | 
 |  | 
 | * Is one of the versions you earlier established as 'good' or 'bad' a stable or | 
 |   longterm release (say 6.1.5)? Then download the code for the series it belongs | 
 |   to ('linux-6.1.y' in this example):: | 
 |  | 
 |     git remote set-branches --add stable linux-6.1.y | 
 |     git fetch stable | 
 |  | 
 | .. _oldconfig_bissbs: | 
 |  | 
 | * Start preparing a kernel build configuration (the '.config' file). | 
 |  | 
 |   Before doing so, ensure you are still running the 'working' kernel an earlier | 
 |   step told you to boot; if you are unsure, check the current kernelrelease | 
 |   identifier using ``uname -r``. | 
 |  | 
 |   Afterwards check out the source code for the version earlier established as | 
 |   'good'. In the following example command this is assumed to be 6.0; note that | 
 |   the version number in this and all later Git commands needs to be prefixed | 
 |   with a 'v':: | 
 |  | 
 |     git switch --discard-changes --detach v6.0 | 
 |  | 
 |   Now create a build configuration file:: | 
 |  | 
 |     make olddefconfig | 
 |  | 
 |   The kernel build scripts then will try to locate the build configuration file | 
 |   for the running kernel and then adjust it for the needs of the kernel sources | 
 |   you checked out. While doing so, it will print a few lines you need to check. | 
 |  | 
 |   Look out for a line starting with '# using defaults found in'. It should be | 
 |   followed by a path to a file in '/boot/' that contains the release identifier | 
 |   of your currently working kernel. If the line instead continues with something | 
 |   like 'arch/x86/configs/x86_64_defconfig', then the build infra failed to find | 
 |   the .config file for your running kernel -- in which case you have to put one | 
 |   there manually, as explained in the reference section. | 
 |  | 
 |   In case you can not find such a line, look for one containing '# configuration | 
 |   written to .config'. If that's the case you have a stale build configuration | 
 |   lying around. Unless you intend to use it, delete it; afterwards run | 
 |   'make olddefconfig' again and check if it now picked up the right config file | 
 |   as base. | 
 |  | 
 |   [:ref:`details <oldconfig_bisref>`] | 
 |  | 
 | .. _localmodconfig_bissbs: | 
 |  | 
 | * Disable any kernel modules apparently superfluous for your setup. This is | 
 |   optional, but especially wise for bisections, as it speeds up the build | 
 |   process enormously -- at least unless the .config file picked up in the | 
 |   previous step was already tailored to your and your hardware needs, in which | 
 |   case you should skip this step. | 
 |  | 
 |   To prepare the trimming, connect external hardware you occasionally use (USB | 
 |   keys, tokens, ...), quickly start a VM, and bring up VPNs. And if you rebooted | 
 |   since you started that guide, ensure that you tried using the feature causing | 
 |   trouble since you started the system. Only then trim your .config:: | 
 |  | 
 |      yes '' | make localmodconfig | 
 |  | 
 |   There is a catch to this, as the 'apparently' in initial sentence of this step | 
 |   and the preparation instructions already hinted at: | 
 |  | 
 |   The 'localmodconfig' target easily disables kernel modules for features only | 
 |   used occasionally -- like modules for external peripherals not yet connected | 
 |   since booting, virtualization software not yet utilized, VPN tunnels, and a | 
 |   few other things. That's because some tasks rely on kernel modules Linux only | 
 |   loads when you execute tasks like the aforementioned ones for the first time. | 
 |  | 
 |   This drawback of localmodconfig is nothing you should lose sleep over, but | 
 |   something to keep in mind: if something is misbehaving with the kernels built | 
 |   during this guide, this is most likely the reason. You can reduce or nearly | 
 |   eliminate the risk with tricks outlined in the reference section; but when | 
 |   building a kernel just for quick testing purposes this is usually not worth | 
 |   spending much effort on, as long as it boots and allows to properly test the | 
 |   feature that causes trouble. | 
 |  | 
 |   [:ref:`details <localmodconfig_bisref>`] | 
 |  | 
 | .. _tagging_bissbs: | 
 |  | 
 | * Ensure all the kernels you will build are clearly identifiable using a special | 
 |   tag and a unique version number:: | 
 |  | 
 |     ./scripts/config --set-str CONFIG_LOCALVERSION '-local' | 
 |     ./scripts/config -e CONFIG_LOCALVERSION_AUTO | 
 |  | 
 |   [:ref:`details <tagging_bisref>`] | 
 |  | 
 | .. _debugsymbols_bissbs: | 
 |  | 
 | * Decide how to handle debug symbols. | 
 |  | 
 |   In the context of this document it is often wise to enable them, as there is a | 
 |   decent chance you will need to decode a stack trace from a 'panic', 'Oops', | 
 |   'warning', or 'BUG':: | 
 |  | 
 |     ./scripts/config -d DEBUG_INFO_NONE -e KALLSYMS_ALL -e DEBUG_KERNEL \ | 
 |       -e DEBUG_INFO -e DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT -e KALLSYMS | 
 |  | 
 |   But if you are extremely short on storage space, you might want to disable | 
 |   debug symbols instead:: | 
 |  | 
 |     ./scripts/config -d DEBUG_INFO -d DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT \ | 
 |       -d DEBUG_INFO_DWARF4 -d DEBUG_INFO_DWARF5 -e CONFIG_DEBUG_INFO_NONE | 
 |  | 
 |   [:ref:`details <debugsymbols_bisref>`] | 
 |  | 
 | .. _configmods_bissbs: | 
 |  | 
 | * Check if you may want or need to adjust some other kernel configuration | 
 |   options: | 
 |  | 
 |   * Are you running Debian? Then you want to avoid known problems by performing | 
 |     additional adjustments explained in the reference section. | 
 |  | 
 |     [:ref:`details <configmods_distros_bisref>`]. | 
 |  | 
 |   * If you want to influence other aspects of the configuration, do so now using | 
 |     your preferred tool. Note, to use make targets like 'menuconfig' or | 
 |     'nconfig', you will need to install the development files of ncurses; for | 
 |     'xconfig' you likewise need the Qt5 or Qt6 headers. | 
 |  | 
 |     [:ref:`details <configmods_individual_bisref>`]. | 
 |  | 
 | .. _saveconfig_bissbs: | 
 |  | 
 | * Reprocess the .config after the latest adjustments and store it in a safe | 
 |   place:: | 
 |  | 
 |      make olddefconfig | 
 |      cp .config ~/kernel-config-working | 
 |  | 
 |   [:ref:`details <saveconfig_bisref>`] | 
 |  | 
 | .. _introlatestcheck_bissbs: | 
 |  | 
 | Segment 1: try to reproduce the problem with the latest codebase | 
 | ---------------------------------------------------------------- | 
 |  | 
 | The following steps verify if the problem occurs with the code currently | 
 | supported by developers. In case you face a regression, it also checks that the | 
 | problem is not caused by some .config change, as reporting the issue then would | 
 | be a waste of time. [:ref:`details <introlatestcheck_bisref>`] | 
 |  | 
 | .. _checkoutmaster_bissbs: | 
 |  | 
 | * Check out the latest Linux codebase. | 
 |  | 
 |   * Are your 'good' and 'bad' versions from the same stable or longterm series? | 
 |     Then check the `front page of kernel.org <https://kernel.org/>`_: if it | 
 |     lists a release from that series without an '[EOL]' tag, checkout the series | 
 |     latest version ('linux-6.1.y' in the following example):: | 
 |  | 
 |       cd ~/linux/ | 
 |       git switch --discard-changes --detach stable/linux-6.1.y | 
 |  | 
 |     Your series is unsupported, if is not listed or carrying a 'end of life' | 
 |     tag. In that case you might want to check if a successor series (say | 
 |     linux-6.2.y) or mainline (see next point) fix the bug. | 
 |  | 
 |   * In all other cases, run:: | 
 |  | 
 |       cd ~/linux/ | 
 |       git switch --discard-changes --detach mainline/master | 
 |  | 
 |   [:ref:`details <checkoutmaster_bisref>`] | 
 |  | 
 | .. _build_bissbs: | 
 |  | 
 | * Build the image and the modules of your first kernel using the config file you | 
 |   prepared:: | 
 |  | 
 |     cp ~/kernel-config-working .config | 
 |     make olddefconfig | 
 |     make -j $(nproc --all) | 
 |  | 
 |   If you want your kernel packaged up as deb, rpm, or tar file, see the | 
 |   reference section for alternatives, which obviously will require other | 
 |   steps to install as well. | 
 |  | 
 |   [:ref:`details <build_bisref>`] | 
 |  | 
 | .. _install_bissbs: | 
 |  | 
 | * Install your newly built kernel. | 
 |  | 
 |   Before doing so, consider checking if there is still enough space for it:: | 
 |  | 
 |     df -h /boot/ /lib/modules/ | 
 |  | 
 |   For now assume 150 MByte in /boot/ and 200 in /lib/modules/ will suffice; how | 
 |   much your kernels actually require will be determined later during this guide. | 
 |  | 
 |   Now install the kernel's modules and its image, which will be stored in | 
 |   parallel to the your Linux distribution's kernels:: | 
 |  | 
 |     sudo make modules_install | 
 |     command -v installkernel && sudo make install | 
 |  | 
 |   The second command ideally will take care of three steps required at this | 
 |   point: copying the kernel's image to /boot/, generating an initramfs, and | 
 |   adding an entry for both to the boot loader's configuration. | 
 |  | 
 |   Sadly some distributions (among them Arch Linux, its derivatives, and many | 
 |   immutable Linux distributions) will perform none or only some of those tasks. | 
 |   You therefore want to check if all of them were taken care of and manually | 
 |   perform those that were not. The reference section provides further details on | 
 |   that; your distribution's documentation might help, too. | 
 |  | 
 |   Once you figured out the steps needed at this point, consider writing them | 
 |   down: if you will build more kernels as described in segment 2 and 3, you will | 
 |   have to perform those again after executing ``command -v installkernel [...]``. | 
 |  | 
 |   [:ref:`details <install_bisref>`] | 
 |  | 
 | .. _storagespace_bissbs: | 
 |  | 
 | * In case you plan to follow this guide further, check how much storage space | 
 |   the kernel, its modules, and other related files like the initramfs consume:: | 
 |  | 
 |     du -ch /boot/*$(make -s kernelrelease)* | tail -n 1 | 
 |     du -sh /lib/modules/$(make -s kernelrelease)/ | 
 |  | 
 |   Write down or remember those two values for later: they enable you to prevent | 
 |   running out of disk space accidentally during a bisection. | 
 |  | 
 |   [:ref:`details <storagespace_bisref>`] | 
 |  | 
 | .. _kernelrelease_bissbs: | 
 |  | 
 | * Show and store the kernelrelease identifier of the kernel you just built:: | 
 |  | 
 |     make -s kernelrelease | tee -a ~/kernels-built | 
 |  | 
 |   Remember the identifier momentarily, as it will help you pick the right kernel | 
 |   from the boot menu upon restarting. | 
 |  | 
 | * Reboot into your newly built kernel. To ensure your actually started the one | 
 |   you just built, you might want to verify if the output of these commands | 
 |   matches:: | 
 |  | 
 |     tail -n 1 ~/kernels-built | 
 |     uname -r | 
 |  | 
 | .. _tainted_bissbs: | 
 |  | 
 | * Check if the kernel marked itself as 'tainted':: | 
 |  | 
 |     cat /proc/sys/kernel/tainted | 
 |  | 
 |   If that command does not return '0', check the reference section, as the cause | 
 |   for this might interfere with your testing. | 
 |  | 
 |   [:ref:`details <tainted_bisref>`] | 
 |  | 
 | .. _recheckbroken_bissbs: | 
 |  | 
 | * Verify if your bug occurs with the newly built kernel. If it does not, check | 
 |   out the instructions in the reference section to ensure nothing went sideways | 
 |   during your tests. | 
 |  | 
 |   [:ref:`details <recheckbroken_bisref>`] | 
 |  | 
 | .. _recheckstablebroken_bissbs: | 
 |  | 
 | * Did you just built a stable or longterm kernel? And were you able to reproduce | 
 |   the regression with it? Then you should test the latest mainline codebase as | 
 |   well, because the result determines which developers the bug must be submitted | 
 |   to. | 
 |  | 
 |   To prepare that test, check out current mainline:: | 
 |  | 
 |     cd ~/linux/ | 
 |     git switch --discard-changes --detach mainline/master | 
 |  | 
 |   Now use the checked out code to build and install another kernel using the | 
 |   commands the earlier steps already described in more detail:: | 
 |  | 
 |     cp ~/kernel-config-working .config | 
 |     make olddefconfig | 
 |     make -j $(nproc --all) | 
 |     # * Check if the free space suffices holding another kernel: | 
 |     df -h /boot/ /lib/modules/ | 
 |     sudo make modules_install | 
 |     command -v installkernel && sudo make install | 
 |     make -s kernelrelease | tee -a ~/kernels-built | 
 |     reboot | 
 |  | 
 |   Confirm you booted the kernel you intended to start and check its tainted | 
 |   status:: | 
 |  | 
 |     tail -n 1 ~/kernels-built | 
 |     uname -r | 
 |     cat /proc/sys/kernel/tainted | 
 |  | 
 |   Now verify if this kernel is showing the problem. If it does, then you need | 
 |   to report the bug to the primary developers; if it does not, report it to the | 
 |   stable team. See Documentation/admin-guide/reporting-issues.rst for details. | 
 |  | 
 |   [:ref:`details <recheckstablebroken_bisref>`] | 
 |  | 
 | Do you follow this guide to verify if a problem is present in the code | 
 | currently supported by Linux kernel developers? Then you are done at this | 
 | point. If you later want to remove the kernel you just built, check out | 
 | :ref:`Complementary tasks: cleanup during and after following this guide <introclosure_bissbs>`. | 
 |  | 
 | In case you face a regression, move on and execute at least the next segment | 
 | as well. | 
 |  | 
 | .. _introworkingcheck_bissbs: | 
 |  | 
 | Segment 2: check if the kernels you build work fine | 
 | --------------------------------------------------- | 
 |  | 
 | In case of a regression, you now want to ensure the trimmed configuration file | 
 | you created earlier works as expected; a bisection with the .config file | 
 | otherwise would be a waste of time. [:ref:`details <introworkingcheck_bisref>`] | 
 |  | 
 | .. _recheckworking_bissbs: | 
 |  | 
 | * Build your own variant of the 'working' kernel and check if the feature that | 
 |   regressed works as expected with it. | 
 |  | 
 |   Start by checking out the sources for the version earlier established as | 
 |   'good' (once again assumed to be 6.0 here):: | 
 |  | 
 |     cd ~/linux/ | 
 |     git switch --discard-changes --detach v6.0 | 
 |  | 
 |   Now use the checked out code to configure, build, and install another kernel | 
 |   using the commands the previous subsection explained in more detail:: | 
 |  | 
 |     cp ~/kernel-config-working .config | 
 |     make olddefconfig | 
 |     make -j $(nproc --all) | 
 |     # * Check if the free space suffices holding another kernel: | 
 |     df -h /boot/ /lib/modules/ | 
 |     sudo make modules_install | 
 |     command -v installkernel && sudo make install | 
 |     make -s kernelrelease | tee -a ~/kernels-built | 
 |     reboot | 
 |  | 
 |   When the system booted, you may want to verify once again that the | 
 |   kernel you started is the one you just built:: | 
 |  | 
 |     tail -n 1 ~/kernels-built | 
 |     uname -r | 
 |  | 
 |   Now check if this kernel works as expected; if not, consult the reference | 
 |   section for further instructions. | 
 |  | 
 |   [:ref:`details <recheckworking_bisref>`] | 
 |  | 
 | .. _introbisect_bissbs: | 
 |  | 
 | Segment 3: perform the bisection and validate the result | 
 | -------------------------------------------------------- | 
 |  | 
 | With all the preparations and precaution builds taken care of, you are now ready | 
 | to begin the bisection. This will make you build quite a few kernels -- usually | 
 | about 15 in case you encountered a regression when updating to a newer series | 
 | (say from 6.0.13 to 6.1.5). But do not worry, due to the trimmed build | 
 | configuration created earlier this works a lot faster than many people assume: | 
 | overall on average it will often just take about 10 to 15 minutes to compile | 
 | each kernel on commodity x86 machines. | 
 |  | 
 | .. _bisectstart_bissbs: | 
 |  | 
 | * Start the bisection and tell Git about the versions earlier established as | 
 |   'good' (6.0 in the following example command) and 'bad' (6.1.5):: | 
 |  | 
 |     cd ~/linux/ | 
 |     git bisect start | 
 |     git bisect good v6.0 | 
 |     git bisect bad v6.1.5 | 
 |  | 
 |   [:ref:`details <bisectstart_bisref>`] | 
 |  | 
 | .. _bisectbuild_bissbs: | 
 |  | 
 | * Now use the code Git checked out to build, install, and boot a kernel using | 
 |   the commands introduced earlier:: | 
 |  | 
 |     cp ~/kernel-config-working .config | 
 |     make olddefconfig | 
 |     make -j $(nproc --all) | 
 |     # * Check if the free space suffices holding another kernel: | 
 |     df -h /boot/ /lib/modules/ | 
 |     sudo make modules_install | 
 |     command -v installkernel && sudo make install | 
 |     make -s kernelrelease | tee -a ~/kernels-built | 
 |     reboot | 
 |  | 
 |   If compilation fails for some reason, run ``git bisect skip`` and restart | 
 |   executing the stack of commands from the beginning. | 
 |  | 
 |   In case you skipped the 'test latest codebase' step in the guide, check its | 
 |   description as for why the 'df [...]' and 'make -s kernelrelease [...]' | 
 |   commands are here. | 
 |  | 
 |   Important note: the latter command from this point on will print release | 
 |   identifiers that might look odd or wrong to you -- which they are not, as it's | 
 |   totally normal to see release identifiers like '6.0-rc1-local-gcafec0cacaca0' | 
 |   if you bisect between versions 6.1 and 6.2 for example. | 
 |  | 
 |   [:ref:`details <bisectbuild_bisref>`] | 
 |  | 
 | .. _bisecttest_bissbs: | 
 |  | 
 | * Now check if the feature that regressed works in the kernel you just built. | 
 |  | 
 |   You again might want to start by making sure the kernel you booted is the one | 
 |   you just built:: | 
 |  | 
 |     cd ~/linux/ | 
 |     tail -n 1 ~/kernels-built | 
 |     uname -r | 
 |  | 
 |   Now verify if the feature that regressed works at this kernel bisection point. | 
 |   If it does, run this:: | 
 |  | 
 |     git bisect good | 
 |  | 
 |   If it does not, run this:: | 
 |  | 
 |     git bisect bad | 
 |  | 
 |   Be sure about what you tell Git, as getting this wrong just once will send the | 
 |   rest of the bisection totally off course. | 
 |  | 
 |   While the bisection is ongoing, Git will use the information you provided to | 
 |   find and check out another bisection point for you to test. While doing so, it | 
 |   will print something like 'Bisecting: 675 revisions left to test after this | 
 |   (roughly 10 steps)' to indicate how many further changes it expects to be | 
 |   tested. Now build and install another kernel using the instructions from the | 
 |   previous step; afterwards follow the instructions in this step again. | 
 |  | 
 |   Repeat this again and again until you finish the bisection -- that's the case | 
 |   when Git after tagging a change as 'good' or 'bad' prints something like | 
 |   'cafecaca0c0dacafecaca0c0dacafecaca0c0da is the first bad commit'; right | 
 |   afterwards it will show some details about the culprit including the patch | 
 |   description of the change. The latter might fill your terminal screen, so you | 
 |   might need to scroll up to see the message mentioning the culprit; | 
 |   alternatively, run ``git bisect log > ~/bisection-log``. | 
 |  | 
 |   [:ref:`details <bisecttest_bisref>`] | 
 |  | 
 | .. _bisectlog_bissbs: | 
 |  | 
 | * Store Git's bisection log and the current .config file in a safe place before | 
 |   telling Git to reset the sources to the state before the bisection:: | 
 |  | 
 |     cd ~/linux/ | 
 |     git bisect log > ~/bisection-log | 
 |     cp .config ~/bisection-config-culprit | 
 |     git bisect reset | 
 |  | 
 |   [:ref:`details <bisectlog_bisref>`] | 
 |  | 
 | .. _revert_bissbs: | 
 |  | 
 | * Try reverting the culprit on top of latest mainline to see if this fixes your | 
 |   regression. | 
 |  | 
 |   This is optional, as it might be impossible or hard to realize. The former is | 
 |   the case, if the bisection determined a merge commit as the culprit; the | 
 |   latter happens if other changes depend on the culprit. But if the revert | 
 |   succeeds, it is worth building another kernel, as it validates the result of | 
 |   a bisection, which can easily deroute; it furthermore will let kernel | 
 |   developers know, if they can resolve the regression with a quick revert. | 
 |  | 
 |   Begin by checking out the latest codebase depending on the range you bisected: | 
 |  | 
 |   * Did you face a regression within a stable/longterm series (say between | 
 |     6.0.13 and 6.0.15) that does not happen in mainline? Then check out the | 
 |     latest codebase for the affected series like this:: | 
 |  | 
 |       git fetch stable | 
 |       git switch --discard-changes --detach linux-6.0.y | 
 |  | 
 |   * In all other cases check out latest mainline:: | 
 |  | 
 |       git fetch mainline | 
 |       git switch --discard-changes --detach mainline/master | 
 |  | 
 |     If you bisected a regression within a stable/longterm series that also | 
 |     happens in mainline, there is one more thing to do: look up the mainline | 
 |     commit-id. To do so, use a command like ``git show abcdcafecabcd`` to | 
 |     view the patch description of the culprit. There will be a line near | 
 |     the top which looks like 'commit cafec0cacaca0 upstream.' or | 
 |     'Upstream commit cafec0cacaca0'; use that commit-id in the next command | 
 |     and not the one the bisection blamed. | 
 |  | 
 |   Now try reverting the culprit by specifying its commit id:: | 
 |  | 
 |     git revert --no-edit cafec0cacaca0 | 
 |  | 
 |   If that fails, give up trying and move on to the next step; if it works, | 
 |   adjust the tag to facilitate the identification and prevent accidentally | 
 |   overwriting another kernel:: | 
 |  | 
 |     cp ~/kernel-config-working .config | 
 |     ./scripts/config --set-str CONFIG_LOCALVERSION '-local-cafec0cacaca0-reverted' | 
 |  | 
 |   Build a kernel using the familiar command sequence, just without copying the | 
 |   the base .config over:: | 
 |  | 
 |     make olddefconfig && | 
 |     make -j $(nproc --all) | 
 |     # * Check if the free space suffices holding another kernel: | 
 |     df -h /boot/ /lib/modules/ | 
 |     sudo make modules_install | 
 |     command -v installkernel && sudo make install | 
 |     make -s kernelrelease | tee -a ~/kernels-built | 
 |     reboot | 
 |  | 
 |   Now check one last time if the feature that made you perform a bisection works | 
 |   with that kernel: if everything went well, it should not show the regression. | 
 |  | 
 |   [:ref:`details <revert_bisref>`] | 
 |  | 
 | .. _introclosure_bissbs: | 
 |  | 
 | Complementary tasks: cleanup during and after the bisection | 
 | ----------------------------------------------------------- | 
 |  | 
 | During and after following this guide you might want or need to remove some of | 
 | the kernels you installed: the boot menu otherwise will become confusing or | 
 | space might run out. | 
 |  | 
 | .. _makeroom_bissbs: | 
 |  | 
 | * To remove one of the kernels you installed, look up its 'kernelrelease' | 
 |   identifier. This guide stores them in '~/kernels-built', but the following | 
 |   command will print them as well:: | 
 |  | 
 |     ls -ltr /lib/modules/*-local* | 
 |  | 
 |   You in most situations want to remove the oldest kernels built during the | 
 |   actual bisection (e.g. segment 3 of this guide). The two ones you created | 
 |   beforehand (e.g. to test the latest codebase and the version considered | 
 |   'good') might become handy to verify something later -- thus better keep them | 
 |   around, unless you are really short on storage space. | 
 |  | 
 |   To remove the modules of a kernel with the kernelrelease identifier | 
 |   '*6.0-rc1-local-gcafec0cacaca0*', start by removing the directory holding its | 
 |   modules:: | 
 |  | 
 |     sudo rm -rf /lib/modules/6.0-rc1-local-gcafec0cacaca0 | 
 |  | 
 |   Afterwards try the following command:: | 
 |  | 
 |     sudo kernel-install -v remove 6.0-rc1-local-gcafec0cacaca0 | 
 |  | 
 |   On quite a few distributions this will delete all other kernel files installed | 
 |   while also removing the kernel's entry from the boot menu. But on some | 
 |   distributions kernel-install does not exist or leaves boot-loader entries or | 
 |   kernel image and related files behind; in that case remove them as described | 
 |   in the reference section. | 
 |  | 
 |   [:ref:`details <makeroom_bisref>`] | 
 |  | 
 | .. _finishingtouch_bissbs: | 
 |  | 
 | * Once you have finished the bisection, do not immediately remove anything you | 
 |   set up, as you might need a few things again. What is safe to remove depends | 
 |   on the outcome of the bisection: | 
 |  | 
 |   * Could you initially reproduce the regression with the latest codebase and | 
 |     after the bisection were able to fix the problem by reverting the culprit on | 
 |     top of the latest codebase? Then you want to keep those two kernels around | 
 |     for a while, but safely remove all others with a '-local' in the release | 
 |     identifier. | 
 |  | 
 |   * Did the bisection end on a merge-commit or seems questionable for other | 
 |     reasons? Then you want to keep as many kernels as possible around for a few | 
 |     days: it's pretty likely that you will be asked to recheck something. | 
 |  | 
 |   * In other cases it likely is a good idea to keep the following kernels around | 
 |     for some time: the one built from the latest codebase, the one created from | 
 |     the version considered 'good', and the last three or four you compiled | 
 |     during the actual bisection process. | 
 |  | 
 |   [:ref:`details <finishingtouch_bisref>`] | 
 |  | 
 | .. _introoptional_bissbs: | 
 |  | 
 | Optional: test reverts, patches, or later versions | 
 | -------------------------------------------------- | 
 |  | 
 | While or after reporting a bug, you might want or potentially will be asked to | 
 | test reverts, debug patches, proposed fixes, or other versions. In that case | 
 | follow these instructions. | 
 |  | 
 | * Update your Git clone and check out the latest code. | 
 |  | 
 |   * In case you want to test mainline, fetch its latest changes before checking | 
 |     its code out:: | 
 |  | 
 |       git fetch mainline | 
 |       git switch --discard-changes --detach mainline/master | 
 |  | 
 |   * In case you want to test a stable or longterm kernel, first add the branch | 
 |     holding the series you are interested in (6.2 in the example), unless you | 
 |     already did so earlier:: | 
 |  | 
 |       git remote set-branches --add stable linux-6.2.y | 
 |  | 
 |     Then fetch the latest changes and check out the latest version from the | 
 |     series:: | 
 |  | 
 |       git fetch stable | 
 |       git switch --discard-changes --detach stable/linux-6.2.y | 
 |  | 
 | * Copy your kernel build configuration over:: | 
 |  | 
 |     cp ~/kernel-config-working .config | 
 |  | 
 | * Your next step depends on what you want to do: | 
 |  | 
 |   * In case you just want to test the latest codebase, head to the next step, | 
 |     you are already all set. | 
 |  | 
 |   * In case you want to test if a revert fixes an issue, revert one or multiple | 
 |     changes by specifying their commit ids:: | 
 |  | 
 |       git revert --no-edit cafec0cacaca0 | 
 |  | 
 |     Now give that kernel a special tag to facilitates its identification and | 
 |     prevent accidentally overwriting another kernel:: | 
 |  | 
 |       ./scripts/config --set-str CONFIG_LOCALVERSION '-local-cafec0cacaca0-reverted' | 
 |  | 
 |   * In case you want to test a patch, store the patch in a file like | 
 |     '/tmp/foobars-proposed-fix-v1.patch' and apply it like this:: | 
 |  | 
 |       git apply /tmp/foobars-proposed-fix-v1.patch | 
 |  | 
 |     In case of multiple patches, repeat this step with the others. | 
 |  | 
 |     Now give that kernel a special tag to facilitates its identification and | 
 |     prevent accidentally overwriting another kernel:: | 
 |  | 
 |     ./scripts/config --set-str CONFIG_LOCALVERSION '-local-foobars-fix-v1' | 
 |  | 
 | * Build a kernel using the familiar commands, just without copying the kernel | 
 |   build configuration over, as that has been taken care of already:: | 
 |  | 
 |     make olddefconfig && | 
 |     make -j $(nproc --all) | 
 |     # * Check if the free space suffices holding another kernel: | 
 |     df -h /boot/ /lib/modules/ | 
 |     sudo make modules_install | 
 |     command -v installkernel && sudo make install | 
 |     make -s kernelrelease | tee -a ~/kernels-built | 
 |     reboot | 
 |  | 
 | * Now verify you booted the newly built kernel and check it. | 
 |  | 
 | [:ref:`details <introoptional_bisref>`] | 
 |  | 
 | .. _submit_improvements: | 
 |  | 
 | Conclusion | 
 | ---------- | 
 |  | 
 | You have reached the end of the step-by-step guide. | 
 |  | 
 | Did you run into trouble following any of the above steps not cleared up by the | 
 | reference section below? Did you spot errors? Or do you have ideas how to | 
 | improve the guide? | 
 |  | 
 | If any of that applies, please take a moment and let the maintainer of this | 
 | document know by email (Thorsten Leemhuis <linux@leemhuis.info>), ideally while | 
 | CCing the Linux docs mailing list (linux-doc@vger.kernel.org). Such feedback is | 
 | vital to improve this text further, which is in everybody's interest, as it | 
 | will enable more people to master the task described here -- and hopefully also | 
 | improve similar guides inspired by this one. | 
 |  | 
 |  | 
 | Reference section for the step-by-step guide | 
 | ============================================ | 
 |  | 
 | This section holds additional information for almost all the items in the above | 
 | step-by-step guide. | 
 |  | 
 | Preparations for building your own kernels | 
 | ------------------------------------------ | 
 |  | 
 |   *The steps in this section lay the groundwork for all further tests.* | 
 |   [:ref:`... <introprep_bissbs>`] | 
 |  | 
 | The steps in all later sections of this guide depend on those described here. | 
 |  | 
 | [:ref:`back to step-by-step guide <introprep_bissbs>`]. | 
 |  | 
 | .. _backup_bisref: | 
 |  | 
 | Prepare for emergencies | 
 | ~~~~~~~~~~~~~~~~~~~~~~~ | 
 |  | 
 |   *Create a fresh backup and put system repair and restore tools at hand.* | 
 |   [:ref:`... <backup_bissbs>`] | 
 |  | 
 | Remember, you are dealing with computers, which sometimes do unexpected things | 
 | -- especially if you fiddle with crucial parts like the kernel of an operating | 
 | system. That's what you are about to do in this process. Hence, better prepare | 
 | for something going sideways, even if that should not happen. | 
 |  | 
 | [:ref:`back to step-by-step guide <backup_bissbs>`] | 
 |  | 
 | .. _vanilla_bisref: | 
 |  | 
 | Remove anything related to externally maintained kernel modules | 
 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 
 |  | 
 |   *Remove all software that depends on externally developed kernel drivers or | 
 |   builds them automatically.* [:ref:`...<vanilla_bissbs>`] | 
 |  | 
 | Externally developed kernel modules can easily cause trouble during a bisection. | 
 |  | 
 | But there is a more important reason why this guide contains this step: most | 
 | kernel developers will not care about reports about regressions occurring with | 
 | kernels that utilize such modules. That's because such kernels are not | 
 | considered 'vanilla' anymore, as Documentation/admin-guide/reporting-issues.rst | 
 | explains in more detail. | 
 |  | 
 | [:ref:`back to step-by-step guide <vanilla_bissbs>`] | 
 |  | 
 | .. _secureboot_bisref: | 
 |  | 
 | Deal with techniques like Secure Boot | 
 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 
 |  | 
 |   *On platforms with 'Secure Boot' or similar techniques, prepare everything to | 
 |   ensure the system will permit your self-compiled kernel to boot later.* | 
 |   [:ref:`... <secureboot_bissbs>`] | 
 |  | 
 | Many modern systems allow only certain operating systems to start; that's why | 
 | they reject booting self-compiled kernels by default. | 
 |  | 
 | You ideally deal with this by making your platform trust your self-built kernels | 
 | with the help of a certificate. How to do that is not described | 
 | here, as it requires various steps that would take the text too far away from | 
 | its purpose; 'Documentation/admin-guide/module-signing.rst' and various web | 
 | sides already explain everything needed in more detail. | 
 |  | 
 | Temporarily disabling solutions like Secure Boot is another way to make your own | 
 | Linux boot. On commodity x86 systems it is possible to do this in the BIOS Setup | 
 | utility; the required steps vary a lot between machines and therefore cannot be | 
 | described here. | 
 |  | 
 | On mainstream x86 Linux distributions there is a third and universal option: | 
 | disable all Secure Boot restrictions for your Linux environment. You can | 
 | initiate this process by running ``mokutil --disable-validation``; this will | 
 | tell you to create a one-time password, which is safe to write down. Now | 
 | restart; right after your BIOS performed all self-tests the bootloader Shim will | 
 | show a blue box with a message 'Press any key to perform MOK management'. Hit | 
 | some key before the countdown exposes, which will open a menu. Choose 'Change | 
 | Secure Boot state'. Shim's 'MokManager' will now ask you to enter three | 
 | randomly chosen characters from the one-time password specified earlier. Once | 
 | you provided them, confirm you really want to disable the validation. | 
 | Afterwards, permit MokManager to reboot the machine. | 
 |  | 
 | [:ref:`back to step-by-step guide <secureboot_bissbs>`] | 
 |  | 
 | .. _bootworking_bisref: | 
 |  | 
 | Boot the last kernel that was working | 
 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 
 |  | 
 |   *Boot into the last working kernel and briefly recheck if the feature that | 
 |   regressed really works.* [:ref:`...<bootworking_bissbs>`] | 
 |  | 
 | This will make later steps that cover creating and trimming the configuration do | 
 | the right thing. | 
 |  | 
 | [:ref:`back to step-by-step guide <bootworking_bissbs>`] | 
 |  | 
 | .. _diskspace_bisref: | 
 |  | 
 | Space requirements | 
 | ~~~~~~~~~~~~~~~~~~ | 
 |  | 
 |   *Ensure to have enough free space for building Linux.* | 
 |   [:ref:`... <diskspace_bissbs>`] | 
 |  | 
 | The numbers mentioned are rough estimates with a big extra charge to be on the | 
 | safe side, so often you will need less. | 
 |  | 
 | If you have space constraints, be sure to hay attention to the :ref:`step about | 
 | debug symbols' <debugsymbols_bissbs>` and its :ref:`accompanying reference | 
 | section' <debugsymbols_bisref>`, as disabling then will reduce the consumed disk | 
 | space by quite a few gigabytes. | 
 |  | 
 | [:ref:`back to step-by-step guide <diskspace_bissbs>`] | 
 |  | 
 | .. _rangecheck_bisref: | 
 |  | 
 | Bisection range | 
 | ~~~~~~~~~~~~~~~ | 
 |  | 
 |   *Determine the kernel versions considered 'good' and 'bad' throughout this | 
 |   guide.* [:ref:`...<rangecheck_bissbs>`] | 
 |  | 
 | Establishing the range of commits to be checked is mostly straightforward, | 
 | except when a regression occurred when switching from a release of one stable | 
 | series to a release of a later series (e.g. from 6.0.13 to 6.1.5). In that case | 
 | Git will need some hand holding, as there is no straight line of descent. | 
 |  | 
 | That's because with the release of 6.0 mainline carried on to 6.1 while the | 
 | stable series 6.0.y branched to the side. It's therefore theoretically possible | 
 | that the issue you face with 6.1.5 only worked in 6.0.13, as it was fixed by a | 
 | commit that went into one of the 6.0.y releases, but never hit mainline or the | 
 | 6.1.y series. Thankfully that normally should not happen due to the way the | 
 | stable/longterm maintainers maintain the code. It's thus pretty safe to assume | 
 | 6.0 as a 'good' kernel. That assumption will be tested anyway, as that kernel | 
 | will be built and tested in the segment '2' of this guide; Git would force you | 
 | to do this as well, if you tried bisecting between 6.0.13 and 6.1.15. | 
 |  | 
 | [:ref:`back to step-by-step guide <rangecheck_bissbs>`] | 
 |  | 
 | .. _buildrequires_bisref: | 
 |  | 
 | Install build requirements | 
 | ~~~~~~~~~~~~~~~~~~~~~~~~~~ | 
 |  | 
 |   *Install all software required to build a Linux kernel.* | 
 |   [:ref:`...<buildrequires_bissbs>`] | 
 |  | 
 | The kernel is pretty stand-alone, but besides tools like the compiler you will | 
 | sometimes need a few libraries to build one. How to install everything needed | 
 | depends on your Linux distribution and the configuration of the kernel you are | 
 | about to build. | 
 |  | 
 | Here are a few examples what you typically need on some mainstream | 
 | distributions: | 
 |  | 
 | * Arch Linux and derivatives:: | 
 |  | 
 |     sudo pacman --needed -S bc binutils bison flex gcc git kmod libelf openssl \ | 
 |       pahole perl zlib ncurses qt6-base | 
 |  | 
 | * Debian, Ubuntu, and derivatives:: | 
 |  | 
 |     sudo apt install bc binutils bison dwarves flex gcc git kmod libelf-dev \ | 
 |       libssl-dev make openssl pahole perl-base pkg-config zlib1g-dev \ | 
 |       libncurses-dev qt6-base-dev g++ | 
 |  | 
 | * Fedora and derivatives:: | 
 |  | 
 |     sudo dnf install binutils \ | 
 |       /usr/bin/{bc,bison,flex,gcc,git,openssl,make,perl,pahole,rpmbuild} \ | 
 |       /usr/include/{libelf.h,openssl/pkcs7.h,zlib.h,ncurses.h,qt6/QtGui/QAction} | 
 |  | 
 | * openSUSE and derivatives:: | 
 |  | 
 |     sudo zypper install bc binutils bison dwarves flex gcc git \ | 
 |       kernel-install-tools libelf-devel make modutils openssl openssl-devel \ | 
 |       perl-base zlib-devel rpm-build ncurses-devel qt6-base-devel | 
 |  | 
 | These commands install a few packages that are often, but not always needed. You | 
 | for example might want to skip installing the development headers for ncurses, | 
 | which you will only need in case you later might want to adjust the kernel build | 
 | configuration using make the targets 'menuconfig' or 'nconfig'; likewise omit | 
 | the headers of Qt6 if you do not plan to adjust the .config using 'xconfig'. | 
 |  | 
 | You furthermore might need additional libraries and their development headers | 
 | for tasks not covered in this guide -- for example when building utilities from | 
 | the kernel's tools/ directory. | 
 |  | 
 | [:ref:`back to step-by-step guide <buildrequires_bissbs>`] | 
 |  | 
 | .. _sources_bisref: | 
 |  | 
 | Download the sources using Git | 
 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 
 |  | 
 |   *Retrieve the Linux mainline sources.* | 
 |   [:ref:`...<sources_bissbs>`] | 
 |  | 
 | The step-by-step guide outlines how to download the Linux sources using a full | 
 | Git clone of Linus' mainline repository. There is nothing more to say about | 
 | that -- but there are two alternatives ways to retrieve the sources that might | 
 | work better for you: | 
 |  | 
 | * If you have an unreliable internet connection, consider | 
 |   :ref:`using a 'Git bundle'<sources_bundle_bisref>`. | 
 |  | 
 | * If downloading the complete repository would take too long or requires too | 
 |   much storage space, consider :ref:`using a 'shallow | 
 |   clone'<sources_shallow_bisref>`. | 
 |  | 
 | .. _sources_bundle_bisref: | 
 |  | 
 | Downloading Linux mainline sources using a bundle | 
 | """"""""""""""""""""""""""""""""""""""""""""""""" | 
 |  | 
 | Use the following commands to retrieve the Linux mainline sources using a | 
 | bundle:: | 
 |  | 
 |     wget -c \ | 
 |       https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/clone.bundle | 
 |     git clone --no-checkout clone.bundle ~/linux/ | 
 |     cd ~/linux/ | 
 |     git remote remove origin | 
 |     git remote add mainline \ | 
 |       https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git | 
 |     git fetch mainline | 
 |     git remote add -t master stable \ | 
 |       https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git | 
 |  | 
 | In case the 'wget' command fails, just re-execute it, it will pick up where | 
 | it left off. | 
 |  | 
 | [:ref:`back to step-by-step guide <sources_bissbs>`] | 
 | [:ref:`back to section intro <sources_bisref>`] | 
 |  | 
 | .. _sources_shallow_bisref: | 
 |  | 
 | Downloading Linux mainline sources using a shallow clone | 
 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 
 |  | 
 | First, execute the following command to retrieve the latest mainline codebase:: | 
 |  | 
 |     git clone -o mainline --no-checkout --depth 1 -b master \ | 
 |       https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git ~/linux/ | 
 |     cd ~/linux/ | 
 |     git remote add -t master stable \ | 
 |       https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git | 
 |  | 
 | Now deepen your clone's history to the second predecessor of the mainline | 
 | release of your 'good' version. In case the latter are 6.0 or 6.0.13, 5.19 would | 
 | be the first predecessor and 5.18 the second -- hence deepen the history up to | 
 | that version:: | 
 |  | 
 |     git fetch --shallow-exclude=v5.18 mainline | 
 |  | 
 | Afterwards add the stable Git repository as remote and all required stable | 
 | branches as explained in the step-by-step guide. | 
 |  | 
 | Note, shallow clones have a few peculiar characteristics: | 
 |  | 
 | * For bisections the history needs to be deepened a few mainline versions | 
 |   farther than it seems necessary, as explained above already. That's because | 
 |   Git otherwise will be unable to revert or describe most of the commits within | 
 |   a range (say 6.1..6.2), as they are internally based on earlier kernels | 
 |   releases (like 6.0-rc2 or 5.19-rc3). | 
 |  | 
 | * This document in most places uses ``git fetch`` with ``--shallow-exclude=`` | 
 |   to specify the earliest version you care about (or to be precise: its git | 
 |   tag). You alternatively can use the parameter ``--shallow-since=`` to specify | 
 |   an absolute (say ``'2023-07-15'``) or relative (``'12 months'``) date to | 
 |   define the depth of the history you want to download. When using them while | 
 |   bisecting mainline, ensure to deepen the history to at least 7 months before | 
 |   the release of the mainline release your 'good' kernel is based on. | 
 |  | 
 | * Be warned, when deepening your clone you might encounter an error like | 
 |   'fatal: error in object: unshallow cafecaca0c0dacafecaca0c0dacafecaca0c0da'. | 
 |   In that case run ``git repack -d`` and try again. | 
 |  | 
 | [:ref:`back to step-by-step guide <sources_bissbs>`] | 
 | [:ref:`back to section intro <sources_bisref>`] | 
 |  | 
 | .. _oldconfig_bisref: | 
 |  | 
 | Start defining the build configuration for your kernel | 
 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 
 |  | 
 |   *Start preparing a kernel build configuration (the '.config' file).* | 
 |   [:ref:`... <oldconfig_bissbs>`] | 
 |  | 
 | *Note, this is the first of multiple steps in this guide that create or modify | 
 | build artifacts. The commands used in this guide store them right in the source | 
 | tree to keep things simple. In case you prefer storing the build artifacts | 
 | separately, create a directory like '~/linux-builddir/' and add the parameter | 
 | ``O=~/linux-builddir/`` to all make calls used throughout this guide. You will | 
 | have to point other commands there as well -- among them the ``./scripts/config | 
 | [...]`` commands, which will require ``--file ~/linux-builddir/.config`` to | 
 | locate the right build configuration.* | 
 |  | 
 | Two things can easily go wrong when creating a .config file as advised: | 
 |  | 
 | * The oldconfig target will use a .config file from your build directory, if | 
 |   one is already present there (e.g. '~/linux/.config'). That's totally fine if | 
 |   that's what you intend (see next step), but in all other cases you want to | 
 |   delete it. This for example is important in case you followed this guide | 
 |   further, but due to problems come back here to redo the configuration from | 
 |   scratch. | 
 |  | 
 | * Sometimes olddefconfig is unable to locate the .config file for your running | 
 |   kernel and will use defaults, as briefly outlined in the guide. In that case | 
 |   check if your distribution ships the configuration somewhere and manually put | 
 |   it in the right place (e.g. '~/linux/.config') if it does. On distributions | 
 |   where /proc/config.gz exists this can be achieved using this command:: | 
 |  | 
 |     zcat /proc/config.gz > .config | 
 |  | 
 |   Once you put it there, run ``make olddefconfig`` again to adjust it to the | 
 |   needs of the kernel about to be built. | 
 |  | 
 | Note, the olddefconfig target will set any undefined build options to their | 
 | default value. If you prefer to set such configuration options manually, use | 
 | ``make oldconfig`` instead. Then for each undefined configuration option you | 
 | will be asked how to proceed; in case you are unsure what to answer, simply hit | 
 | 'enter' to apply the default value. Note though that for bisections you normally | 
 | want to go with the defaults, as you otherwise might enable a new feature that | 
 | causes a problem looking like regressions (for example due to security | 
 | restrictions). | 
 |  | 
 | Occasionally odd things happen when trying to use a config file prepared for one | 
 | kernel (say 6.1) on an older mainline release -- especially if it is much older | 
 | (say 5.15). That's one of the reasons why the previous step in the guide told | 
 | you to boot the kernel where everything works. If you manually add a .config | 
 | file you thus want to ensure it's from the working kernel and not from a one | 
 | that shows the regression. | 
 |  | 
 | In case you want to build kernels for another machine, locate its kernel build | 
 | configuration; usually ``ls /boot/config-$(uname -r)`` will print its name. Copy | 
 | that file to the build machine and store it as ~/linux/.config; afterwards run | 
 | ``make olddefconfig`` to adjust it. | 
 |  | 
 | [:ref:`back to step-by-step guide <oldconfig_bissbs>`] | 
 |  | 
 | .. _localmodconfig_bisref: | 
 |  | 
 | Trim the build configuration for your kernel | 
 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 
 |  | 
 |   *Disable any kernel modules apparently superfluous for your setup.* | 
 |   [:ref:`... <localmodconfig_bissbs>`] | 
 |  | 
 | As explained briefly in the step-by-step guide already: with localmodconfig it | 
 | can easily happen that your self-built kernels will lack modules for tasks you | 
 | did not perform at least once before utilizing this make target. That happens | 
 | when a task requires kernel modules which are only autoloaded when you execute | 
 | it for the first time. So when you never performed that task since starting your | 
 | kernel the modules will not have been loaded -- and from localmodonfig's point | 
 | of view look superfluous, which thus disables them to reduce the amount of code | 
 | to be compiled. | 
 |  | 
 | You can try to avoid this by performing typical tasks that often will autoload | 
 | additional kernel modules: start a VM, establish VPN connections, loop-mount a | 
 | CD/DVD ISO, mount network shares (CIFS, NFS, ...), and connect all external | 
 | devices (2FA keys, headsets, webcams, ...) as well as storage devices with file | 
 | systems you otherwise do not utilize (btrfs, ext4, FAT, NTFS, XFS, ...). But it | 
 | is hard to think of everything that might be needed -- even kernel developers | 
 | often forget one thing or another at this point. | 
 |  | 
 | Do not let that risk bother you, especially when compiling a kernel only for | 
 | testing purposes: everything typically crucial will be there. And if you forget | 
 | something important you can turn on a missing feature manually later and quickly | 
 | run the commands again to compile and install a kernel that has everything you | 
 | need. | 
 |  | 
 | But if you plan to build and use self-built kernels regularly, you might want to | 
 | reduce the risk by recording which modules your system loads over the course of | 
 | a few weeks. You can automate this with `modprobed-db | 
 | <https://github.com/graysky2/modprobed-db>`_. Afterwards use ``LSMOD=<path>`` to | 
 | point localmodconfig to the list of modules modprobed-db noticed being used:: | 
 |  | 
 |   yes '' | make LSMOD='${HOME}'/.config/modprobed.db localmodconfig | 
 |  | 
 | That parameter also allows you to build trimmed kernels for another machine in | 
 | case you copied a suitable .config over to use as base (see previous step). Just | 
 | run ``lsmod > lsmod_foo-machine`` on that system and copy the generated file to | 
 | your build's host home directory. Then run these commands instead of the one the | 
 | step-by-step guide mentions:: | 
 |  | 
 |   yes '' | make LSMOD=~/lsmod_foo-machine localmodconfig | 
 |  | 
 | [:ref:`back to step-by-step guide <localmodconfig_bissbs>`] | 
 |  | 
 | .. _tagging_bisref: | 
 |  | 
 | Tag the kernels about to be build | 
 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 
 |  | 
 |   *Ensure all the kernels you will build are clearly identifiable using a | 
 |   special tag and a unique version identifier.* [:ref:`... <tagging_bissbs>`] | 
 |  | 
 | This allows you to differentiate your distribution's kernels from those created | 
 | during this process, as the file or directories for the latter will contain | 
 | '-local' in the name; it also helps picking the right entry in the boot menu and | 
 | not lose track of you kernels, as their version numbers will look slightly | 
 | confusing during the bisection. | 
 |  | 
 | [:ref:`back to step-by-step guide <tagging_bissbs>`] | 
 |  | 
 | .. _debugsymbols_bisref: | 
 |  | 
 | Decide to enable or disable debug symbols | 
 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 
 |  | 
 |   *Decide how to handle debug symbols.* [:ref:`... <debugsymbols_bissbs>`] | 
 |  | 
 | Having debug symbols available can be important when your kernel throws a | 
 | 'panic', 'Oops', 'warning', or 'BUG' later when running, as then you will be | 
 | able to find the exact place where the problem occurred in the code. But | 
 | collecting and embedding the needed debug information takes time and consumes | 
 | quite a bit of space: in late 2022 the build artifacts for a typical x86 kernel | 
 | trimmed with localmodconfig consumed around 5 Gigabyte of space with debug | 
 | symbols, but less than 1 when they were disabled. The resulting kernel image and | 
 | modules are bigger as well, which increases storage requirements for /boot/ and | 
 | load times. | 
 |  | 
 | In case you want a small kernel and are unlikely to decode a stack trace later, | 
 | you thus might want to disable debug symbols to avoid those downsides. If it | 
 | later turns out that you need them, just enable them as shown and rebuild the | 
 | kernel. | 
 |  | 
 | You on the other hand definitely want to enable them for this process, if there | 
 | is a decent chance that you need to decode a stack trace later. The section | 
 | 'Decode failure messages' in Documentation/admin-guide/reporting-issues.rst | 
 | explains this process in more detail. | 
 |  | 
 | [:ref:`back to step-by-step guide <debugsymbols_bissbs>`] | 
 |  | 
 | .. _configmods_bisref: | 
 |  | 
 | Adjust build configuration | 
 | ~~~~~~~~~~~~~~~~~~~~~~~~~~ | 
 |  | 
 |   *Check if you may want or need to adjust some other kernel configuration | 
 |   options:* | 
 |  | 
 | Depending on your needs you at this point might want or have to adjust some | 
 | kernel configuration options. | 
 |  | 
 | .. _configmods_distros_bisref: | 
 |  | 
 | Distro specific adjustments | 
 | """"""""""""""""""""""""""" | 
 |  | 
 |   *Are you running* [:ref:`... <configmods_bissbs>`] | 
 |  | 
 | The following sections help you to avoid build problems that are known to occur | 
 | when following this guide on a few commodity distributions. | 
 |  | 
 | **Debian:** | 
 |  | 
 | * Remove a stale reference to a certificate file that would cause your build to | 
 |   fail:: | 
 |  | 
 |    ./scripts/config --set-str SYSTEM_TRUSTED_KEYS '' | 
 |  | 
 |   Alternatively, download the needed certificate and make that configuration | 
 |   option point to it, as `the Debian handbook explains in more detail | 
 |   <https://debian-handbook.info/browse/stable/sect.kernel-compilation.html>`_ | 
 |   -- or generate your own, as explained in | 
 |   Documentation/admin-guide/module-signing.rst. | 
 |  | 
 | [:ref:`back to step-by-step guide <configmods_bissbs>`] | 
 |  | 
 | .. _configmods_individual_bisref: | 
 |  | 
 | Individual adjustments | 
 | """""""""""""""""""""" | 
 |  | 
 |   *If you want to influence the other aspects of the configuration, do so | 
 |   now.* [:ref:`... <configmods_bissbs>`] | 
 |  | 
 | At this point you can use a command like ``make menuconfig`` or ``make nconfig`` | 
 | to enable or disable certain features using a text-based user interface; to use | 
 | a graphical configuration utility, run ``make xconfig`` instead. Both of them | 
 | require development libraries from toolkits they are rely on (ncurses | 
 | respectively Qt5 or Qt6); an error message will tell you if something required | 
 | is missing. | 
 |  | 
 | [:ref:`back to step-by-step guide <configmods_bissbs>`] | 
 |  | 
 | .. _saveconfig_bisref: | 
 |  | 
 | Put the .config file aside | 
 | ~~~~~~~~~~~~~~~~~~~~~~~~~~ | 
 |  | 
 |   *Reprocess the .config after the latest changes and store it in a safe place.* | 
 |   [:ref:`... <saveconfig_bissbs>`] | 
 |  | 
 | Put the .config you prepared aside, as you want to copy it back to the build | 
 | directory every time during this guide before you start building another | 
 | kernel. That's because going back and forth between different versions can alter | 
 | .config files in odd ways; those occasionally cause side effects that could | 
 | confuse testing or in some cases render the result of your bisection | 
 | meaningless. | 
 |  | 
 | [:ref:`back to step-by-step guide <saveconfig_bissbs>`] | 
 |  | 
 | .. _introlatestcheck_bisref: | 
 |  | 
 | Try to reproduce the problem with the latest codebase | 
 | ----------------------------------------------------- | 
 |  | 
 |   *Verify the regression is not caused by some .config change and check if it | 
 |   still occurs with the latest codebase.* [:ref:`... <introlatestcheck_bissbs>`] | 
 |  | 
 | For some readers it might seem unnecessary to check the latest codebase at this | 
 | point, especially if you did that already with a kernel prepared by your | 
 | distributor or face a regression within a stable/longterm series. But it's | 
 | highly recommended for these reasons: | 
 |  | 
 | * You will run into any problems caused by your setup before you actually begin | 
 |   a bisection. That will make it a lot easier to differentiate between 'this | 
 |   most likely is some problem in my setup' and 'this change needs to be skipped | 
 |   during the bisection, as the kernel sources at that stage contain an unrelated | 
 |   problem that causes building or booting to fail'. | 
 |  | 
 | * These steps will rule out if your problem is caused by some change in the | 
 |   build configuration between the 'working' and the 'broken' kernel. This for | 
 |   example can happen when your distributor enabled an additional security | 
 |   feature in the newer kernel which was disabled or not yet supported by the | 
 |   older kernel. That security feature might get into the way of something you | 
 |   do -- in which case your problem from the perspective of the Linux kernel | 
 |   upstream developers is not a regression, as | 
 |   Documentation/admin-guide/reporting-regressions.rst explains in more detail. | 
 |   You thus would waste your time if you'd try to bisect this. | 
 |  | 
 | * If the cause for your regression was already fixed in the latest mainline | 
 |   codebase, you'd perform the bisection for nothing. This holds true for a | 
 |   regression you encountered with a stable/longterm release as well, as they are | 
 |   often caused by problems in mainline changes that were backported -- in which | 
 |   case the problem will have to be fixed in mainline first. Maybe it already was | 
 |   fixed there and the fix is already in the process of being backported. | 
 |  | 
 | * For regressions within a stable/longterm series it's furthermore crucial to | 
 |   know if the issue is specific to that series or also happens in the mainline | 
 |   kernel, as the report needs to be sent to different people: | 
 |  | 
 |   * Regressions specific to a stable/longterm series are the stable team's | 
 |     responsibility; mainline Linux developers might or might not care. | 
 |  | 
 |   * Regressions also happening in mainline are something the regular Linux | 
 |     developers and maintainers have to handle; the stable team does not care | 
 |     and does not need to be involved in the report, they just should be told | 
 |     to backport the fix once it's ready. | 
 |  | 
 |   Your report might be ignored if you send it to the wrong party -- and even | 
 |   when you get a reply there is a decent chance that developers tell you to | 
 |   evaluate which of the two cases it is before they take a closer look. | 
 |  | 
 | [:ref:`back to step-by-step guide <introlatestcheck_bissbs>`] | 
 |  | 
 | .. _checkoutmaster_bisref: | 
 |  | 
 | Check out the latest Linux codebase | 
 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 
 |  | 
 |   *Check out the latest Linux codebase.* | 
 |   [:ref:`... <checkoutmaster_bissbs>`] | 
 |  | 
 | In case you later want to recheck if an ever newer codebase might fix the | 
 | problem, remember to run that ``git fetch --shallow-exclude [...]`` command | 
 | again mentioned earlier to update your local Git repository. | 
 |  | 
 | [:ref:`back to step-by-step guide <checkoutmaster_bissbs>`] | 
 |  | 
 | .. _build_bisref: | 
 |  | 
 | Build your kernel | 
 | ~~~~~~~~~~~~~~~~~ | 
 |  | 
 |   *Build the image and the modules of your first kernel using the config file | 
 |   you prepared.* [:ref:`... <build_bissbs>`] | 
 |  | 
 | A lot can go wrong at this stage, but the instructions below will help you help | 
 | yourself. Another subsection explains how to directly package your kernel up as | 
 | deb, rpm or tar file. | 
 |  | 
 | Dealing with build errors | 
 | """"""""""""""""""""""""" | 
 |  | 
 | When a build error occurs, it might be caused by some aspect of your machine's | 
 | setup that often can be fixed quickly; other times though the problem lies in | 
 | the code and can only be fixed by a developer. A close examination of the | 
 | failure messages coupled with some research on the internet will often tell you | 
 | which of the two it is. To perform such investigation, restart the build | 
 | process like this:: | 
 |  | 
 |   make V=1 | 
 |  | 
 | The ``V=1`` activates verbose output, which might be needed to see the actual | 
 | error. To make it easier to spot, this command also omits the ``-j $(nproc | 
 | --all)`` used earlier to utilize every CPU core in the system for the job -- but | 
 | this parallelism also results in some clutter when failures occur. | 
 |  | 
 | After a few seconds the build process should run into the error again. Now try | 
 | to find the most crucial line describing the problem. Then search the internet | 
 | for the most important and non-generic section of that line (say 4 to 8 words); | 
 | avoid or remove anything that looks remotely system-specific, like your username | 
 | or local path names like ``/home/username/linux/``. First try your regular | 
 | internet search engine with that string, afterwards search Linux kernel mailing | 
 | lists via `lore.kernel.org/all/ <https://lore.kernel.org/all/>`_. | 
 |  | 
 | This most of the time will find something that will explain what is wrong; quite | 
 | often one of the hits will provide a solution for your problem, too. If you | 
 | do not find anything that matches your problem, try again from a different angle | 
 | by modifying your search terms or using another line from the error messages. | 
 |  | 
 | In the end, most issues you run into have likely been encountered and | 
 | reported by others already. That includes issues where the cause is not your | 
 | system, but lies in the code. If you run into one of those, you might thus find | 
 | a solution (e.g. a patch) or workaround for your issue, too. | 
 |  | 
 | Package your kernel up | 
 | """""""""""""""""""""" | 
 |  | 
 | The step-by-step guide uses the default make targets (e.g. 'bzImage' and | 
 | 'modules' on x86) to build the image and the modules of your kernel, which later | 
 | steps of the guide then install. You instead can also directly build everything | 
 | and directly package it up by using one of the following targets: | 
 |  | 
 | * ``make -j $(nproc --all) bindeb-pkg`` to generate a deb package | 
 |  | 
 | * ``make -j $(nproc --all) binrpm-pkg`` to generate a rpm package | 
 |  | 
 | * ``make -j $(nproc --all) tarbz2-pkg`` to generate a bz2 compressed tarball | 
 |  | 
 | This is just a selection of available make targets for this purpose, see | 
 | ``make help`` for others. You can also use these targets after running | 
 | ``make -j $(nproc --all)``, as they will pick up everything already built. | 
 |  | 
 | If you employ the targets to generate deb or rpm packages, ignore the | 
 | step-by-step guide's instructions on installing and removing your kernel; | 
 | instead install and remove the packages using the package utility for the format | 
 | (e.g. dpkg and rpm) or a package management utility build on top of them (apt, | 
 | aptitude, dnf/yum, zypper, ...). Be aware that the packages generated using | 
 | these two make targets are designed to work on various distributions utilizing | 
 | those formats, they thus will sometimes behave differently than your | 
 | distribution's kernel packages. | 
 |  | 
 | [:ref:`back to step-by-step guide <build_bissbs>`] | 
 |  | 
 | .. _install_bisref: | 
 |  | 
 | Put the kernel in place | 
 | ~~~~~~~~~~~~~~~~~~~~~~~ | 
 |  | 
 |   *Install the kernel you just built.* [:ref:`... <install_bissbs>`] | 
 |  | 
 | What you need to do after executing the command in the step-by-step guide | 
 | depends on the existence and the implementation of ``/sbin/installkernel`` | 
 | executable on your distribution. | 
 |  | 
 | If installkernel is found, the kernel's build system will delegate the actual | 
 | installation of your kernel image to this executable, which then performs some | 
 | or all of these tasks: | 
 |  | 
 | * On almost all Linux distributions installkernel will store your kernel's | 
 |   image in /boot/, usually as '/boot/vmlinuz-<kernelrelease_id>'; often it will | 
 |   put a 'System.map-<kernelrelease_id>' alongside it. | 
 |  | 
 | * On most distributions installkernel will then generate an 'initramfs' | 
 |   (sometimes also called 'initrd'), which usually are stored as | 
 |   '/boot/initramfs-<kernelrelease_id>.img' or | 
 |   '/boot/initrd-<kernelrelease_id>'. Commodity distributions rely on this file | 
 |   for booting, hence ensure to execute the make target 'modules_install' first, | 
 |   as your distribution's initramfs generator otherwise will be unable to find | 
 |   the modules that go into the image. | 
 |  | 
 | * On some distributions installkernel will then add an entry for your kernel | 
 |   to your bootloader's configuration. | 
 |  | 
 | You have to take care of some or all of the tasks yourself, if your | 
 | distribution lacks a installkernel script or does only handle part of them. | 
 | Consult the distribution's documentation for details. If in doubt, install the | 
 | kernel manually:: | 
 |  | 
 |    sudo install -m 0600 $(make -s image_name) /boot/vmlinuz-$(make -s kernelrelease) | 
 |    sudo install -m 0600 System.map /boot/System.map-$(make -s kernelrelease) | 
 |  | 
 | Now generate your initramfs using the tools your distribution provides for this | 
 | process. Afterwards add your kernel to your bootloader configuration and reboot. | 
 |  | 
 | [:ref:`back to step-by-step guide <install_bissbs>`] | 
 |  | 
 | .. _storagespace_bisref: | 
 |  | 
 | Storage requirements per kernel | 
 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 
 |  | 
 |   *Check how much storage space the kernel, its modules, and other related files | 
 |   like the initramfs consume.* [:ref:`... <storagespace_bissbs>`] | 
 |  | 
 | The kernels built during a bisection consume quite a bit of space in /boot/ and | 
 | /lib/modules/, especially if you enabled debug symbols. That makes it easy to | 
 | fill up volumes during a bisection -- and due to that even kernels which used to | 
 | work earlier might fail to boot. To prevent that you will need to know how much | 
 | space each installed kernel typically requires. | 
 |  | 
 | Note, most of the time the pattern '/boot/*$(make -s kernelrelease)*' used in | 
 | the guide will match all files needed to boot your kernel -- but neither the | 
 | path nor the naming scheme are mandatory. On some distributions you thus will | 
 | need to look in different places. | 
 |  | 
 | [:ref:`back to step-by-step guide <storagespace_bissbs>`] | 
 |  | 
 | .. _tainted_bisref: | 
 |  | 
 | Check if your newly built kernel considers itself 'tainted' | 
 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 
 |  | 
 |   *Check if the kernel marked itself as 'tainted'.* | 
 |   [:ref:`... <tainted_bissbs>`] | 
 |  | 
 | Linux marks itself as tainted when something happens that potentially leads to | 
 | follow-up errors that look totally unrelated. That is why developers might | 
 | ignore or react scantly to reports from tainted kernels -- unless of course the | 
 | kernel set the flag right when the reported bug occurred. | 
 |  | 
 | That's why you want check why a kernel is tainted as explained in | 
 | Documentation/admin-guide/tainted-kernels.rst; doing so is also in your own | 
 | interest, as your testing might be flawed otherwise. | 
 |  | 
 | [:ref:`back to step-by-step guide <tainted_bissbs>`] | 
 |  | 
 | .. _recheckbroken_bisref: | 
 |  | 
 | Check the kernel built from a recent mainline codebase | 
 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 
 |  | 
 |   *Verify if your bug occurs with the newly built kernel.* | 
 |   [:ref:`... <recheckbroken_bissbs>`] | 
 |  | 
 | There are a couple of reasons why your bug or regression might not show up with | 
 | the kernel you built from the latest codebase. These are the most frequent: | 
 |  | 
 | * The bug was fixed meanwhile. | 
 |  | 
 | * What you suspected to be a regression was caused by a change in the build | 
 |   configuration the provider of your kernel carried out. | 
 |  | 
 | * Your problem might be a race condition that does not show up with your kernel; | 
 |   the trimmed build configuration, a different setting for debug symbols, the | 
 |   compiler used, and various other things can cause this. | 
 |  | 
 | * In case you encountered the regression with a stable/longterm kernel it might | 
 |   be a problem that is specific to that series; the next step in this guide will | 
 |   check this. | 
 |  | 
 | [:ref:`back to step-by-step guide <recheckbroken_bissbs>`] | 
 |  | 
 | .. _recheckstablebroken_bisref: | 
 |  | 
 | Check the kernel built from the latest stable/longterm codebase | 
 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 
 |  | 
 |   *Are you facing a regression within a stable/longterm release, but failed to | 
 |   reproduce it with the kernel you just built using the latest mainline sources? | 
 |   Then check if the latest codebase for the particular series might already fix | 
 |   the problem.* [:ref:`... <recheckstablebroken_bissbs>`] | 
 |  | 
 | If this kernel does not show the regression either, there most likely is no need | 
 | for a bisection. | 
 |  | 
 | [:ref:`back to step-by-step guide <recheckstablebroken_bissbs>`] | 
 |  | 
 | .. _introworkingcheck_bisref: | 
 |  | 
 | Ensure the 'good' version is really working well | 
 | ------------------------------------------------ | 
 |  | 
 |   *Check if the kernels you build work fine.* | 
 |   [:ref:`... <introworkingcheck_bissbs>`] | 
 |  | 
 | This section will reestablish a known working base. Skipping it might be | 
 | appealing, but is usually a bad idea, as it does something important: | 
 |  | 
 | It will ensure the .config file you prepared earlier actually works as expected. | 
 | That is in your own interest, as trimming the configuration is not foolproof -- | 
 | and you might be building and testing ten or more kernels for nothing before | 
 | starting to suspect something might be wrong with the build configuration. | 
 |  | 
 | That alone is reason enough to spend the time on this, but not the only reason. | 
 |  | 
 | Many readers of this guide normally run kernels that are patched, use add-on | 
 | modules, or both. Those kernels thus are not considered 'vanilla' -- therefore | 
 | it's possible that the thing that regressed might never have worked in vanilla | 
 | builds of the 'good' version in the first place. | 
 |  | 
 | There is a third reason for those that noticed a regression between | 
 | stable/longterm kernels of different series (e.g. 6.0.13..6.1.5): it will | 
 | ensure the kernel version you assumed to be 'good' earlier in the process (e.g. | 
 | 6.0) actually is working. | 
 |  | 
 | [:ref:`back to step-by-step guide <introworkingcheck_bissbs>`] | 
 |  | 
 | .. _recheckworking_bisref: | 
 |  | 
 | Build your own version of the 'good' kernel | 
 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 
 |  | 
 |   *Build your own variant of the working kernel and check if the feature that | 
 |   regressed works as expected with it.* [:ref:`... <recheckworking_bissbs>`] | 
 |  | 
 | In case the feature that broke with newer kernels does not work with your first | 
 | self-built kernel, find and resolve the cause before moving on. There are a | 
 | multitude of reasons why this might happen. Some ideas where to look: | 
 |  | 
 | * Check the taint status and the output of ``dmesg``, maybe something unrelated | 
 |   went wrong. | 
 |  | 
 | * Maybe localmodconfig did something odd and disabled the module required to | 
 |   test the feature? Then you might want to recreate a .config file based on the | 
 |   one from the last working kernel and skip trimming it down; manually disabling | 
 |   some features in the .config might work as well to reduce the build time. | 
 |  | 
 | * Maybe it's not a kernel regression and something that is caused by some fluke, | 
 |   a broken initramfs (also known as initrd), new firmware files, or an updated | 
 |   userland software? | 
 |  | 
 | * Maybe it was a feature added to your distributor's kernel which vanilla Linux | 
 |   at that point never supported? | 
 |  | 
 | Note, if you found and fixed problems with the .config file, you want to use it | 
 | to build another kernel from the latest codebase, as your earlier tests with | 
 | mainline and the latest version from an affected stable/longterm series were | 
 | most likely flawed. | 
 |  | 
 | [:ref:`back to step-by-step guide <recheckworking_bissbs>`] | 
 |  | 
 | Perform a bisection and validate the result | 
 | ------------------------------------------- | 
 |  | 
 |   *With all the preparations and precaution builds taken care of, you are now | 
 |   ready to begin the bisection.* [:ref:`... <introbisect_bissbs>`] | 
 |  | 
 | The steps in this segment perform and validate the bisection. | 
 |  | 
 | [:ref:`back to step-by-step guide <introbisect_bissbs>`]. | 
 |  | 
 | .. _bisectstart_bisref: | 
 |  | 
 | Start the bisection | 
 | ~~~~~~~~~~~~~~~~~~~ | 
 |  | 
 |   *Start the bisection and tell Git about the versions earlier established as | 
 |   'good' and 'bad'.* [:ref:`... <bisectstart_bissbs>`] | 
 |  | 
 | This will start the bisection process; the last of the commands will make Git | 
 | check out a commit round about half-way between the 'good' and the 'bad' changes | 
 | for you to test. | 
 |  | 
 | [:ref:`back to step-by-step guide <bisectstart_bissbs>`] | 
 |  | 
 | .. _bisectbuild_bisref: | 
 |  | 
 | Build a kernel from the bisection point | 
 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 
 |  | 
 |   *Build, install, and boot a kernel from the code Git checked out using the | 
 |   same commands you used earlier.* [:ref:`... <bisectbuild_bissbs>`] | 
 |  | 
 | There are two things worth of note here: | 
 |  | 
 | * Occasionally building the kernel will fail or it might not boot due some | 
 |   problem in the code at the bisection point. In that case run this command:: | 
 |  | 
 |     git bisect skip | 
 |  | 
 |   Git will then check out another commit nearby which with a bit of luck should | 
 |   work better. Afterwards restart executing this step. | 
 |  | 
 | * Those slightly odd looking version identifiers can happen during bisections, | 
 |   because the Linux kernel subsystems prepare their changes for a new mainline | 
 |   release (say 6.2) before its predecessor (e.g. 6.1) is finished. They thus | 
 |   base them on a somewhat earlier point like 6.1-rc1 or even 6.0 -- and then | 
 |   get merged for 6.2 without rebasing nor squashing them once 6.1 is out. This | 
 |   leads to those slightly odd looking version identifiers coming up during | 
 |   bisections. | 
 |  | 
 | [:ref:`back to step-by-step guide <bisectbuild_bissbs>`] | 
 |  | 
 | .. _bisecttest_bisref: | 
 |  | 
 | Bisection checkpoint | 
 | ~~~~~~~~~~~~~~~~~~~~ | 
 |  | 
 |   *Check if the feature that regressed works in the kernel you just built.* | 
 |   [:ref:`... <bisecttest_bissbs>`] | 
 |  | 
 | Ensure what you tell Git is accurate: getting it wrong just one time will bring | 
 | the rest of the bisection totally off course, hence all testing after that point | 
 | will be for nothing. | 
 |  | 
 | [:ref:`back to step-by-step guide <bisecttest_bissbs>`] | 
 |  | 
 | .. _bisectlog_bisref: | 
 |  | 
 | Put the bisection log away | 
 | ~~~~~~~~~~~~~~~~~~~~~~~~~~ | 
 |  | 
 |   *Store Git's bisection log and the current .config file in a safe place.* | 
 |   [:ref:`... <bisectlog_bissbs>`] | 
 |  | 
 | As indicated above: declaring just one kernel wrongly as 'good' or 'bad' will | 
 | render the end result of a bisection useless. In that case you'd normally have | 
 | to restart the bisection from scratch. The log can prevent that, as it might | 
 | allow someone to point out where a bisection likely went sideways -- and then | 
 | instead of testing ten or more kernels you might only have to build a few to | 
 | resolve things. | 
 |  | 
 | The .config file is put aside, as there is a decent chance that developers might | 
 | ask for it after you report the regression. | 
 |  | 
 | [:ref:`back to step-by-step guide <bisectlog_bissbs>`] | 
 |  | 
 | .. _revert_bisref: | 
 |  | 
 | Try reverting the culprit | 
 | ~~~~~~~~~~~~~~~~~~~~~~~~~ | 
 |  | 
 |   *Try reverting the culprit on top of the latest codebase to see if this fixes | 
 |   your regression.* [:ref:`... <revert_bissbs>`] | 
 |  | 
 | This is an optional step, but whenever possible one you should try: there is a | 
 | decent chance that developers will ask you to perform this step when you bring | 
 | the bisection result up. So give it a try, you are in the flow already, building | 
 | one more kernel shouldn't be a big deal at this point. | 
 |  | 
 | The step-by-step guide covers everything relevant already except one slightly | 
 | rare thing: did you bisected a regression that also happened with mainline using | 
 | a stable/longterm series, but Git failed to revert the commit in mainline? Then | 
 | try to revert the culprit in the affected stable/longterm series -- and if that | 
 | succeeds, test that kernel version instead. | 
 |  | 
 | [:ref:`back to step-by-step guide <revert_bissbs>`] | 
 |  | 
 | Cleanup steps during and after following this guide | 
 | --------------------------------------------------- | 
 |  | 
 |   *During and after following this guide you might want or need to remove some | 
 |   of the kernels you installed.* [:ref:`... <introclosure_bissbs>`] | 
 |  | 
 | The steps in this section describe clean-up procedures. | 
 |  | 
 | [:ref:`back to step-by-step guide <introclosure_bissbs>`]. | 
 |  | 
 | .. _makeroom_bisref: | 
 |  | 
 | Cleaning up during the bisection | 
 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 
 |  | 
 |   *To remove one of the kernels you installed, look up its 'kernelrelease' | 
 |   identifier.* [:ref:`... <makeroom_bissbs>`] | 
 |  | 
 | The kernels you install during this process are easy to remove later, as its | 
 | parts are only stored in two places and clearly identifiable. You thus do not | 
 | need to worry to mess up your machine when you install a kernel manually (and | 
 | thus bypass your distribution's packaging system): all parts of your kernels are | 
 | relatively easy to remove later. | 
 |  | 
 | One of the two places is a directory in /lib/modules/, which holds the modules | 
 | for each installed kernel. This directory is named after the kernel's release | 
 | identifier; hence, to remove all modules for one of the kernels you built, | 
 | simply remove its modules directory in /lib/modules/. | 
 |  | 
 | The other place is /boot/, where typically two up to five files will be placed | 
 | during installation of a kernel. All of them usually contain the release name in | 
 | their file name, but how many files and their exact names depend somewhat on | 
 | your distribution's installkernel executable and its initramfs generator. On | 
 | some distributions the ``kernel-install remove...`` command mentioned in the | 
 | step-by-step guide will delete all of these files for you while also removing | 
 | the menu entry for the kernel from your bootloader configuration. On others you | 
 | have to take care of these two tasks yourself. The following command should | 
 | interactively remove the three main files of a kernel with the release name | 
 | '6.0-rc1-local-gcafec0cacaca0':: | 
 |  | 
 |   rm -i /boot/{System.map,vmlinuz,initr}-6.0-rc1-local-gcafec0cacaca0 | 
 |  | 
 | Afterwards check for other files in /boot/ that have | 
 | '6.0-rc1-local-gcafec0cacaca0' in their name and consider deleting them as well. | 
 | Now remove the boot entry for the kernel from your bootloader's configuration; | 
 | the steps to do that vary quite a bit between Linux distributions. | 
 |  | 
 | Note, be careful with wildcards like '*' when deleting files or directories | 
 | for kernels manually: you might accidentally remove files of a 6.0.13 kernel | 
 | when all you want is to remove 6.0 or 6.0.1. | 
 |  | 
 | [:ref:`back to step-by-step guide <makeroom_bissbs>`] | 
 |  | 
 | Cleaning up after the bisection | 
 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 
 |  | 
 | .. _finishingtouch_bisref: | 
 |  | 
 |   *Once you have finished the bisection, do not immediately remove anything | 
 |   you set up, as you might need a few things again.* | 
 |   [:ref:`... <finishingtouch_bissbs>`] | 
 |  | 
 | When you are really short of storage space removing the kernels as described in | 
 | the step-by-step guide might not free as much space as you would like. In that | 
 | case consider running ``rm -rf ~/linux/*`` as well now. This will remove the | 
 | build artifacts and the Linux sources, but will leave the Git repository | 
 | (~/linux/.git/) behind -- a simple ``git reset --hard`` thus will bring the | 
 | sources back. | 
 |  | 
 | Removing the repository as well would likely be unwise at this point: there | 
 | is a decent chance developers will ask you to build another kernel to | 
 | perform additional tests -- like testing a debug patch or a proposed fix. | 
 | Details on how to perform those can be found in the section :ref:`Optional | 
 | tasks: test reverts, patches, or later versions <introoptional_bissbs>`. | 
 |  | 
 | Additional tests are also the reason why you want to keep the | 
 | ~/kernel-config-working file around for a few weeks. | 
 |  | 
 | [:ref:`back to step-by-step guide <finishingtouch_bissbs>`] | 
 |  | 
 | .. _introoptional_bisref: | 
 |  | 
 | Test reverts, patches, or later versions | 
 | ---------------------------------------- | 
 |  | 
 |   *While or after reporting a bug, you might want or potentially will be asked | 
 |   to test reverts, patches, proposed fixes, or other versions.* | 
 |   [:ref:`... <introoptional_bissbs>`] | 
 |  | 
 | All the commands used in this section should be pretty straight forward, so | 
 | there is not much to add except one thing: when setting a kernel tag as | 
 | instructed, ensure it is not much longer than the one used in the example, as | 
 | problems will arise if the kernelrelease identifier exceeds 63 characters. | 
 |  | 
 | [:ref:`back to step-by-step guide <introoptional_bissbs>`]. | 
 |  | 
 |  | 
 | Additional information | 
 | ====================== | 
 |  | 
 | .. _buildhost_bis: | 
 |  | 
 | Build kernels on a different machine | 
 | ------------------------------------ | 
 |  | 
 | To compile kernels on another system, slightly alter the step-by-step guide's | 
 | instructions: | 
 |  | 
 | * Start following the guide on the machine where you want to install and test | 
 |   the kernels later. | 
 |  | 
 | * After executing ':ref:`Boot into the working kernel and briefly use the | 
 |   apparently broken feature <bootworking_bissbs>`', save the list of loaded | 
 |   modules to a file using ``lsmod > ~/test-machine-lsmod``. Then locate the | 
 |   build configuration for the running kernel (see ':ref:`Start defining the | 
 |   build configuration for your kernel <oldconfig_bisref>`' for hints on where | 
 |   to find it) and store it as '~/test-machine-config-working'. Transfer both | 
 |   files to the home directory of your build host. | 
 |  | 
 | * Continue the guide on the build host (e.g. with ':ref:`Ensure to have enough | 
 |   free space for building [...] <diskspace_bissbs>`'). | 
 |  | 
 | * When you reach ':ref:`Start preparing a kernel build configuration[...] | 
 |   <oldconfig_bissbs>`': before running ``make olddefconfig`` for the first time, | 
 |   execute the following command to base your configuration on the one from the | 
 |   test machine's 'working' kernel:: | 
 |  | 
 |     cp ~/test-machine-config-working ~/linux/.config | 
 |  | 
 | * During the next step to ':ref:`disable any apparently superfluous kernel | 
 |   modules <localmodconfig_bissbs>`' use the following command instead:: | 
 |  | 
 |     yes '' | make localmodconfig LSMOD=~/lsmod_foo-machine localmodconfig | 
 |  | 
 | * Continue the guide, but ignore the instructions outlining how to compile, | 
 |   install, and reboot into a kernel every time they come up. Instead build | 
 |   like this:: | 
 |  | 
 |     cp ~/kernel-config-working .config | 
 |     make olddefconfig && | 
 |     make -j $(nproc --all) targz-pkg | 
 |  | 
 |   This will generate a gzipped tar file whose name is printed in the last | 
 |   line shown; for example, a kernel with the kernelrelease identifier | 
 |   '6.0.0-rc1-local-g928a87efa423' built for x86 machines usually will | 
 |   be stored as '~/linux/linux-6.0.0-rc1-local-g928a87efa423-x86.tar.gz'. | 
 |  | 
 |   Copy that file to your test machine's home directory. | 
 |  | 
 | * Switch to the test machine to check if you have enough space to hold another | 
 |   kernel. Then extract the file you transferred:: | 
 |  | 
 |     sudo tar -xvzf ~/linux-6.0.0-rc1-local-g928a87efa423-x86.tar.gz -C / | 
 |  | 
 |   Afterwards :ref:`generate the initramfs and add the kernel to your boot | 
 |   loader's configuration <install_bisref>`; on some distributions the following | 
 |   command will take care of both these tasks:: | 
 |  | 
 |     sudo /sbin/installkernel 6.0.0-rc1-local-g928a87efa423 /boot/vmlinuz-6.0.0-rc1-local-g928a87efa423 | 
 |  | 
 |   Now reboot and ensure you started the intended kernel. | 
 |  | 
 | This approach even works when building for another architecture: just install | 
 | cross-compilers and add the appropriate parameters to every invocation of make | 
 | (e.g. ``make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- [...]``). | 
 |  | 
 | Additional reading material | 
 | --------------------------- | 
 |  | 
 | * The `man page for 'git bisect' <https://git-scm.com/docs/git-bisect>`_ and | 
 |   `fighting regressions with 'git bisect' <https://git-scm.com/docs/git-bisect-lk2009.html>`_ | 
 |   in the Git documentation. | 
 | * `Working with git bisect <https://nathanchance.dev/posts/working-with-git-bisect/>`_ | 
 |   from kernel developer Nathan Chancellor. | 
 | * `Using Git bisect to figure out when brokenness was introduced <http://webchick.net/node/99>`_. | 
 | * `Fully automated bisecting with 'git bisect run' <https://lwn.net/Articles/317154>`_. | 
 |  | 
 | .. | 
 |    end-of-content | 
 | .. | 
 |    This document is maintained by Thorsten Leemhuis <linux@leemhuis.info>. If | 
 |    you spot a typo or small mistake, feel free to let him know directly and | 
 |    he'll fix it. You are free to do the same in a mostly informal way if you | 
 |    want to contribute changes to the text -- but for copyright reasons please CC | 
 |    linux-doc@vger.kernel.org and 'sign-off' your contribution as | 
 |    Documentation/process/submitting-patches.rst explains in the section 'Sign | 
 |    your work - the Developer's Certificate of Origin'. | 
 | .. | 
 |    This text is available under GPL-2.0+ or CC-BY-4.0, as stated at the top | 
 |    of the file. If you want to distribute this text under CC-BY-4.0 only, | 
 |    please use 'The Linux kernel development community' for author attribution | 
 |    and link this as source: | 
 |    https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/plain/Documentation/admin-guide/verify-bugs-and-bisect-regressions.rst | 
 |  | 
 | .. | 
 |    Note: Only the content of this RST file as found in the Linux kernel sources | 
 |    is available under CC-BY-4.0, as versions of this text that were processed | 
 |    (for example by the kernel's build system) might contain content taken from | 
 |    files which use a more restrictive license. |