如何驗證錯誤和二分查找回歸

本文件描述瞭如何檢查某些 Linux 核心問題是否發生在當前受開發者支援的程式碼中——然後解釋如何找到導致該問題的更改(如果這是一個迴歸問題,例如早期版本中沒有發生過)。

本文旨在幫助在商品硬體上執行主流 Linux 發行版的核心的使用者,他們希望向上游 Linux 開發者報告核心錯誤。儘管有此意圖,但這些說明同樣適用於已經熟悉構建自己的核心的使用者:它們有助於避免即使是有經驗的開發者有時也會犯的錯誤。

流程的本質(又名 ‘TL;DR’)

[如果您是 Linux 構建或二分查詢的新手,請忽略此部分,並跳轉到下面的分步指南。它利用與本節相同的命令,同時以簡短的方式描述它們。這些步驟仍然很容易遵循,並且參考部分中附帶的條目提到了許多替代方案、陷阱和其他方面,所有這些都可能在您當前的情況下至關重要。]

**如果您想檢查某個錯誤是否存在於當前受開發者支援的程式碼中**,只需執行*準備工作*和*段落 1*;在執行此操作時,請將您經常使用的最新 Linux 核心視為“正常工作”的核心。在以下示例中,假設為 6.0,這就是為什麼將使用其原始碼來準備 .config 檔案。

**如果您遇到迴歸**,請至少按照步驟操作到*段落 2*的末尾。然後您可以提交初步報告——或者繼續*段落 3*,其中描述瞭如何執行二分查詢,以便生成完整的迴歸報告。在以下示例中,假設 6.0.13 是“正常工作”的核心,而 6.1.5 是第一個“損壞”的核心,這就是為什麼 6.0 將被視為“良好”版本,並用於準備 .config 檔案。

  • **準備工作**:設定一切以構建您自己的核心

    # * 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
    
  • **段落 1**:從最新的主線程式碼庫構建核心。

    這尤其檢查了問題是否已被修復,以及以後需要告訴哪些開發者關於該問題;如果是一個迴歸問題,這將排除 .config 更改作為問題的根源。

    1. 檢出最新的主線程式碼

      cd ~/linux/
      git switch --discard-changes --detach mainline/master
      
    2. 構建、安裝和啟動核心

      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
      
    3. 檢查該核心是否也出現此問題。

  • **段落 2**:確保“良好”核心也是“正常工作”的核心。

    這尤其驗證了精簡的 .config 檔案是否確實執行良好,否則使用它進行二分查詢將是浪費時間

    1. 首先檢出“良好”版本的原始碼

      cd ~/linux/
      git switch --discard-changes --detach v6.0
      
    2. 如前面的*段落 1,b 節*中所述,構建、安裝和啟動核心——只需隨意跳過 ‘du’ 命令,因為您已經有了一個粗略的估計。

    3. 確保在“損壞”核心中迴歸的功能確實與此核心一起工作。

  • **段落 3**:執行並驗證二分查詢。

    1. 檢索“損壞”版本的原始碼

      git remote set-branches --add stable linux-6.1.y
      git fetch stable
      
    2. 初始化二分查詢

      cd ~/linux/
      git bisect start
      git bisect good v6.0
      git bisect bad v6.1.5
      
    3. 如前面的*段落 1,b 節*中所述,構建、安裝和啟動核心。

      如果由於無關的原因導致構建或啟動核心失敗,請執行 git bisect skip。在所有其他結果中,檢查迴歸功能是否與新構建的核心一起工作。如果有效,請透過執行 git bisect good 告訴 Git;如果無效,請改為執行 git bisect bad

      所有三個命令都會使 Git 檢出另一個提交;然後重新執行此步驟(例如,構建、安裝、啟動和測試核心,然後將結果告訴 Git)。一遍又一遍地這樣做,直到 Git 顯示哪個提交破壞了內容。如果您在此過程中磁碟空間不足,請檢視下面的“補充任務:在過程中和之後清理”部分。

    4. 完成二分查詢後,將一些內容收起來

      cd ~/linux/
      git bisect log > ~/bisect-log
      cp .config ~/bisection-config-culprit
      git bisect reset
      
    5. 嘗試驗證二分查詢結果

      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'
      

    這是可選的,因為有些提交無法恢復。但是,如果第二個命令執行順利,請構建、安裝和啟動另一個核心核心;只是這次跳過第一個複製基本 .config 檔案的命令,因為這已經處理完畢。

  • **補充任務**:在過程中和之後清理。

    1. 為了避免在二分查詢期間耗盡磁碟空間,您可能需要刪除一些您先前構建的核心。您很可能希望將您在段落 1 和 2 期間構建的那些核心保留一段時間,但您很可能不再需要二分查詢期間測試的核心(段落 3 c)。您可以使用以下命令按構建順序列出它們

      ls -ltr /lib/modules/*-local*
      

    然後,例如刪除一個將其自身標識為 ‘6.0-rc1-local-gcafec0cacaca0’ 的核心,請使用此命令

    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.
    
    1. 如果您執行了二分查詢併成功驗證了結果,請隨意刪除在實際二分查詢期間構建的所有核心(段落 3 c);您可能希望將您先前和之後構建的核心保留一兩週。

  • **可選任務**:稍後測試除錯補丁或提出的修復程式

    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'
    

    如*段落 1,b 節*中所述,構建、安裝和啟動核心——但這次省略第一個複製構建配置的命令,因為這已處理完畢。

關於如何驗證錯誤和二分查找回歸的分步指南

本指南描述瞭如何設定您自己的 Linux 核心,以用於調查您打算報告的錯誤或迴歸問題。您想遵循這些說明的程度取決於您的問題

執行所有步驟到*段落 1* 的末尾,以**驗證您的核心問題是否出現在 Linux 核心開發者支援的程式碼中**。如果是,那麼您已準備好報告錯誤——除非它沒有發生在早期核心版本中,因為那麼您至少要繼續執行*段落 2*,以**檢查該問題是否符合作為迴歸的條件**,這些迴歸問題會受到優先處理。根據結果,您現在已準備好報告錯誤或提交初步迴歸報告;除了後者,您也可以直接按照*段落 3* 執行**二分查詢**,以便生成開發者有義務採取行動的完整迴歸報告。

每個段落中的步驟都說明了該過程的重要方面,而全面的參考部分則包含了幾乎所有步驟的更多詳細資訊。參考部分有時還會概述替代方法、陷阱,以及可能在特定步驟中發生的問題——以及如何使事情重新啟動。

有關如何報告 Linux 核心問題或迴歸問題的更多詳細資訊,請檢視報告問題,該文件與本文件結合使用。它尤其解釋了為什麼您需要使用最新的“主線”核心(例如 6.0、6.1-rc1 或 6.1-rc6 等版本)驗證錯誤,即使您遇到了“穩定/長期”系列核心(例如 6.0.13)的問題。

對於面臨迴歸問題的使用者,該文件還解釋了為什麼在段落 2 之後傳送初步報告可能是明智的,因為可能已經知道迴歸問題及其原因。有關什麼實際符合迴歸條件的更多詳細資訊,請檢視報告迴歸

如果您在遵循本指南時遇到任何問題或有改進的想法,請告知核心開發者

準備工作:設定一切以構建您自己的核心

以下步驟為所有進一步的任務奠定了基礎。

注意:這些說明假定您在同一臺機器上構建和測試;如果您想在另一個系統上編譯核心,請檢視下面的在不同的機器上構建核心

  • 建立一個新的備份,並將系統修復和還原工具放在手邊,以防發生意外情況。

    [詳細資訊]

  • 刪除所有依賴於外部開發的核心驅動程式或自動構建它們的軟體。這包括但不限於 DKMS、openZFS、VirtualBox 和 Nvidia 的圖形驅動程式(包括 GPLed 核心模組)。

    [詳細資訊]

  • 在具有“安全啟動”或類似解決方案的平臺上,準備好一切,以確保系統允許啟動您自己編譯的核心。在商品 x86 系統上實現此目的的最快和最簡單的方法是在 BIOS 設定實用程式中停用此類技術;或者,透過 mokutil --disable-validation 發起的流程刪除其限制。

    [詳細資訊]

  • 確定在本指南中被認為是“良好”和“不良”的核心版本

    • 您是否遵循本指南來驗證某個錯誤是否存在於主要開發者關心的程式碼中?然後將您目前經常使用的最新核心版本視為“良好”(例如 6.0、6.0.13 或 6.1-rc2)。

    • 您是否面臨迴歸問題,例如切換到較新的核心版本後,某些東西被破壞或執行更糟?在這種情況下,它取決於問題出現的版本範圍

      • 當從穩定/長期版本(例如 6.0.13)更新到較新的主線系列(例如 6.1-rc7 或 6.1)或基於其的穩定/長期版本(例如 6.1.5)時,某些東西發生了迴歸?然後將您的正常工作的核心所基於的主線版本視為“良好”版本(例如 6.0),並將第一個被破壞的版本視為“不良”版本(例如 6.1-rc7、6.1 或 6.1.5)。請注意,此時僅假設 6.0 正常工作;此假設將在段落 2 中進行檢查。

      • 當從一個主線版本(例如 6.0)切換到稍後的一個版本(例如 6.1-rc1)或基於其的穩定/長期版本(例如 6.1.5)時,某些東西發生了迴歸?然後將最後一個正常工作的版本(例如 6.0)視為“良好”,並將第一個被破壞的版本(例如 6.1-rc1 或 6.1.5)視為“不良”。

      • 當在穩定/長期系列中更新時(例如從 6.0.13 更新到 6.0.15)時,某些東西發生了迴歸?然後將這些版本視為“良好”和“不良”(例如 6.0.13 和 6.0.15),因為您需要在該系列中進行二分查詢。

    請注意,不要將“良好”版本與“正常工作”核心混淆;在本指南中,後者將指代最後一個執行良好的核心。

    [詳細資訊]

  • 啟動到“正常工作”核心中,並簡要使用顯然被破壞的功能。

    [詳細資訊]

  • 確保有足夠的可用空間來構建 Linux。您家目錄中的 15 GB 通常應該足夠了。如果您的可用空間較少,請務必注意後面的關於檢索 Linux 原始碼和處理除錯符號的步驟:兩者都解釋了減少空間量的方法,這應該允許您以大約 4 GB 的可用空間來掌握這些任務。

    [詳細資訊]

  • 安裝構建 Linux 核心所需的所有軟體。通常您需要:‘bc’、‘binutils’(‘ld’ 等)、‘bison’、‘flex’、‘gcc’、‘git’、‘openssl’、‘pahole’、‘perl’,以及 ‘libelf’ 和 ‘openssl’ 的開發標頭檔案。參考部分展示瞭如何在各種流行的 Linux 發行版上快速安裝這些軟體。

    [詳細資訊]

  • 檢索主線 Linux 原始碼;然後更改到包含它們的目錄,因為本指南中的所有進一步命令都旨在從那裡執行。

    注意,以下描述瞭如何使用完整的主線克隆來檢索原始碼,截至 2024 年初,該克隆下載大約 2.75 GB。參考部分描述了兩種替代方案:一種下載少於 500 MB,另一種在不可靠的網際網路連線下效果更好。

    執行以下命令以檢索新的主線程式碼庫,同時準備好新增穩定/長期系列的 branch

    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
    

    [詳細資訊]

  • 您先前確定的“良好”或“不良”版本之一是否為穩定或長期版本(例如 6.1.5)?然後下載它所屬的系列的程式碼(在此示例中為 ‘linux-6.1.y’)

    git remote set-branches --add stable linux-6.1.y
    git fetch stable
    
  • 開始準備核心構建配置(‘.config’ 檔案)。

    在這樣做之前,請確保您仍在執行先前的步驟告訴您啟動的“正常工作”核心;如果您不確定,請使用 uname -r 檢查當前的核心版本識別符號。

    之後,檢出先前確定的“良好”版本的原始碼。在以下示例命令中,假設為 6.0;請注意,此版本號和所有後續 Git 命令中的版本號都需要以 ‘v’ 為字首

    git switch --discard-changes --detach v6.0
    

    現在建立一個構建配置檔案

    make olddefconfig
    

    然後,核心構建指令碼將嘗試找到正在執行的核心的構建配置檔案,然後根據您檢出的核心原始碼的需求進行調整。在這樣做時,它將列印一些您需要檢查的行。

    注意以 ‘# using defaults found in’ 開頭的行。它後面應該跟著一個位於 ‘/boot/’ 中的檔案的路徑,該檔案包含您當前正在執行的核心的版本識別符號。如果該行改為繼續類似 ‘arch/x86/configs/x86_64_defconfig’ 的內容,則構建基礎架構未能找到您正在執行的核心的 .config 檔案——在這種情況下,您必須手動將一個檔案放在那裡,如參考部分中所述。

    如果您找不到這樣的行,請查詢包含 ‘# configuration written to .config’ 的行。如果是這種情況,您有一個過時的構建配置檔案。除非您打算使用它,否則請刪除它;之後再次執行 ‘make olddefconfig’,並檢查它現在是否選擇了正確的配置檔案作為基礎。

    [詳細資訊]

  • 停用任何對您的設定來說顯然多餘的核心模組。這是可選的,但對於二分查詢來說尤其明智,因為它極大地加快了構建過程——至少除非在上一步中選擇的 .config 檔案已經針對您和您的硬體需求量身定製,在這種情況下,您應該跳過此步驟。

    為了準備精簡,請連線您偶爾使用的外部硬體(USB 金鑰、令牌,...),快速啟動 VM,並啟動 VPN。如果您自啟動該指南以來重新啟動過,請確保您嘗試使用自系統啟動以來導致問題的的功能。只有這樣才能精簡您的 .config

    yes '' | make localmodconfig
    

    這裡有一個問題,正如本步驟的初始句子中的 ‘顯然’ 和準備說明已經暗示的那樣

    ‘localmodconfig’ 目標很容易停用僅偶爾使用的功能的核心模組——例如,自啟動以來尚未連線的外部外圍裝置模組、尚未使用的虛擬化軟體、VPN 隧道以及其他一些內容。這是因為某些任務依賴於 Linux 僅在您首次執行諸如上述任務之類的任務時才載入的核心模組。

    您不應該對 localmodconfig 的這種缺點感到困擾,但需要記住一點:如果在此指南中構建的核心出現問題,這很可能是原因。您可以使用參考部分中概述的技巧來降低或幾乎消除風險;但是,在僅用於快速測試目的而構建核心時,通常不值得花費太多精力,只要它能夠啟動並允許正確測試導致問題的功能即可。

    [詳細資訊]

  • 確保您將構建的所有核心都使用特殊標籤和唯一版本號清楚地標識

    ./scripts/config --set-str CONFIG_LOCALVERSION '-local'
    ./scripts/config -e CONFIG_LOCALVERSION_AUTO
    

    [詳細資訊]

  • 決定如何處理除錯符號。

    在本文件的上下文中,啟用它們通常是明智的,因為您很有可能需要解碼來自 ‘panic’、‘Oops’、‘warning’ 或 ‘BUG’ 的堆疊跟蹤

    ./scripts/config -d DEBUG_INFO_NONE -e KALLSYMS_ALL -e DEBUG_KERNEL \
      -e DEBUG_INFO -e DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT -e KALLSYMS
    

    但是,如果您的儲存空間非常有限,您可能想要改為停用除錯符號

    ./scripts/config -d DEBUG_INFO -d DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT \
      -d DEBUG_INFO_DWARF4 -d DEBUG_INFO_DWARF5 -e CONFIG_DEBUG_INFO_NONE
    

    [詳細資訊]

  • 檢查您是否可能想要或需要調整其他一些核心配置選項

    • 您是否正在執行 Debian?然後,您需要執行參考部分中解釋的其他調整來避免已知問題。

      [詳細資訊].

    • 如果您想影響配置的其他方面,請現在使用您喜歡的工具執行此操作。請注意,要使用諸如 ‘menuconfig’ 或 ‘nconfig’ 之類的 make 目標,您需要安裝 ncurses 的開發檔案;對於 ‘xconfig’,您同樣需要 Qt5 或 Qt6 的標頭檔案。

      [詳細資訊].

  • 重新處理最新調整後的 .config,並將其儲存在安全的地方

    make olddefconfig
    cp .config ~/kernel-config-working
    

    [詳細資訊]

段落 1:嘗試使用最新的程式碼庫重現該問題

以下步驟驗證該問題是否發生在當前受開發者支援的程式碼中。如果您面臨迴歸問題,它還會檢查該問題是否不是由某些 .config 更改引起的,因為報告該問題將是浪費時間。[詳細資訊]

  • 檢出最新的 Linux 程式碼庫。

    • 您的“良好”和“不良”版本是否來自同一穩定或長期系列?然後檢查 kernel.org 的首頁:如果它列出了來自該系列的版本,但沒有 ‘[EOL]’ 標籤,請檢出該系列的最新版本(在以下示例中為 ‘linux-6.1.y’)

      cd ~/linux/
      git switch --discard-changes --detach stable/linux-6.1.y
      

      如果您的系列未列出或帶有 ‘end of life’ 標籤,則不受支援。在這種情況下,您可能想要檢查後繼系列(例如 linux-6.2.y)或主線(請參閱下一點)是否修復了該錯誤。

    • 在所有其他情況下,執行

      cd ~/linux/
      git switch --discard-changes --detach mainline/master
      

    [詳細資訊]

  • 使用您準備的配置檔案構建第一個核心的映象和模組

    cp ~/kernel-config-working .config
    make olddefconfig
    make -j $(nproc --all)
    

    如果您希望將您的核心打包為 deb、rpm 或 tar 檔案,請參閱參考部分以獲取替代方案,這些替代方案顯然也需要其他步驟才能安裝。

    [詳細資訊]

  • 安裝您新構建的核心。

    在這樣做之前,請考慮檢查是否還有足夠的空間

    df -h /boot/ /lib/modules/
    

    現在假設 /boot/ 中的 150 MB 和 /lib/modules/ 中的 200 MB 足夠了;您的核心實際需要的空間量將在本指南的稍後確定。

    現在安裝核心的模組及其映象,這些映象將與您的 Linux 發行版的核心並行儲存

    sudo make modules_install
    command -v installkernel && sudo make install
    

    理想情況下,第二個命令將處理此時所需的三個步驟:將核心的映象複製到 /boot/,生成 initramfs,並將兩者的條目新增到引導載入程式的配置中。

    遺憾的是,某些發行版(其中包括 Arch Linux 及其衍生產品以及許多不可變的 Linux 發行版)將不執行或僅執行其中一些任務。因此,您需要檢查是否已處理所有這些任務,並手動執行未完成的任務。參考部分提供了有關此內容的更多詳細資訊;您的發行版的文件也可能會有所幫助。

    一旦您弄清楚了此時所需的步驟,請考慮將它們寫下來:如果您將按照段落 2 和 3 中的描述構建更多核心,您將不得不在執行 command -v installkernel [...] 之後再次執行這些步驟。

    [詳細資訊]

  • 如果您計劃進一步遵循本指南,請檢查核心、其模組以及其他相關檔案(如 initramfs)佔用多少儲存空間

    du -ch /boot/*$(make -s kernelrelease)* | tail -n 1
    du -sh /lib/modules/$(make -s kernelrelease)/
    

    寫下或記住這兩個值以供以後使用:它們使您能夠在二分查詢期間防止意外耗盡磁碟空間。

    [詳細資訊]

  • 顯示並存儲您剛剛構建的核心的版本識別符號

    make -s kernelrelease | tee -a ~/kernels-built
    

    暫時記住該識別符號,因為它將幫助您在重新啟動時從啟動選單中選擇正確的核心。

  • 重新啟動到您新構建的核心中。為了確保您確實啟動了您剛剛構建的核心,您可能想要驗證以下命令的輸出是否匹配

    tail -n 1 ~/kernels-built
    uname -r
    
  • 檢查核心是否將自身標記為“被汙染”

    cat /proc/sys/kernel/tainted
    

    如果該命令未返回 ‘0’,請檢查參考部分,因為此原因可能會干擾您的測試。

    [詳細資訊]

  • 驗證您新構建的核心是否出現該錯誤。如果未出現,請檢視參考部分中的說明,以確保您的測試過程中沒有出現任何問題。

    [詳細資訊]

  • 您剛剛構建了一個穩定或長期核心嗎?您是否能夠使用它重現迴歸問題?然後您也應該測試最新的主線程式碼庫,因為結果決定了必須將該錯誤提交給哪些開發者。

    為了準備該測試,請檢出當前主線

    cd ~/linux/
    git switch --discard-changes --detach mainline/master
    

    現在使用檢出的程式碼,使用早期步驟中已更詳細描述的命令來構建和安裝另一個核心

    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
    

    確認您已啟動您打算啟動的核心,並檢查其被汙染狀態

    tail -n 1 ~/kernels-built
    uname -r
    cat /proc/sys/kernel/tainted
    

    現在驗證此核心是否顯示該問題。如果顯示,那麼您需要向主要開發者報告該錯誤;如果不顯示,請將其報告給穩定團隊。有關詳細資訊,請參閱報告問題

    [詳細資訊]

您是否遵循本指南來驗證某個問題是否存在於當前受 Linux 核心開發者支援的程式碼中?那麼您此時就完成了。如果您以後想要刪除您剛剛構建的核心,請檢視補充任務:在遵循本指南期間和之後清理

如果您面臨迴歸問題,請繼續並至少執行下一個段落。

段落 2:檢查您構建的核心是否執行良好

如果出現迴歸問題,您現在想要確保您先前建立的精簡配置檔案按預期工作;否則,使用 .config 檔案進行二分查詢將是浪費時間。[詳細資訊]

  • 構建您自己的“正常工作”核心變體,並檢查迴歸功能是否按預期工作。

    首先檢出先前確定的“良好”版本的原始碼(再次假設此處為 6.0)

    cd ~/linux/
    git switch --discard-changes --detach v6.0
    

    現在使用檢出的程式碼,使用前面的小節中更詳細解釋的命令來配置、構建和安裝另一個核心

    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
    

    當系統啟動時,您可能想要再次驗證您啟動的核心是否是您剛剛構建的核心

    tail -n 1 ~/kernels-built
    uname -r
    

    現在檢查此核心是否按預期工作;如果不是,請查閱參考部分以獲取更多說明。

    [詳情]

第三步:執行二分查詢並驗證結果

在完成了所有的準備和預防措施後,您現在可以開始二分查找了。這將使您構建相當多的核心——通常大約 15 個,如果您在更新到較新系列時遇到迴歸(例如從 6.0.13 到 6.1.5)。但請不要擔心,由於之前建立的精簡構建配置,這比許多人想象的要快得多:總的來說,在普通的 x86 機器上,編譯每個核心通常只需要大約 10 到 15 分鐘。

  • 啟動二分查詢,並告訴 Git 早些時候建立的“良好”版本(在以下示例命令中為 6.0)和“不良”版本(6.1.5)

    cd ~/linux/
    git bisect start
    git bisect good v6.0
    git bisect bad v6.1.5
    

    [詳情]

  • 現在使用 Git 檢出的程式碼來構建、安裝和啟動核心,使用之前介紹的命令

    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
    

    如果編譯由於某種原因失敗,請執行 git bisect skip 並重新從頭開始執行命令堆疊。

    如果您跳過了指南中的“測試最新的程式碼庫”步驟,請檢查其描述,瞭解為什麼這裡有“df [...]”和“make -s kernelrelease [...]”命令。

    重要提示:從現在開始的後一個命令將打印出您可能覺得奇怪或錯誤的釋出識別符號——但它們並非如此,因為如果在 6.1 和 6.2 版本之間進行二分查詢,看到諸如“6.0-rc1-local-gcafec0cacaca0”之類的釋出識別符號是完全正常的。

    [詳情]

  • 現在檢查迴歸的功能是否在您剛剛構建的核心中工作。

    您可能再次想首先確保您啟動的核心是您剛剛構建的核心

    cd ~/linux/
    tail -n 1 ~/kernels-built
    uname -r
    

    現在驗證迴歸的功能是否在這個核心二分點工作。 如果可以,執行此命令

    git bisect good
    

    如果不可以,執行此命令

    git bisect bad
    

    請務必確定您告訴 Git 的內容,因為只要錯一次就會使其餘的二分查詢完全偏離方向。

    在二分查詢正在進行時,Git 將使用您提供的資訊來查詢並檢出另一個二分點供您測試。 在此過程中,它會打印出類似“Bisecting: 675 revisions left to test after this (roughly 10 steps)”的內容,以指示它期望測試的進一步更改的數量。 現在使用上一步中的說明構建並安裝另一個核心; 然後再次按照此步驟中的說明進行操作。

    一遍又一遍地重複此操作,直到完成二分查詢——當 Git 在將更改標記為“良好”或“不良”後打印出類似“cafecaca0c0dacafecaca0c0dacafecaca0c0da is the first bad commit”的內容時,就是這種情況; 緊隨其後的是顯示有關罪魁禍首的一些詳細資訊,包括更改的補丁描述。 後者可能會填滿您的終端螢幕,因此您可能需要向上滾動才能看到提及罪魁禍首的訊息; 或者,執行 git bisect log > ~/bisection-log

    [詳情]

  • 在告訴 Git 將原始碼重置為二分查詢之前的狀態之前,將 Git 的二分查詢日誌和當前的 .config 檔案儲存在安全的地方

    cd ~/linux/
    git bisect log > ~/bisection-log
    cp .config ~/bisection-config-culprit
    git bisect reset
    

    [詳情]

  • 嘗試在最新的主線上還原罪魁禍首,看看這是否修復了您的迴歸。

    這是可選的,因為它可能無法實現或難以實現。 如果二分查詢確定合併提交是罪魁禍首,則會出現前一種情況; 如果其他更改依賴於罪魁禍首,則會出現後一種情況。 但是,如果還原成功,則值得構建另一個核心,因為它驗證了可以輕鬆繞行的二分查詢的結果; 此外,如果核心開發人員可以使用快速還原解決迴歸,它會讓核心開發人員知道。

    首先,根據您二分查詢的範圍檢出最新的程式碼庫

    • 您是否在穩定/長期系列中(例如在 6.0.13 和 6.0.15 之間)遇到迴歸,而該回歸不會在主線中發生? 然後像這樣檢查受影響系列的最新程式碼庫

      git fetch stable
      git switch --discard-changes --detach linux-6.0.y
      
    • 在所有其他情況下,請檢查最新的主線

      git fetch mainline
      git switch --discard-changes --detach mainline/master
      

      如果您二分查找了穩定/長期系列中的迴歸,該回歸也會在主線中發生,那麼還有一件事要做:查詢主線提交 ID。 為此,請使用類似於 git show abcdcafecabcd 的命令來檢視罪魁禍首的補丁描述。 頂部附近會有一行看起來像“commit cafec0cacaca0 upstream.”或“Upstream commit cafec0cacaca0”; 在下一個命令中使用該提交 ID,而不是二分查詢歸咎的提交 ID。

    現在嘗試透過指定其提交 ID 來還原罪魁禍首

    git revert --no-edit cafec0cacaca0
    

    如果失敗,放棄嘗試並繼續下一步; 如果有效,請調整標籤以方便識別並防止意外覆蓋另一個核心

    cp ~/kernel-config-working .config
    ./scripts/config --set-str CONFIG_LOCALVERSION '-local-cafec0cacaca0-reverted'
    

    使用熟悉的命令序列構建核心,只是沒有複製基本 .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
    

    現在最後一次檢查使您執行二分查詢的功能是否使用該核心工作:如果一切順利,則不應顯示迴歸。

    [詳情]

補充任務:二分查詢期間和之後的清理

在遵循本指南期間和之後,您可能想要或需要刪除一些已安裝的核心:否則,啟動選單會變得混亂,或者空間可能會耗盡。

  • 要刪除您安裝的核心之一,請查詢其“kernelrelease”識別符號。 本指南將它們儲存在“~/kernels-built”中,但以下命令也會列印它們

    ls -ltr /lib/modules/*-local*
    

    在大多數情況下,您希望刪除在實際二分查詢期間構建的最舊的核心(例如,本指南的第 3 步)。 您之前建立的兩個核心(例如,測試最新的程式碼庫和被認為是“良好”的版本)可能會方便以後驗證某些內容——因此最好保留它們,除非您的儲存空間確實不足。

    要刪除核心版本識別符號為“6.0-rc1-local-gcafec0cacaca0”的核心的模組,首先刪除包含其模組的目錄

    sudo rm -rf /lib/modules/6.0-rc1-local-gcafec0cacaca0
    

    之後嘗試以下命令

    sudo kernel-install -v remove 6.0-rc1-local-gcafec0cacaca0
    

    在很多發行版上,這將刪除所有其他已安裝的核心檔案,同時從啟動選單中刪除核心的條目。 但是在某些發行版上,kernel-install 不存在或遺留了引導載入程式條目或核心映像以及相關檔案; 在這種情況下,請按照參考部分中的說明刪除它們。

    [詳情]

  • 完成二分查詢後,不要立即刪除您設定的任何內容,因為您可能再次需要一些東西。 什麼可以安全刪除取決於二分查詢的結果

    • 您最初是否可以使用最新的程式碼庫重現迴歸,並且在二分查詢後能夠透過在最新的程式碼庫之上還原罪魁禍首來修復問題? 那麼您希望將這兩個核心保留一段時間,但安全地刪除釋出識別符號中帶有“-local”的所有其他核心。

    • 二分查詢是否在合併提交上結束,或者由於其他原因看起來有問題? 那麼您希望儘可能多地保留核心幾天:您很可能被要求重新檢查某些內容。

    • 在其他情況下,最好將以下核心保留一段時間:從最新程式碼庫構建的核心,從被認為是“良好”的版本建立的核心,以及您在實際二分查詢過程中編譯的最後三個或四個核心。

    [詳情]

可選:測試還原、補丁或更高版本

在報告錯誤時或之後,您可能想要或可能會被要求測試還原、除錯補丁、建議的修復程式或其他版本。 在這種情況下,請按照以下說明進行操作。

  • 更新您的 Git 克隆並檢查最新的程式碼。

    • 如果您想測試主線,請在檢查其程式碼之前獲取其最新更改

      git fetch mainline
      git switch --discard-changes --detach mainline/master
      
    • 如果您想測試穩定或長期核心,請首先新增包含您感興趣的系列的 Branch(例如 6.2),除非您之前已經這樣做了

      git remote set-branches --add stable linux-6.2.y
      

      然後獲取最新更改並從該系列中檢查最新版本

      git fetch stable
      git switch --discard-changes --detach stable/linux-6.2.y
      
  • 複製您的核心構建配置

    cp ~/kernel-config-working .config
    
  • 您的下一步取決於您想要做什麼

    • 如果您只想測試最新的程式碼庫,請轉到下一步,您已經準備好了。

    • 如果您想測試還原是否修復了問題,請透過指定其提交 ID 來還原一個或多個更改

      git revert --no-edit cafec0cacaca0
      

      現在給該核心一個特殊的標籤,以方便其識別並防止意外覆蓋另一個核心

      ./scripts/config --set-str CONFIG_LOCALVERSION '-local-cafec0cacaca0-reverted'
      
    • 如果您想測試補丁,請將補丁儲存在一個檔案中,例如“/tmp/foobars-proposed-fix-v1.patch”,並像這樣應用它

      git apply /tmp/foobars-proposed-fix-v1.patch
      

      如果有多個補丁,請使用其他補丁重複此步驟。

      現在給該核心一個特殊的標籤,以方便其識別並防止意外覆蓋另一個核心

      ./scripts/config --set-str CONFIG_LOCALVERSION '-local-foobars-fix-v1'
      
  • 使用熟悉的命令構建核心,只是沒有複製核心構建配置,因為已經處理好了

    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
    
  • 現在驗證您是否啟動了新構建的核心並對其進行檢查。

[詳情]

結論

您已到達分步指南的結尾。

您在遵循上述任何未在下面參考部分中清除的步驟時遇到麻煩了嗎? 您發現錯誤了嗎? 或者您對如何改進本指南有什麼想法嗎?

如果以上任何一種情況適用,請花點時間透過電子郵件(Thorsten Leemhuis <linux@leemhuis.info>)告知本文件的維護者,最好是抄送 Linux 文件郵件列表(linux-doc@vger.kernel.org)。 此類反饋對於進一步改進本文至關重要,這符合每個人的利益,因為它將使更多的人能夠掌握此處描述的任務——並希望也能改進受此啟發而編寫的類似指南。

分步指南的參考部分

本節包含上述分步指南中幾乎所有專案的其他資訊。

構建您自己的核心的準備工作

本節中的步驟為所有進一步的測試奠定了基礎。 [...]

本指南所有後續部分中的步驟都依賴於此處描述的步驟。

[返回分步指南]。

為緊急情況做好準備

建立新的備份並將系統修復和還原工具放在手邊。 [...]

請記住,您正在處理計算機,它們有時會做一些意想不到的事情——特別是如果您擺弄作業系統的核心等關鍵部件。 這就是您將要在此過程中做的事情。 因此,最好為可能會出現偏差的情況做好準備,即使這種情況不應該發生。

[返回分步指南]

處理諸如安全啟動之類的技術

在具有“安全啟動”或類似技術的平臺上,準備好一切以確保系統允許您稍後啟動您自己編譯的核心。 [...]

許多現代系統只允許某些作業系統啟動; 這就是為什麼它們預設拒絕啟動自己編譯的核心的原因。

您最好透過讓您的平臺信任您自己構建的核心(藉助證書)來處理此問題。 如何做到這一點並沒有在此處描述,因為它需要各種步驟,這些步驟會使文字偏離其目的太遠;“核心模組簽名設施”和各種網頁側面已經更詳細地解釋了所需的一切。

暫時停用安全啟動等解決方案是使您自己的 Linux 啟動的另一種方法。 在普通的 x86 系統上,可以在 BIOS 設定實用程式中執行此操作; 所需的步驟因機器而異,因此無法在此處描述。

在主流 x86 Linux 發行版上,還有第三個通用選項:停用 Linux 環境的所有安全啟動限制。 您可以透過執行 mokutil --disable-validation 來啟動此過程; 這會告訴您建立一個一次性密碼,可以安全地寫下來。 現在重新啟動; 在您的 BIOS 執行完所有自檢後,引導載入程式 Shim 將顯示一個藍色框,其中包含一條訊息“Press any key to perform MOK management”。 在倒計時公開之前按某個鍵,這將開啟一個選單。 選擇“Change Secure Boot state”。 Shim 的“MokManager”現在會要求您輸入之前指定的一次性密碼中的三個隨機選擇的字元。 提供它們後,確認您確實要停用驗證。 之後,允許 MokManager 重新啟動機器。

[返回分步指南]

啟動最後一次工作的核心

啟動到上次工作的核心中,並簡要地重新檢查迴歸的功能是否真的有效。 [...]

這將使稍後涵蓋建立和修剪配置的步驟做正確的事情。

[返回分步指南]

空間要求

確保有足夠的可用空間來構建 Linux。 [...]

提到的數字是粗略的估計值,具有很大的額外收費以確保安全,因此您通常需要更少。

如果您有空間限制,請務必注意 關於除錯符號的步驟 及其 隨附的參考部分,因為停用它們將減少相當多千兆位元組的已用磁碟空間。

[返回分步指南]

二分查詢範圍

確定本指南中被認為是“良好”和“不良”的核心版本。 [...]

確定要檢查的提交範圍大多很簡單,除非在從一個穩定系列的版本切換到更高系列的版本時發生迴歸(例如從 6.0.13 到 6.1.5)。 在這種情況下,Git 將需要一些手動操作,因為沒有直接的下降線。

那是因為隨著 6.0 的釋出,主線延續到 6.1,而穩定系列 6.0.y 向側面分支。 因此,理論上,您在 6.1.5 中面臨的問題可能只在 6.0.13 中有效,因為它已透過進入其中一個 6.0.y 版本的提交修復,但從未命中主線或 6.1.y 系列。 值得慶幸的是,由於穩定/長期維護人員維護程式碼的方式,通常不應該發生這種情況。 因此,假設 6.0 是“良好”的核心非常安全。 無論如何,將對該假設進行測試,因為該核心將在本指南的第“2”步中構建和測試; 如果您嘗試在 6.0.13 和 6.1.15 之間進行二分查詢,Git 也會強制您執行此操作。

[返回分步指南]

安裝構建要求

安裝構建 Linux 核心所需的所有軟體。 [...]

核心非常獨立,但除了編譯器之類的工具外,您有時還需要一些庫來構建核心。 如何安裝所需的一切取決於您的 Linux 發行版以及您將要構建的核心的配置。

以下是一些主流發行版上通常需要的內容的示例

  • Arch Linux 及其衍生產品

    sudo pacman --needed -S bc binutils bison flex gcc git kmod libelf openssl \
      pahole perl zlib ncurses qt6-base
    
  • Debian、Ubuntu 及其衍生產品

    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 及其衍生產品

    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 及其衍生產品

    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
    

這些命令安裝了一些經常但並非總是需要的軟體包。 例如,您可能希望跳過為 ncurses 安裝開發標頭,只有當您以後可能想要使用 make 目標“menuconfig”或“nconfig”調整核心構建配置時才需要它們; 同樣,如果您不打算使用“xconfig”調整 .config,請省略 Qt6 的標頭。

此外,您可能需要額外的庫及其開發標頭來完成本指南中未涵蓋的任務——例如,當從核心的 tools/ 目錄構建實用程式時。

[返回分步指南]

使用 Git 下載原始碼

檢索 Linux 主線原始碼。 [...]

分步指南概述瞭如何使用 Linus 的主線儲存庫的完整 Git 克隆來下載 Linux 原始碼。 關於這一點沒有什麼可說的——但有兩種替代方法來檢索原始碼,這些方法可能更適合您

使用包下載 Linux 主線原始碼

使用以下命令來檢索 Linux 主線原始碼

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

如果“wget”命令失敗,只需重新執行它即可,它將從中斷處繼續。

[返回分步指南] [返回部分介紹]

使用淺克隆下載 Linux 主線原始碼

首先,執行以下命令來檢索最新的主線程式碼庫

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

現在加深克隆的歷史記錄到“良好”版本的 mainline 版本的第二個前身。 如果後者是 6.0 或 6.0.13,則 5.19 將是第一個前身,而 5.18 將是第二個前身——因此加深歷史記錄直到該版本

git fetch --shallow-exclude=v5.18 mainline

之後,按照分步指南中的說明將穩定的 Git 儲存庫新增為遠端,並將所有必需的穩定分支新增為遠端。

請注意,淺克隆有一些特殊的特徵

  • 對於二分查詢,歷史記錄需要比看起來必要的更深入幾個主線版本,如上文已經解釋的那樣。 這是因為 Git 否則將無法還原或描述範圍內的(例如 6.1..6.2)的大部分提交,因為它們在內部基於較早的核心版本(例如 6.0-rc2 或 5.19-rc3)。

  • 本文件在大多數地方使用帶有 --shallow-exclude=git fetch 來指定您關心的最早版本(或者更準確地說:它的 git 標籤)。 您也可以使用引數 --shallow-since= 來指定絕對的(例如 '2023-07-15')或相對的('12 months')日期來定義您要下載的歷史記錄的深度。 在進行主線二分查詢時使用它們,請確保將歷史記錄加深到基於您的“良好”核心的主線版本釋出之前至少 7 個月。

  • 請注意,在加深克隆時,您可能會遇到諸如“fatal: error in object: unshallow cafecaca0c0dacafecaca0c0dacafecaca0c0da”之類的錯誤。 在這種情況下,執行 git repack -d 並重試。

[返回分步指南] [返回部分介紹]

開始定義核心的構建配置

開始準備核心構建配置(“.config”檔案)。 [...]

請注意,這是本指南中建立或修改構建工件的多個步驟中的第一個步驟。 本指南中使用的命令將它們儲存在原始碼樹中以簡化操作。 如果您喜歡單獨儲存構建工件,請建立一個類似於“~/linux-builddir/”的目錄,並將引數``O=~/linux-builddir/``新增到本指南中使用的所有 make 呼叫中。 您還需要將其他命令指向那裡——其中包括``./scripts/config [...]``命令,該命令將需要``--file ~/linux-builddir/.config``來找到正確的構建配置。

按照建議建立 .config 檔案時,很容易出錯兩件事

  • 如果您的構建目錄中已經存在一個 .config 檔案(例如“~/linux/.config”),則 oldconfig 目標將使用該檔案。 如果這正是您打算做的,那完全沒問題(請參閱下一步),但在所有其他情況下,您都想刪除它。 例如,如果您進一步遵循了本指南,但由於問題而返回此處從頭開始重新配置,這很重要。

  • 有時 olddefconfig 無法找到正在執行的核心的 .config 檔案,並將使用預設值,如指南中簡要概述的那樣。 在這種情況下,請檢查您的發行版是否在某處附帶配置,如果附帶,請手動將其放在正確的位置(例如“~/linux/.config”)。 在存在 /proc/config.gz 的發行版上,可以使用以下命令實現此目的

    zcat /proc/config.gz > .config
    

    將其放在那裡後,再次執行 make olddefconfig 以根據即將構建的核心的需求對其進行調整。

請注意,olddefconfig 目標會將任何未定義的構建選項設定為其預設值。 如果您希望手動設定此類配置選項,請改為使用 make oldconfig。 然後,對於每個未定義的配置選項,您都會被問到如何繼續; 如果您不確定要回答什麼,只需按“Enter”鍵以應用預設值。 但請注意,對於二分查詢,您通常希望使用預設值,因為否則您可能會啟用一個新功能,該功能會導致看起來像迴歸的問題(例如由於安全限制)。

有時,嘗試在較舊的主線版本上使用為某個核心(例如 6.1)準備的配置檔案時,會發生奇怪的事情——尤其是在它太舊時(例如 5.15)。 這是本指南中的上一步告訴您啟動一切正常執行的核心的原因之一。 因此,如果您手動新增 .config 檔案,您需要確保它來自正在執行的核心,而不是來自顯示迴歸的核心。

如果您想為另一臺機器構建核心,請找到其核心構建配置; 通常,ls /boot/config-$(uname -r) 將列印其名稱。 將該檔案複製到構建機器並將其儲存為 ~/linux/.config; 之後執行 make olddefconfig 進行調整。

[返回分步指南]

修剪核心的構建配置

停用對於您的設定來說顯然多餘的任何核心模組。 [...]

正如分步指南中已經簡要解釋的那樣:使用 localmodconfig 很容易發生的情況是,您自己構建的核心會缺少用於您在使用此 make 目標之前至少執行過一次的任務的模組。 當任務需要僅在您第一次執行它時才自動載入的核心模組時,就會發生這種情況。 因此,如果您自從啟動核心以來從未執行過該任務,則這些模組將不會被載入——並且從 localmodconfig 的角度來看,它們看起來是多餘的,因此會停用它們以減少要編譯的程式碼量。

您可以透過執行通常會自動載入其他核心模組的典型任務來嘗試避免這種情況:啟動 VM,建立 VPN 連線,迴圈掛載 CD/DVD ISO,掛載網路共享(CIFS、NFS、...),以及連線所有外部裝置(2FA 金鑰、耳機、網路攝像頭、...)以及您不使用的帶有檔案系統的儲存裝置(btrfs、ext4、FAT、NTFS、XFS、...)。 但很難想到可能需要的一切——即使是核心開發人員也經常在此時忘記一件事或另一件事。

不要讓這種風險困擾您,尤其是在僅出於測試目的編譯核心時:通常關鍵的一切都將在那裡。 如果您忘記了重要的東西,您可以稍後手動開啟缺少的功能,然後快速再次執行命令來編譯和安裝具有您所需一切的核心。

但是,如果您計劃定期構建和使用自己構建的核心,您可能希望透過記錄您的系統在幾周內載入的模組來降低風險。 您可以使用 modprobed-db 自動執行此操作。 之後,使用 LSMOD=<path> 將 localmodconfig 指向 modprobed-db 注意到的正在使用的模組列表

yes '' | make LSMOD='${HOME}'/.config/modprobed.db localmodconfig

該引數還允許你為另一臺機器構建精簡的核心,以防你複製了一個合適的 .config 檔案作為基礎(參見上一步)。只需在那臺系統上執行 lsmod > lsmod_foo-machine,並將生成的檔案複製到你的構建主機的家目錄。然後執行這些命令,而不是逐步指南中提到的命令。

yes '' | make LSMOD=~/lsmod_foo-machine localmodconfig

[返回逐步指南]

標記要構建的核心

確保所有要構建的核心都使用特殊標籤和唯一的版本識別符號清晰地標識出來。 [...]

這允許你區分發行版的核心和在此過程中建立的核心,因為後者的檔案或目錄名稱中將包含“-local”;它還有助於在啟動選單中選擇正確的條目,並且不會丟失你的核心的蹤跡,因為在二分查詢過程中,它們的版本號看起來會有些混亂。

[返回逐步指南]

決定啟用或停用除錯符號

決定如何處理除錯符號。 [...]

當你的核心在執行過程中丟擲“panic”、“Oops”、“warning”或“BUG”時,擁有可用的除錯符號可能非常重要,因為這樣你就可以找到程式碼中發生問題的確切位置。但是收集和嵌入所需的除錯資訊需要時間和消耗大量的空間:在 2022 年末,使用 localmodconfig 精簡的典型 x86 核心的構建工件在啟用除錯符號時會消耗大約 5 GB 的空間,但在停用時會消耗不到 1 GB 的空間。生成的核心映象和模組也更大,這增加了 /boot/ 的儲存需求和載入時間。

如果你想要一個小核心,並且不太可能在以後解碼堆疊跟蹤,那麼你可能希望停用除錯符號以避免這些缺點。如果後來發現你需要它們,只需按照所示的方式啟用它們並重建核心。

另一方面,如果很有可能需要在以後解碼堆疊跟蹤,那麼你肯定希望為此過程啟用它們。報告問題 中的“解碼故障訊息”部分更詳細地解釋了此過程。

[返回逐步指南]

調整構建配置

檢查您是否可能想要或需要調整其他一些核心配置選項

根據你的需求,你可能希望或必須在此處調整一些核心配置選項。

發行版特定的調整

你是否正在執行 [...]

以下部分幫助你避免在一些常見的發行版上遵循本指南時已知會發生的構建問題。

Debian

  • 刪除對證書檔案的陳舊引用,否則會導致你的構建失敗

    ./scripts/config --set-str SYSTEM_TRUSTED_KEYS ''
    

    或者,下載所需的證書並使該配置選項指向它,正如 Debian 手冊更詳細地解釋 -- 或者生成你自己的證書,正如 核心模組簽名工具 中所解釋的那樣。

[返回逐步指南]

單獨的調整

如果你想影響配置的其他方面,現在就去做。 [...]

此時,你可以使用類似 make menuconfigmake nconfig 的命令,使用基於文字的使用者介面來啟用或停用某些功能;要使用圖形配置實用程式,請執行 make xconfig 代替。它們都需要來自工具包的開發庫(分別是 ncurses、Qt5 或 Qt6);如果缺少某些必需的東西,將會顯示一條錯誤訊息。

[返回逐步指南]

將 .config 檔案放在一邊

在進行最新更改後,重新處理 .config 檔案並將其儲存在安全的地方。 [...]

將你準備好的 .config 檔案放在一邊,因為你希望在本指南中每次在開始構建另一個核心之前都將其複製回構建目錄。這是因為在不同版本之間來回切換會以奇怪的方式更改 .config 檔案;這些更改有時會導致副作用,這些副作用可能會混淆測試,或者在某些情況下使你的二分查詢結果變得毫無意義。

[返回逐步指南]

嘗試使用最新的程式碼庫重現問題

驗證迴歸是否由某些 .config 更改引起,並檢查它是否仍然發生在最新的程式碼庫中。 [...]

對於某些讀者來說,此時檢查最新的程式碼庫似乎沒有必要,特別是如果你已經使用你的發行商準備的核心進行了檢查,或者遇到了穩定版/長期支援版中的迴歸。但強烈建議這樣做,原因如下:

  • 在你實際開始二分查詢之前,你將遇到由你的設定引起的任何問題。這將更容易區分“這很可能是我設定中的一些問題”和“此更改需要在二分查詢期間跳過,因為該階段的核心原始碼包含一個不相關的問題,導致構建或啟動失敗”。

  • 這些步驟將排除你的問題是否是由“工作”核心和“損壞”核心之間構建配置的某些更改引起的。例如,當你的發行商在新核心中啟用了額外的安全功能時,可能會發生這種情況,而舊核心停用或尚未支援該功能。根據 報告迴歸 中的更詳細解釋,在這種情況下,從 Linux 核心上游開發人員的角度來看,你的問題不是迴歸。因此,如果你嘗試進行二分查詢,那將是在浪費時間。

  • 如果你的迴歸原因已經在最新的主線程式碼庫中修復,那麼你將白費力氣地進行二分查詢。對於你在穩定版/長期支援版中遇到的迴歸也是如此,因為它們通常是由已反向移植的主線更改中的問題引起的 -- 在這種情況下,必須首先在主線中修復該問題。也許它已經在那裡修復,並且該修復程式已經在進行反向移植的過程中。

  • 對於穩定版/長期支援版中的迴歸,更重要的是要知道該問題是否特定於該系列,或者是否也發生在主線核心中,因為需要將報告發送給不同的人員。

    • 特定於穩定版/長期支援版的迴歸是穩定團隊的責任;主線 Linux 開發人員可能關心也可能不關心。

    • 也發生在主線中的迴歸是常規 Linux 開發人員和維護人員必須處理的事情;穩定團隊不關心,也不需要參與報告,他們只需要在修復程式準備好後被告知要反向移植修復程式。

    如果你將報告發送給錯誤的團隊,你的報告可能會被忽略 -- 即使你收到回覆,開發人員也很可能會告訴你先評估是哪種情況,然後再仔細檢視。

[返回逐步指南]

檢查最新的 Linux 程式碼庫

檢查最新的 Linux 程式碼庫。 [...]

如果你以後想重新檢查是否有更新的程式碼庫可以修復該問題,請記住再次執行前面提到的 git fetch --shallow-exclude [...] 命令來更新你的本地 Git 儲存庫。

[返回逐步指南]

構建你的核心

使用你準備的配置檔案構建你的第一個核心的映象和模組。 [...]

在這個階段可能會出現很多問題,但以下說明將幫助你自助。另一個小節解釋瞭如何直接將你的核心打包為 deb、rpm 或 tar 檔案。

處理構建錯誤

當發生構建錯誤時,它可能是由你的機器設定的某些方面引起的,這些方面通常可以快速修復;但在其他情況下,問題在於程式碼中,只能由開發人員修復。仔細檢查失敗訊息並進行一些網際網路搜尋通常會告訴你這是哪種情況。要進行此類調查,請像這樣重新啟動構建過程:

make V=1

V=1 啟用詳細輸出,這可能需要檢視實際錯誤。為了更容易發現錯誤,此命令還省略了之前使用的 -j $(nproc --all) 來利用系統中每個 CPU 核心來完成任務 -- 但這種並行性也會在發生故障時導致一些混亂。

幾秒鐘後,構建過程應該再次遇到錯誤。現在嘗試找到描述問題的最關鍵的一行。然後搜尋網際網路,查詢該行中最重要和非通用的部分(例如 4 到 8 個單詞);避免或刪除任何看起來與系統相關的部分,例如你的使用者名稱或本地路徑名,例如 /home/username/linux/。首先使用該字串在你的常規網際網路搜尋引擎中搜索,然後在 lore.kernel.org/all/ 上搜索 Linux 核心郵件列表。

大多數時候,這會找到一些可以解釋哪裡出了問題的東西;通常,其中一個命中也會提供你的問題的解決方案。如果你沒有找到任何與你的問題匹配的內容,請透過修改你的搜尋詞或使用來自錯誤訊息的另一行,從不同的角度再次嘗試。

最終,你遇到的大多數問題可能已經被其他人遇到和報告了。這包括原因不在於你的系統,而在於程式碼中的問題。如果你遇到其中一個問題,你也可能會找到你問題的解決方案(例如,補丁)或解決方法。

打包你的核心

逐步指南使用預設的 make 目標(例如 x86 上的“bzImage”和“modules”)來構建核心的映象和模組,本指南後面的步驟將安裝這些映象和模組。或者,你可以透過使用以下目標之一來直接構建所有內容並直接打包它:

  • make -j $(nproc --all) bindeb-pkg 生成 deb 包

  • make -j $(nproc --all) binrpm-pkg 生成 rpm 包

  • make -j $(nproc --all) tarbz2-pkg 生成 bz2 壓縮的 tarball

這只是可用於此目的的可用 make 目標的選擇,請參閱 make help 瞭解其他目標。你也可以在執行 make -j $(nproc --all) 後使用這些目標,因為它們將拾取所有已構建的內容。

如果你使用這些目標來生成 deb 或 rpm 包,請忽略逐步指南中有關安裝和刪除你的核心的說明;而是使用該格式的包實用程式(例如 dpkg 和 rpm)或構建在其之上的包管理實用程式(apt、aptitude、dnf/yum、zypper 等)來安裝和刪除這些包。請注意,使用這兩個 make 目標生成的包旨在適用於使用這些格式的各種發行版,因此它們有時會以與你的發行版的核心包不同的方式執行。

[返回逐步指南]

將核心放到位

安裝你剛剛構建的核心。 [...]

在執行逐步指南中的命令後,你需要執行的操作取決於你的發行版上是否存在 /sbin/installkernel 可執行檔案及其實現。

如果找到 installkernel,核心的構建系統會將你的核心映象的實際安裝委託給此可執行檔案,然後該可執行檔案會執行以下部分或全部任務:

  • 在幾乎所有 Linux 發行版上,installkernel 會將你的核心映象儲存在 /boot/ 中,通常為“/boot/vmlinuz-<kernelrelease_id>”;通常它會在旁邊放置一個“System.map-<kernelrelease_id>”。

  • 在大多數發行版上,installkernel 隨後會生成一個“initramfs”(有時也稱為“initrd”),通常儲存為“/boot/initramfs-<kernelrelease_id>.img”或“/boot/initrd-<kernelrelease_id>”。通用發行版依賴此檔案進行啟動,因此請確保首先執行 make 目標“modules_install”,否則你的發行版的 initramfs 生成器將無法找到進入映象的模組。

  • 在某些發行版上,installkernel 隨後會將你的核心的條目新增到你的引導載入程式的配置中。

如果你的發行版缺少 installkernel 指令碼或僅處理其中的一部分,你必須自己處理部分或全部任務。有關詳細資訊,請查閱發行版的文件。如有疑問,請手動安裝核心

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)

現在使用你的發行版為此過程提供的工具生成你的 initramfs。然後將你的核心新增到你的引導載入程式配置並重新啟動。

[返回逐步指南]

每個核心的儲存需求

檢查核心、其模組和其他相關檔案(如 initramfs)消耗多少儲存空間。 [...]

在二分查詢期間構建的核心在 /boot/ 和 /lib/modules/ 中消耗了相當多的空間,特別是如果你啟用了除錯符號。這使得在二分查詢期間很容易填滿卷 -- 因此,即使是以前可以工作的核心也可能無法啟動。為防止這種情況,你需要知道每個已安裝的核心通常需要多少空間。

請注意,大多數時候,指南中使用的模式“/boot/$(make -s kernelrelease)”將匹配啟動你的核心所需的所有檔案 -- 但路徑和命名方案都不是強制性的。因此,在某些發行版上,你需要檢視不同的位置。

[返回逐步指南]

檢查你新構建的核心是否認為自己是“已汙染”的

檢查核心是否將自己標記為“已汙染”。 [...]

當發生可能導致看起來完全無關的後續錯誤的事情時,Linux 會將自己標記為已汙染。這就是為什麼開發人員可能會忽略或敷衍地回應來自已汙染核心的報告 -- 除非當然核心在報告的 bug 發生時立即設定了該標誌。

這就是你想要檢查核心為何被汙染的原因,正如 已汙染的核心 中所解釋的那樣;這樣做也符合你自己的利益,否則你的測試可能存在缺陷。

[返回逐步指南]

檢查從最近的主線程式碼庫構建的核心

驗證你的 bug 是否發生在你新構建的核心中。 [...]

你的 bug 或迴歸可能不會出現在你從最新程式碼庫構建的核心中的原因有很多。以下是最常見的原因:

  • 該 bug 已被修復。

  • 你懷疑是迴歸的原因是由你的核心提供程式進行的構建配置更改引起的。

  • 你的問題可能是一個競爭條件,不會出現在你的核心中;精簡的構建配置、除錯符號的不同設定、使用的編譯器以及各種其他因素都可能導致這種情況。

  • 如果你在使用穩定版/長期支援版核心時遇到迴歸,那麼它可能是特定於該系列的問題;本指南的下一步將對此進行檢查。

[返回逐步指南]

檢查從最新的穩定版/長期支援版程式碼庫構建的核心

你是否在穩定版/長期支援版中遇到迴歸,但未能使用你剛剛使用最新的主線原始碼構建的核心重現它?然後檢查特定系列的最新程式碼庫是否已修復該問題。 [...]

如果此核心也沒有顯示迴歸,那麼很可能不需要進行二分查詢。

[返回逐步指南]

確保“良好”版本真正執行良好

檢查你構建的核心是否執行良好。 [...]

本節將重新建立一個已知的工作基礎。跳過它可能很吸引人,但通常是一個壞主意,因為它會做一些重要的事情:

它將確保你之前準備的 .config 檔案實際上可以按預期工作。這符合你自己的利益,因為精簡配置並非萬無一失 -- 並且你可能會構建和測試十個或更多的核心,然後才開始懷疑構建配置可能存在問題。

僅憑這一點就足以花費時間來完成此操作,但這不是唯一的原因。

本指南的許多讀者通常執行已打補丁、使用附加模組或兩者兼而有之的核心。因此,這些核心不被認為是“原始”核心 -- 因此,可能迴歸的內容可能從未在“良好”版本的原始版本中工作過。

對於那些注意到不同系列的穩定版/長期支援版核心之間存在迴歸(例如,6.0.13..6.1.5)的人來說,還有第三個原因:它將確保你在該過程中早些時候假設為“良好”的核心版本(例如,6.0)實際上可以正常工作。

[返回逐步指南]

構建你自己的“良好”核心版本

構建你自己的工作核心變體,並檢查迴歸的功能是否按預期工作。 [...]

如果使用較新核心損壞的功能不適用於你的第一個自行構建的核心,請在繼續之前找到並解決該原因。發生這種情況的原因有很多。以下是一些查詢位置:

  • 檢查汙染狀態和 dmesg 的輸出,可能發生了無關的事情。

  • 也許 localmodconfig 做了奇怪的事情並停用了測試該功能所需的模組?然後你可能想要基於上次工作核心中的檔案重新建立一個 .config 檔案,並跳過精簡它;手動停用 .config 中的某些功能也可以減少構建時間。

  • 也許這不是核心迴歸,而是由某種僥倖、損壞的 initramfs(也稱為 initrd)、新韌體檔案或更新的使用者空間軟體引起的?

  • 也許它是新增到你的發行版的核心的功能,而 vanilla Linux 在那時從未支援過?

請注意,如果你發現並修復了 .config 檔案的問題,則需要使用它從最新的程式碼庫構建另一個核心,因為你之前使用受影響的穩定版/長期支援版的 mainline 和最新版本的測試很可能存在缺陷。

[返回逐步指南]

執行二分查詢並驗證結果

完成所有準備和預防構建後,你現在可以開始二分查找了。 [...]

本段中的步驟執行並驗證二分查詢。

[返回逐步指南].

開始二分查詢

開始二分查詢並告訴 Git 早期建立的“良好”和“不良”版本。 [...]

這將啟動二分查詢過程;最後一個命令將使 Git 檢出一個大致位於“良好”和“不良”更改之間的提交,供你測試。

[返回逐步指南]

從二分查詢點構建核心

使用與之前相同的命令,從 Git 檢出的程式碼構建、安裝和啟動核心。 [...]

這裡有兩件事值得注意:

  • 有時構建核心會失敗,或者由於二分查詢點的程式碼中存在某些問題而可能無法啟動。在這種情況下,執行此命令:

    git bisect skip
    

    然後,Git 將檢出附近的另一個提交,希望它能更好地工作。之後,重新開始執行此步驟。

  • 那些看起來有點奇怪的版本識別符號可能在二分查詢期間發生,因為 Linux 核心子系統會在其前身(例如 6.1)完成之前,為新的主線版本(例如 6.2)準備其更改。因此,他們將它們基於稍早的一點,例如 6.1-rc1 甚至 6.0 -- 然後在 6.1 釋出後合併為 6.2,而不會重新定基或壓縮它們。這導致那些看起來有點奇怪的版本識別符號在二分查詢期間出現。

[返回逐步指南]

二分查詢檢查點

檢查迴歸的功能在你剛剛構建的核心中是否有效。 [...]

確保你告訴 Git 的內容準確:如果一次弄錯,將使二分查詢的其餘部分完全偏離方向,因此之後的全部測試都將毫無意義。

[返回逐步指南]

將二分查詢日誌收起來

將 Git 的二分查詢日誌和當前的 .config 檔案儲存在安全的地方。 [...]

如上所述:將一個核心錯誤地宣告為“良好”或“不良”將使二分查詢的最終結果毫無用處。在這種情況下,你通常必須從頭開始重新啟動二分查詢。日誌可以防止這種情況,因為它可能允許某人指出二分查詢可能出錯的地方 -- 然後,你可能只需要構建幾個核心來解決問題,而不是測試十個或更多的核心。

將 .config 檔案放在一邊,因為很有可能開發人員會在你報告迴歸後要求它。

[返回逐步指南]

嘗試還原罪魁禍首

嘗試在最新程式碼庫之上還原罪魁禍首,看看這是否可以修復你的迴歸。 [...]

這是一個可選步驟,但只要有可能,你應該嘗試一下:很有可能開發人員會在你提出二分查詢結果時要求你執行此步驟。所以嘗試一下,你已經進入狀態,再構建一個核心在這個時候應該不是什麼大問題。

逐步指南涵蓋了所有相關內容,但有一件稍微罕見的事情:你是否使用穩定版/長期支援版二分查找了也發生在 mainline 中的迴歸,但 Git 未能在 mainline 中還原提交?然後嘗試在受影響的穩定版/長期支援版中還原罪魁禍首 -- 如果成功,則測試該核心版本。

[返回逐步指南]

遵循本指南期間和之後的清理步驟

在本指南期間和之後,你可能希望或需要刪除你安裝的某些核心。 [...]

本節中的步驟描述了清理過程。

[返回逐步指南].

在二分查詢期間進行清理

要刪除你安裝的核心之一,請查詢其“kernelrelease”識別符號。 [...]

在此過程中安裝的核心以後很容易刪除,因為它的各個部分僅儲存在兩個位置並且可以清楚地識別。因此,當你手動安裝核心時(因此繞過你的發行版的打包系統),你無需擔心會搞砸你的機器:你的核心的所有部分以後都相對容易刪除。

兩個位置之一是 /lib/modules/ 目錄中的一個目錄,該目錄儲存每個已安裝核心的模組。此目錄以核心的釋出識別符號命名;因此,要刪除您構建的核心的所有模組,只需刪除 /lib/modules/ 中相應的模組目錄即可。

另一個位置是 /boot/,通常在安裝核心期間會放置兩到五個檔案。所有這些檔案通常在其檔名中包含釋出名稱,但檔案的數量及其確切名稱在某種程度上取決於您的發行版的 installkernel 可執行檔案及其 initramfs 生成器。在某些發行版上,分步指南中提到的 kernel-install remove... 命令將為您刪除所有這些檔案,同時還會從引導載入程式配置中刪除核心的選單項。在其他發行版上,您必須自己處理這兩個任務。以下命令應以互動方式刪除釋出名稱為“6.0-rc1-local-gcafec0cacaca0”的核心的三個主要檔案

rm -i /boot/{System.map,vmlinuz,initr}-6.0-rc1-local-gcafec0cacaca0

之後,檢查 /boot/ 中是否有其他名稱中包含“6.0-rc1-local-gcafec0cacaca0”的檔案,並考慮將其刪除。現在從引導載入程式的配置中刪除核心的引導條目;執行此操作的步驟在 Linux 發行版之間差異很大。

請注意,手動刪除核心的檔案或目錄時,請小心使用“*”等萬用字元:您可能會意外刪除 6.0.13 核心的檔案,而您只想刪除 6.0 或 6.0.1。

[返回分步指南]

二分法之後的清理

完成二分法後,請勿立即刪除您設定的任何內容,因為您可能需要再次使用一些東西。 [...]

如果您真的缺少儲存空間,那麼按照分步指南中所述刪除核心可能無法釋放您想要的那麼多空間。在這種情況下,請考慮立即執行 rm -rf ~/linux/*。這將刪除構建產物和 Linux 原始碼,但會保留 Git 倉庫 (~/linux/.git/) -- 因此,一個簡單的 git reset --hard 將恢復原始碼。

此時刪除倉庫可能不明智:很有可能開發人員會要求您構建另一個核心來執行額外的測試 -- 比如測試除錯補丁或提議的修復。有關如何執行這些操作的詳細資訊,請參見 可選任務:測試還原、補丁或更高版本 部分。

額外的測試也是您希望將 ~/kernel-config-working 檔案保留幾周的原因。

[返回分步指南]

測試還原、補丁或更高版本

在報告錯誤時或之後,您可能想要或可能會被要求測試還原、補丁、提議的修復或其他版本。 [...]

本節中使用的所有命令都應該非常簡單,因此除了以下內容外,沒有什麼可補充的:在按照說明設定核心標籤時,請確保它不要比示例中使用的標籤長太多,因為如果 kernelrelease 識別符號超過 63 個字元,則會出現問題。

[返回分步指南].

附加資訊

在不同的機器上構建核心

要在另一個系統上編譯核心,請稍微更改分步指南的說明

  • 在您想要稍後安裝和測試核心的機器上開始按照指南進行操作。

  • 在執行“啟動到工作的核心並簡要使用明顯損壞的功能”之後,使用 lsmod > ~/test-machine-lsmod 將載入的模組列表儲存到檔案中。然後找到執行核心的構建配置(有關在哪裡找到它的提示,請參見“開始定義核心的構建配置”),並將其儲存為“~/test-machine-config-working”。將這兩個檔案都傳輸到您的構建主機的 home 目錄。

  • 在構建主機上繼續該指南(例如,使用“確保有足夠的可用空間來構建 [...]”)。

  • 當您到達“開始準備核心構建配置[...]”時:在第一次執行 make olddefconfig 之前,執行以下命令以基於測試機器“working”核心中的配置來配置您的配置

    cp ~/test-machine-config-working ~/linux/.config
    
  • 在下一步“停用任何明顯多餘的核心模組”中,請改用以下命令

    yes '' | make localmodconfig LSMOD=~/lsmod_foo-machine localmodconfig
    
  • 繼續該指南,但忽略每次出現時概述如何編譯、安裝和重新啟動到核心中的說明。而是像這樣構建

    cp ~/kernel-config-working .config
    make olddefconfig &&
    make -j $(nproc --all) targz-pkg
    

    這將生成一個 gzipped tar 檔案,其名稱顯示在顯示的最後一行中;例如,kernelrelease 識別符號為“6.0.0-rc1-local-g928a87efa423”的為 x86 機器構建的核心通常將儲存為“~/linux/linux-6.0.0-rc1-local-g928a87efa423-x86.tar.gz”。

    將該檔案複製到測試機器的 home 目錄。

  • 切換到測試機器以檢查您是否有足夠的空間來容納另一個核心。然後提取您傳輸的檔案

    sudo tar -xvzf ~/linux-6.0.0-rc1-local-g928a87efa423-x86.tar.gz -C /
    

    之後,生成 initramfs 並將核心新增到引導載入程式的配置中;在某些發行版上,以下命令將處理這兩個任務

    sudo /sbin/installkernel 6.0.0-rc1-local-g928a87efa423 /boot/vmlinuz-6.0.0-rc1-local-g928a87efa423
    

    現在重新啟動並確保您啟動了預期的核心。

即使為另一種架構構建,此方法也有效:只需安裝交叉編譯器並將適當的引數新增到每次呼叫 make 中(例如,make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- [...])。

其他閱讀材料