內核

出自 Arch Linux 中文维基

根據維基百科:

Linux 內核是一種開源的類 Unix 作業系統宏內核。

Arch Linux 基於 Linux 內核。除了最新的穩定內核之外,還有許多各種各樣的 Linux 內核可供選擇。本文列出了倉庫中提供的一些選擇,並對它們簡要介紹。本文還介紹了一些可用的內核補丁。文章的最後總覽了自行編譯內核的方法,並包含各種方法的連結。

內核包安裝/usr/lib/modules/ 路徑下,並隨後用於生成儲存在 /boot/ 中的可執行鏡像。[1] 為了能夠啟動到內核,需要正確配置啟動加載器

官方支持的內核[編輯 | 編輯原始碼]

官方支持的內核可以得到來自論壇錯誤報吿的社區支持。

  • Stable — 原版的 Linux 內核和模塊,採用了一些補丁。
https://www.kernel.org/ || linux
  • Hardened — 注重安全的 Linux 內核,採用一系列加固補丁以緩解內核和用户空間漏洞。和 linux 相比,它啟用了上游更多的內核加固功能。
https://github.com/anthraxx/linux-hardened || linux-hardened
  • Longterm — 受長期支持(Long Term Support)的 Linux 內核和模塊。這提供了最新的長期支持(LTS)內核,並且被認為比默認內核「更穩定」。但是,它有時會使用較舊的驅動程序,這些驅動程序可能與較新的硬件不兼容,並且可能缺少較新的內核版本的某些功能。LTS內核沒有固定的發佈周期,但通常對於桌面版每3年更新一次,對於伺服器每5年更新一次。
https://www.kernel.org/ || linux-lts
  • Realtime kernel — 由Ingo Molnar領導的一小羣核心開發人員維護。這個補丁允許幾乎所有的內核被搶佔,除了少數非常小的代碼區域(「原始自旋鎖關鍵區域」)。這是通過將大多數內核自旋鎖替換為支持優先級繼承的互斥鎖,以及將所有中斷和軟件中斷移動到內核線程來實現的
https://wiki.linuxfoundation.org/realtime/start || linux-rt, linux-rt-lts
  • Zen Kernel — 一些內核黑客合作的結果,提供了最適合日常使用的內核。可在 https://liquorix.net 上找到一些細節(他們為 Debian 提供基於 Zen 的內核二進制文件)。
https://github.com/zen-kernel/zen-kernel || linux-zen

編譯[編輯 | 編輯原始碼]

可通過以下方式編譯內核:

Arch 構建系統
充分利用已有的高質量的 linux PKGBUILD 且受益於包管理
傳統方式
需要手動下載內核原始碼包,然後在自己的主目錄裡以普通用户的身份編譯。
警吿:
  • 使用自定義內核可能會引起各種穩定性和可靠性問題,包括數據丟失。強烈建議操作前進行備份
  • Arch Linux 僅對#官方支持的內核提供官方支持。當使用非官方支持的內核時,務必在請求支持時提及這一點。
提示:
  • 提高系統速度的最佳方法是首先根據架構和處理器類型定製內核配置。
  • 可以通過不包含對你沒有用的內容來縮小內核的大小(也因此減少構建時間)。例如,對藍牙、video4linux、1000Mbit以太網等的支持。
Arch 內核包的 config 文件位於 Arch 軟件包的源文件中(例如:linux 連結到的 [2])。如果啟用了 CONFIG_IKCONFIG_PROC 內核選項,當前運行的內核的 config 文件也可能位於 /proc/config.gz

也可以通過Unofficial user repositories獲取一些列出的軟件包的二進制版本。

kernel.org 內核[編輯 | 編輯原始碼]

  • Git — 使用Linus Torvalds Git存儲庫中的原始碼構建的Linux內核和模塊
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git || linux-gitAUR
  • Mainline — 內核中引入了所有新功能,每2-3個月發佈一次
https://www.kernel.org/ || linux-mainlineAUR
  • Next — 具有待合併到下一個主線版本的功能的前沿內核
https://www.kernel.org/doc/man-pages/linux-next.html || linux-next-gitAUR
  • DRM — 帶有前沿 GPU 驅動程序的 Linux 內核。
https://cgit.freedesktop.org/drm/ || linux-drm-tip-gitAURlinux-drm-next-gitAUR
  • Longterm 4.9 — 長期支持 (LTS) Linux 4.9版本的內核和模塊
https://www.kernel.org/ || linux-lts49AUR
  • Longterm 4.14 — 長期支持 (LTS) Linux 4.14版本的內核和模塊
https://www.kernel.org/ || linux-lts414AUR
  • Longterm 4.19 — 長期支持 (LTS) Linux 4.19版本的內核和模塊
https://www.kernel.org/ || linux-lts419AUR
  • Longterm 5.4 — 長期支持 (LTS) Linux 5.4版本的內核和模塊
https://www.kernel.org/ || linux-lts54AUR
  • Longterm 5.10 — 長期支持 (LTS) Linux 5.10版本的內核和模塊
https://www.kernel.org/ || linux-lts510AUR

非官方內核[編輯 | 編輯原始碼]

  • linux-lily — 本站站長 Lilydjwg 使用的內核,包含 cjktty、Android binder 和默認 BBR。這是一個較少更新的內核包,可以通過添加 archlinuxcn 倉庫來安裝。
https://github.com/archlinuxcn/repo/tree/master/archlinuxcn/linux-lily || linux-lilyCNRepo
  • Ck — 包含Con Kolivas設計的補丁,旨在提高系統響應能力,尤其是桌面,但它們同時也適用於任何工作負載 。
http://ck.kolivas.org/ || linux-ckAUR
  • Clear — 英特爾 Clear Linux 項目的補丁,提供性能和安全優化。
https://github.com/clearlinux-pkgs/linux || linux-clearAUR
  • GalliumOS — 帶有 Chromebook 的 GalliumOS 補丁的 Linux 內核和模塊。
https://github.com/GalliumOS/linux || linux-galliumosAUR
https://www.fsfla.org/ikiwiki/selibre/linux-libre/ || linux-libreAUR
  • Liquorix — 使用面向 Debian 的配置和 Zen 內核原始碼構建的用於替換的內核。 專為桌面、多媒體和遊戲工作負載而設計,它通常用作 Debian Linux 性能替代內核。 Damentz 是 Liquorix 補丁集的維護者,也是 Zen 補丁集的開發者。
https://liquorix.net || linux-lqxAUR
  • pf-kernel — 提供了一些沒有合併到內核主線中的很棒的功能。 由內核工程師維護。 如果包含的新內核補丁的端未正式發佈,則補丁集提供並支持新內核的補丁端。 當前最突出的 linux-pf 補丁是 UKSM。
https://pfkernel.natalenko.name || 軟件包如下:
  • tkg — 具有特定 PDS 和 Project C / BMQ CPU 調度程序相關補丁集選擇器(庫存 CFS 也是一個選項)的自定義 Linux 內核,並添加了一些調整以實現良好的交互性/性能平衡,旨在獲得最佳遊戲體驗。 維護者是 Etienne Juvigny (Tk-Glitch)
https://github.com/Frogging-Family/linux-tkg || not packaged? search in AUR
  • VFIO — Linux 內核和 Alex Williamson(acs override和i915)編寫的一些修補程序,能夠在某些機器上使用 KVM 進行 PCI 直通。
https://lwn.net/Articles/499240/ || linux-vfioAUR, linux-vfio-ltsAUR
  • XanMod — 旨在充分利用高性能工作站、遊戲台式機、媒體中心和其他方面的優勢,旨在提供更堅如磐石、響應速度更快、更流暢的桌面體驗。此內核使用 MUQS 調度程序、BFQ I/O 調度程序、UKSM 實時內存重複數據消除, TCP BBR 擁塞控制、x86-64 高級指令集支持和其他默認更改。
https://xanmod.org/ || linux-xanmodAUR

疑難解答[編輯 | 編輯原始碼]

內核 Panics[編輯 | 編輯原始碼]

當Linux內核進入不可恢復的失敗狀態時,一個內核 Panics就會發生。這種狀態的發生通常歸咎於不成熟的(包含很多bug)的硬件驅動,它們導致系統死鎖、不能回復響應和必須重新啟動。僅僅在進入死鎖前,會生成診斷信息,它包括:當機器失敗發生時的 machine state 信息,一個識別這次失敗的內核函數的 call trace 調用棧,和一個當前已加載的內核模塊列表。幸運的是,內核 Panics在使用主線mainline版本內核的系統上並不經常發生,這些內核被官方倉庫所支持。但當它們發生時,你需要知道怎麼處理它們。

注意: 內核panics有時被提示為 oops 或者 kernel oops。當 panics 和 oops 作為機器失敗狀態的結果都發生時,一個 oops 通常不一定會導致系統死鎖:有時內核通過殺死問題任務進程從 oops 中恢復並繼續運行。
提示:然而可以在啟動時傳遞內核參數 oops=panic 或者向 /proc/sys/kernel/panic_on_oops 寫入 1 強制一個可恢復的 oops 引發一個 panic。如果你關心從 oops 中恢復導致的系統輕微的不穩定,這種不穩定可能會使未來的錯誤難於診斷,那麼建議你採取上面的做法。

示例:Panic消息[編輯 | 編輯原始碼]

如果一個內核panic發生在非常早的啟動過程(boot process)中,你可能會在終端中看見包含 "Kernel panic - not syncing:" 的信息,但是一旦 Systemd 開始運行,內核消息通常會被捕獲並寫入系統日誌裏面。然而,當一個panic發生時,內核輸出的診斷消息幾乎從不被寫入磁盤上的日誌文件,因為在 system-journald 得到機會前,系統已經死鎖了。因此,檢查panic消息的唯一方式就是當它發生時,在終端上觀察它(不需要求助於設置 kdump crashkernel)。你可以在啟動時帶有下面的內核參數,嘗試在tty1上生成panic消息:

systemd.journald.forward_to_console=1 console=tty1
提示:如果panic消息因滾動太快無法檢查,嘗試在啟動時傳遞 pause_on_oops=seconds 內核參數。

設想示例:壞模塊[編輯 | 編輯原始碼]

使用診斷消息裏面的信息,我們可以很好地猜測是哪一個子系統或者模塊正在導致panic。這下面的設想場景中,我們有一個panic發生在設想機器的啟動過程中。特別注意加粗高亮的行:

kernel: BUG: unable to handle kernel NULL pointer dereference at (null) 1
kernel: IP: fw_core_init+0x18/0x1000 [firewire_core] 2
kernel: PGD 718d00067
kernel: P4D 718d00067
kernel: PUD 7b3611067
kernel: PMD 0
kernel:
kernel: Oops: 0002 [#1] PREEMPT SMP
kernel: Modules linked in: firewire_core(+) crc_itu_t cfg80211 rfkill ipt_REJECT nf_reject_ipv4 nf_log_ipv4 nf_log_common xt_LOG nf_conntrack_ipv4 ... 3
kernel: CPU: 6 PID: 1438 Comm: modprobe Tainted: P           O    4.13.3-1-ARCH #1
kernel: Hardware name: Gigabyte Technology Co., Ltd. H97-D3H/H97-D3H-CF, BIOS F5 06/26/2014
kernel: task: ffff9c667abd9e00 task.stack: ffffb53b8db34000
kernel: RIP: 0010:fw_core_init+0x18/0x1000 [firewire_core]
kernel: RSP: 0018:ffffb53b8db37c68 EFLAGS: 00010246
kernel: RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000000
kernel: RDX: 0000000000000000 RSI: 0000000000000008 RDI: ffffffffc16d3af4
kernel: RBP: ffffb53b8db37c70 R08: 0000000000000000 R09: ffffffffae113e95
kernel: R10: ffffe93edfdb9680 R11: 0000000000000000 R12: ffffffffc16d9000
kernel: R13: ffff9c6729bf8f60 R14: ffffffffc16d5710 R15: ffff9c6736e55840
kernel: FS:  00007f301fc80b80(0000) GS:ffff9c675dd80000(0000) knlGS:0000000000000000
kernel: CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
kernel: CR2: 0000000000000000 CR3: 00000007c6456000 CR4: 00000000001406e0
kernel: Call Trace:
kernel:  do_one_initcall+0x50/0x190 4
kernel:  ? do_init_module+0x27/0x1f2
kernel:  do_init_module+0x5f/0x1f2
kernel:  load_module+0x23f3/0x2be0
kernel:  SYSC_init_module+0x16b/0x1a0
kernel:  ? SYSC_init_module+0x16b/0x1a0
kernel:  SyS_init_module+0xe/0x10
kernel:  entry_SYSCALL_64_fastpath+0x1a/0xa5
kernel: RIP: 0033:0x7f301f3a2a0a
kernel: RSP: 002b:00007ffcabbd1998 EFLAGS: 00000246 ORIG_RAX: 00000000000000af
kernel: RAX: ffffffffffffffda RBX: 0000000000c85a48 RCX: 00007f301f3a2a0a
kernel: RDX: 000000000041aada RSI: 000000000001a738 RDI: 00007f301e7eb010
kernel: RBP: 0000000000c8a520 R08: 0000000000000001 R09: 0000000000000085
kernel: R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000c79208
kernel: R13: 0000000000c8b4d8 R14: 00007f301e7fffff R15: 0000000000000030
kernel: Code: <c7> 04 25 00 00 00 00 01 00 00 00 bb f4 ff ff ff e8 73 43 9c ec 48
kernel: RIP: fw_core_init+0x18/0x1000 [firewire_core] RSP: ffffb53b8db37c68
kernel: CR2: 0000000000000000
kernel: ---[ end trace 71f4306ea1238f17 ]---
kernel: Kernel panic - not syncing: Fatal exception 5
kernel: Kernel Offset: 0x80000000 from 0xffffffff810000000 (relocation range: 0xffffffff800000000-0xfffffffffbffffffff
kernel: ---[ end Kernel panic - not syncing: Fatal exception
  1. 表明導致 panic 的錯誤類型。在這個例子中,是編程時留下的bug。
  2. 表明 panic 發生在 firewire_core 模塊的 fw_core_init 函數中。
  3. 表明 fw_core_init 模塊是載入的最新模塊。
  4. 表明 fw_core_init 函數的調用者是 do_one_initcall 函數。
  5. 表明這個 oops 消息實際上是一個內核panic,而且系統現在已經死鎖。

然後我們可以推測這個panic發生在模塊 firewire_core 載入時的初始化過程中。(然後我們可以推測機器的firewire硬件不兼容當前版本的firewire驅動模塊,因為它包含一個編程錯誤,而且不得不等待新的驅動發佈。)同時,使系統重新運行最簡單的方式就是不允許這個模塊被載入,我們可以採取下面兩種方式之一做到這一點:

  • 如果這個模塊是在 initramfs 執行期間被載入,則使用內核參數 rd.blacklist=firewire_core 重啟。
  • 其他情況下,使用內核參數 module_blacklist=firewire_core 重啟。

調試回退[編輯 | 編輯原始碼]

參考General troubleshooting#Debugging regressions

嘗試 linux-mainlineAUR 以檢查問題是否已在上游解決。下面的 Pinned Comments 還提到了一個包含已經構建的內核的存儲庫,因此可能不需要花費時間手動構建它。

也可以考慮嘗試使用 LTS 內核 (linux-lts) 來調試最近沒有出現的問題。舊版本的 LTS 內核可以在 Arch Linux Archive 找到。

如果問題仍然存在,bisect linux-gitAUR 並在 kernel bugzilla 上報吿錯誤。嘗試不帶任何補丁的「vanilla」版本以確保問題與補丁無關是很重要的。如果補丁導致了問題,請將其報吿給補丁的作者。

注意: bisect 內核可能需要很多時間,因為可能需要多次重建。

參見[編輯 | 編輯原始碼]