跳转至内容

内核

来自 ArchWiki
(重定向自 Linux)

根据维基百科

Linux 内核是一个开源的单体类 Unix 计算机操作系统内核

Arch Linux 基于 Linux 内核。除了最新的稳定版内核外,Arch Linux 还有多种备选 Linux 内核可用。本文列出了仓库中可用的一些选项并附有简要说明。此外还介绍了可以应用于系统内核的补丁。文章最后概述了自定义内核编译,并提供了各种方法的链接。

内核软件包被安装/usr/lib/modules/ 路径下,随后用于将 vmlinuz 可执行镜像复制到 /boot/[1] 在安装不同的内核或在多个内核之间切换时,您必须配置引导加载程序 (boot loader) 以反映这些更改。有关将内核降级到旧版本的方法,请参阅 降级软件包#降级内核

官方支持的内核

官方支持的内核可以通过论坛获得社区支持,并提供缺陷报告服务。

  • Stable (稳定版) — 原生 (Vanilla) Linux 内核及模块,应用了少量补丁。
https://linuxkernel.org.cn/ || linux
  • Hardened (加固版) — 专注于安全的 Linux 内核,应用了一系列加固补丁以缓解内核和用户空间漏洞利用。相比于 linux,它还启用了更多上游内核加固特性。
https://github.com/anthraxx/linux-hardened || linux-hardened
  • Longterm (长期支持版) — 长期支持 (LTS) Linux 内核及模块。在使用可能无法及时发布与最新稳定内核兼容版本的树外 (out-of-tree) 模块时非常有用。
https://linuxkernel.org.cn/ || linux-lts
  • Realtime (实时内核) — 由 Ingo Molnar 领导的小型核心开发团队维护。该补丁允许几乎整个内核被抢占,除了少数极小的代码区域(“raw_spinlock 临界区”)。这是通过将大多数内核自旋锁替换为支持优先级继承的互斥锁,并将所有中断和软件中断移动到内核线程来实现的。
https://wiki.linuxfoundation.org/realtime/start || linux-rt, linux-rt-lts
注意: 实时内核支持已合并入 Linux 6.12
https://github.com/zen-kernel/zen-kernel || linux-zen

编译

可以使用以下方法编译您自己的内核

/Arch 编译系统 (ABS)
利用现有的高质量 linux PKGBUILD软件包管理的优势。
/传统编译方式
涉及手动下载源代码压缩包,并作为普通用户在您的家目录中进行编译。
警告
  • 使用自定义内核可能会导致各种稳定性和可靠性问题,包括数据丢失。强烈建议进行备份
  • Arch Linux 仅对 #官方支持的内核 提供官方支持。当使用其他内核时,请在寻求支持时说明。
提示
  • 提高系统速度的最佳方法是首先根据您的架构和处理器类型定制内核配置。
  • 您可以通过不包含您没有或不使用的功能的持(例如蓝牙、video4linux、1000Mbit 以太网等支持)来减小内核的大小(从而缩短构建时间)。
Arch 内核包的 config 文件位于 Arch 软件包源文件中(例如,从 linux 链接到的 [2])。如果启用了 CONFIG_IKCONFIG_PROC 内核选项,当前运行内核的 config 文件也可以在文件系统中的 /proc/config.gz 处找到。

列表中的某些软件包也可能通过非官方用户仓库作为二进制包提供。

kernel.org 内核

  • Git — 使用 Linus Torvalds 的 Git 仓库源码构建的 Linux 内核及模块。
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git || linux-gitAUR
  • Mainline (主线) — 引入所有新特性的内核,每 2-3 个月发布一次。
https://linuxkernel.org.cn/ || linux-mainlineAUR
  • Next — 前沿内核,包含待合并到下一个主线版本的特性。
https://linuxkernel.org.cn/doc/man-pages/linux-next.html || linux-next-gitAUR
  • DRM — 带有前沿 GPU 驱动程序的 Linux 内核。
https://gitlab.freedesktop.org/drm || linux-drm-tip-gitAUR, linux-drm-next-gitAUR
  • Longterm (长期支持) — 长期支持 (LTS) Linux 内核及模块。
https://linuxkernel.org.cn/ || linux-lts66AUR, linux-lts61AUR, linux-lts515AUR, linux-lts510AUR

非官方内核

  • Tachyon — 来自 Intel Clear Linux 项目的补丁,因 Clear Linux 项目已停止维护,现已 fork 到新项目。提供性能和安全性优化。
https://git.staropensource.de/StarOpenSource/Linux-Tachyon || linux-tachyonAUR
https://www.fsfla.org/ikiwiki/selibre/linux-libre/ || linux-libreAUR
  • Liquorix — 使用面向 Debian 的配置和 Zen 内核源码构建的替代内核。专为桌面、多媒体和游戏负载设计,常被用作 Debian Linux 的性能替换内核。Liquorix 补丁集的维护者 Damentz 同时也是 Zen 补丁集的开发者。
https://liquorix.net || linux-lqxAUR
  • pf-kernel — 提供了一些未合并到内核主线的出色特性。由一名内核工程师维护。如果所含补丁对新内核的移植尚未官方发布,该补丁集会提供并支持向新内核的移植。目前 linux-pf 最突出的补丁包括 UKSM、DDCCI、v4l2loopback 和 BBRv3。
https://pfkernel.natalenko.name || 软件包
  • Project C — 带有 Alfred Chen 的 Project C 补丁集(BMQ 和 PDS 调度器)的内核。
https://gitlab.com/alfredchen/projectc || linux-prjcAUR
  • Nitrous — 针对 Skylake 及更新架构优化的修改版 Linux 内核。
https://gitlab.com/xdevs23/linux-nitrous || linux-nitrousAUR
  • tkg — 一个高度可定制的内核构建系统,提供了一系列旨在提高桌面和游戏性能的补丁和调整。它由 Etienne Juvigny 维护。除了其他补丁外,它还提供各种 CPU 调度器:CFS、Project C PDS、Project C BMQ、MuQSS 和 CacULE。
https://github.com/Frogging-Family/linux-tkg || 可在 chaotic-aur 中获得。
  • VFIO — Linux 内核及由 Alex Williamson 编写的一些补丁(acs override 和 i915),旨在允许某些机器通过 KVM 进行 PCI 直通 (PCI Passthrough)。
https://lwn.net/Articles/499240/ || linux-vfioAUR, linux-vfio-ltsAUR
  • XanMod — 旨在充分利用高性能工作站、游戏桌面、媒体中心等设备的潜力,旨在提供更稳定、响应更迅速、更流畅的桌面体验。该内核使用 BFQ I/O 调度器、TCP BBRv3 拥塞控制、x86_64 高级指令集支持、部分 Clear Linux 补丁集以及其他默认更改。
https://xanmod.org/ || linux-xanmodAUR, linux-xanmod-ltsAUR, linux-xanmod-rtAUR, linux-xanmod-boreAUR
  • linux-cachyos — 由 CachyOS 提供的 Linux SCHED-EXT + BORE + Cachy Sauce 内核,包含其他补丁和改进的内核及模块。
https://github.com/CachyOS/linux-cachyos || linux-cachyosAUR

许多此类非官方内核包含需要手动启用的特性。请尝试阅读补丁本身的文档(许多补丁已包含对内核源码中 Documentation/ 目录的修改)或在网上搜索该补丁集的名称。

故障排除

内核恐慌 (Kernel panics)

当 Linux 内核进入不可恢复的故障状态时,就会发生内核恐慌 (kernel panic)。这种状态通常源于有缺陷的硬件驱动程序,导致机器死锁、无响应并需要重启。在死锁之前,系统会生成一条诊断信息,包括:发生故障时的机器状态、指向识别出故障的内核函数的调用堆栈 (call trace),以及当前加载模块的列表。幸运的是,使用官方仓库提供的主线 (mainline)版本内核时,内核恐慌并不经常发生——但当它们发生时,您需要知道如何处理。

注意: 内核恐慌有时被称为 oopskernel oops。虽然恐慌和 oops 都是由故障状态引起的,但 oops 更为宽泛,因为它不一定导致机器死锁:有时内核可以通过终止出错的任务并继续运行来从 oops 中恢复。
提示: 在启动时传递内核参数 oops=panic,或向 /proc/sys/kernel/panic_on_oops 写入 1,可以强制可恢复的 oops 也发出恐慌。如果您担心 oops 恢复导致的微小系统不稳定可能使未来的错误难以诊断,建议这样做。

检查恐慌信息

如果内核恐慌发生在引导过程的极早期,您可能会在控制台上看到包含 Kernel panic - not syncing: 的消息;但一旦 systemd 开始运行,内核消息通常会被捕获并写入系统日志。然而,当恐慌发生时,内核输出的诊断信息几乎从不会被写入磁盘上的日志文件,因为机器在 system-journald 有机会执行之前就已死锁。

蓝屏二维码

linux 6.10 起(针对 drm_panic),内核会在蓝屏中(默认)以二维码 (QR code)形式显示恐慌信息。堆栈轨迹 (stack trace) 可在二维码提供的 URL 中查看。对于 Arch Linux,这是一个指向 https://panic.archlinux.org/panic_report 的链接。该 URL 包含各种信息以及由 gzip 压缩并编码在 URL 片段 (fragment) 中的堆栈轨迹,该片段不会传输到服务器(在客户端进行处理)。

论坛帖子中可以看到带有链接和截图的恐慌示例。

您可以通过将参数 panic_screen=kmsg 传递给 drm 内核模块(或作为内核参数 drm.panic_screen=kmsg)来恢复旧行为,在控制台中显示堆栈轨迹。

控制台方式

在崩溃发生时直接在控制台上查看的“旧式”方法仍然可用(无需设置 kdump crashkernel)。使用以下内核参数引导并尝试在 tty1 上复现恐慌

systemd.journald.forward_to_console=1 console=tty1
提示: 如果恐慌信息滚动太快而无法检查,请尝试在启动时传递内核参数 pause_on_oops=秒数
示例场景:错误的模块

利用诊断信息中的内容,可以初步判断是哪个子系统或模块导致了恐慌。在此场景中,我们假设一台机器在引导期间发生了恐慌。请注意加粗高亮显示的行

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. 指示导致恐慌的错误类型。在这种情况下,这是一个程序员引入的 bug。
  2. 指示恐慌发生在模块 firewire_core 中名为 fw_core_init 的函数里。
  3. 指示 firewire_core 是最后加载的模块。
  4. 指示调用 fw_core_init 函数的函数是 do_one_initcall
  5. 指示此 oops 消息实际上是一个内核恐慌,系统现在已死锁。

由此我们可以推断,恐慌发生在 firewire_core 模块加载时的初始化程序中。(我们可以假设该机器的 firewire 硬件由于程序错误与此版本的驱动模块不兼容,必须等待新版本发布。)与此同时,让机器重新运行最简单的方法是防止该模块被加载。我们可以通过以下两种方式之一来实现

  • 如果该模块在 initramfs 执行期间加载,请使用内核参数 rd.blacklist=firewire_core 重启。
  • 否则,请使用内核参数 module_blacklist=firewire_core 重启。

重启进入 root shell 并修复问题

本文或本章节已过时。

原因: 由于 initramfs 中的 root 账户已被锁定rd.rescuerd.emergency 将无法工作。(请在 Talk:Kernel 中讨论)

本文或本章节的准确性存在争议。

原因: 键盘在 rd.emergency 中无法工作,因此无法使用。(请在 Talk:Kernel 中讨论)

您需要一个 root shell 来修改系统,以便不再发生恐慌。如果恐慌发生在启动时,有几种策略可以在机器死锁前获取 root shell

  • 使用内核参数 emergencyrd.emergency-b 重启,以便在根文件系统挂载且 systemd 启动后立即获得登录提示符。
注意: 此时根文件系统将以只读方式挂载。以 root 用户身份执行 mount -o remount,rw / 即可进行更改。
  • 使用内核参数 rescuerd.rescuesinglesS1 重启,以便在本地文件系统挂载后立即获得登录提示符。
  • 使用内核参数 systemd.debug_shell 重启,以便在 tty9 上获取极早期的 root shell。按 Ctrl+Alt+F9 切换到该 shell。
  • 通过使用不同的内核参数组合重启来尝试实验,以禁用可能导致恐慌的内核特性。试试“老法子” acpi=offnolapic
提示: 有关所有内核参数,请参阅 kernel-parameters.html
  • 作为最后手段,使用 Arch Linux 安装介质引导,将根文件系统挂载到 /mnt,然后以 root 用户身份执行 arch-chroot /mnt
  • 禁用导致恐慌的服务或程序,回滚有问题的更新,或修复配置问题。
提示: 如果原始镜像已损坏,可能需要生成新的 初始化内存盘 (initial ramdisk) 镜像。当内核更新中断时可能会发生这种情况。有关创建新镜像的方法,请参阅 mkinitcpio

调试回归问题

参见 常规故障排除#调试回归问题

尝试 linux-mainlineAUR 以检查问题是否已在上游修复。置顶评论还提到了一个包含已编译内核的仓库,因此可能不需要手动构建,手动构建会消耗很长时间。

对于非近期出现的问题,也值得尝试 LTS 内核 (linux-lts) 进行调试。较旧版本的 LTS 内核可以在 Arch Linux Archive 中找到。

如果问题仍然存在,请 二分查找 linux-gitAUR 内核,并根据内核 报告回归错误 的流程报告 bug。根据 MAINTAINERS 文件中的 Bugtracker (B:) 条目,这可能需要通过子系统的邮件列表、Kernel Bugzilla 或 DRM Gitlab 等其他问题跟踪器来打开一个 issue。尝试使用“纯净版”内核(不打任何补丁)进行测试很重要,以确保问题与补丁无关。如果某个补丁导致了问题,请向该补丁的作者报告。

注意: 对内核进行二分搜索可能需要很长时间,因为它可能需要多次重新构建。

编译更小的内核

您可以通过使用 modprobed-dbmake localmodconfig 仅构建本地系统所需的模块来缩短内核构建时间。当然,为了调试网络问题,您可以完全丢弃无关的驱动程序(例如声卡驱动)。

参见