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