内核
根据维基百科
Arch Linux 基于 Linux 内核。除了最新的稳定内核之外,还有各种可用于 Arch Linux 的替代 Linux 内核。本文列出了一些在软件仓库中可用的选项,并简要描述了每个选项。本文还描述了可以应用于系统内核的补丁。文章最后概述了自定义内核编译以及指向各种方法的链接。
内核软件包安装在 /usr/lib/modules/
路径下,随后用于在 /boot/
中生成 vmlinuz 可执行镜像。[1] 当安装不同的内核或在多个内核之间切换时,您必须配置您的引导加载器以反映更改。有关将内核降级到旧版本的信息,请参阅软件包降级#降级内核。
官方支持的内核
- 稳定版 — 原版 Linux 内核和模块,应用了一些补丁。
- 强化版 — 专注于安全的 Linux 内核,应用了一组强化补丁以减轻内核和用户空间漏洞的利用。它还启用了比 linux 更多的上游内核强化功能。
- 长期支持版 — 长期支持 (LTS) Linux 内核和模块,其配置选项针对服务器中的使用。
- 实时内核 — 由 Ingo Molnar 领导的一个小型核心开发人员小组维护。此补丁允许几乎所有内核都被抢占,除了少数非常小的代码区域(“raw_spinlock 临界区”)。这是通过将大多数内核自旋锁替换为支持优先级继承的互斥锁,以及将所有中断和软件中断移动到内核线程来完成的。
- https://wiki.linuxfoundation.org/realtime/start || linux-rt, linux-rt-lts
- 注意: 实时内核支持已合并到 Linux 6.12
编译
以下方法可用于编译您自己的内核
- /Arch 构建系统
- 利用现有 linux PKGBUILD 的高质量以及软件包管理的优势。
- /传统编译
- 涉及手动下载源代码 tarball,并在您的主目录中以普通用户身份进行编译。
- 提高系统速度的最佳方法是首先根据您的架构和处理器类型定制您的内核配置。
- 您可以通过不包含对您没有或不使用的东西的支持来减小内核的大小(并因此缩短构建时间)。例如,支持蓝牙、video4linux、1000Mbit 以太网等。
config
文件位于 Arch 软件包源文件中(例如,[2] 链接自 linux)。如果您启用了 CONFIG_IKCONFIG_PROC
内核选项,则当前正在运行的内核的 config
文件也可能在文件系统中的 /proc/config.gz
中找到。某些列出的软件包也可能通过 非官方用户仓库 以二进制软件包的形式提供。
kernel.org 内核
- Git — 使用来自 Linus Torvalds 的 Git 仓库的源代码构建的 Linux 内核和模块。
- 主线 — 引入所有新功能的内核,每 2-3 个月发布一次。
- Next — 具有待合并到下一个主线版本的功能的前沿内核。
- DRM — 具有前沿 GPU 驱动程序的 Linux 内核。
- 长期支持版 — 长期支持 (LTS) Linux 内核和模块。
- https://linuxkernel.org.cn/ || linux-lts66AUR, linux-lts61AUR, linux-lts515AUR, linux-lts510AUR, linux-lts54AUR
非官方内核
- Ck — 包含 Con Kolivas 的补丁(包括 MuQSS 调度器),旨在提高系统响应速度,特别强调桌面,但它们适用于任何工作负载。
- Clear — 来自 Intel Clear Linux 项目的补丁。提供性能和安全优化。
- Liquorix — 使用面向 Debian 的配置和 Zen 内核源代码构建的内核替代品。专为桌面、多媒体和游戏工作负载而设计,通常用作 Debian Linux 性能替代内核。Liquorix 补丁集的维护者 Damentz 也是 Zen 补丁集的开发人员。
- pf-kernel — 提供一些未合并到内核主线中的出色功能。由内核工程师维护。如果新内核的包含补丁的端口未正式发布,则补丁集会为新内核提供和支持补丁端口。linux-pf 当前最突出的补丁是 UKSM、DDCCI、v4l2loopback 和 BBRv3。
- https://pfkernel.natalenko.name || 软件包
- 仓库, linux-pfAUR 由 pf-kernel 开发者 post-factum
- Project C — 带有 Alfred Chen 的 Project C 补丁集(BMQ 和 PDS 调度器)的内核。
- Nitrous — 针对 Skylake 及更新版本优化的修改版 Linux 内核。
- tkg — 高度可定制的内核构建系统,提供一系列旨在提高桌面和游戏性能的补丁和调整。它由 Etienne Juvigny 维护。在其他补丁中,它提供各种 CPU 调度器:CFS、Project C PDS、Project C BMQ、MuQSS 和 CacULE。
- VFIO — Linux 内核和 Alex Williamson 编写的一些补丁(acs override 和 i915),以在某些机器上通过 KVM 实现 PCI Passthrough 功能。
- 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 内核,带有其他补丁和改进的内核和模块
故障排除
内核崩溃
内核崩溃发生在 Linux 内核进入不可恢复的故障状态时。该状态通常源于有缺陷的硬件驱动程序,导致机器死锁、无响应并需要重启。在死锁之前,会生成一条诊断消息,包括:发生故障时的机器状态、导致内核函数识别故障的调用跟踪以及当前加载的模块列表。值得庆幸的是,使用主线版本的内核(例如官方仓库提供的那些)时,内核崩溃的情况并不经常发生,但当它们确实发生时,您需要知道如何处理它们。
oops=panic
或写入 1
到 /proc/sys/kernel/panic_on_oops
以强制可恢复的 oops 发出崩溃。如果您担心 oops 恢复可能导致系统不稳定,从而使未来的错误难以诊断,则建议这样做。检查崩溃信息
如果内核崩溃发生在启动过程的早期,您可能会在控制台上看到一条包含“Kernel panic - not syncing:”的消息,但是一旦 Systemd 正在运行,内核消息通常会被捕获并写入系统日志。但是,当发生崩溃时,内核输出的诊断消息几乎从不写入磁盘上的日志文件,因为机器会在 system-journald
有机会之前死锁。因此,检查崩溃消息的唯一方法是在控制台上查看它发生时的情况(无需设置 kdump crashkernel)。您可以通过使用以下内核参数启动并在 tty1 上尝试重现崩溃来做到这一点
systemd.journald.forward_to_console=1 console=tty1
pause_on_oops=seconds
。示例场景:错误的模块
可以根据诊断消息中的信息,最好地猜测导致崩溃的子系统或模块。在此场景中,我们在某台假想机器启动时发生崩溃。请注意以粗体突出显示的行
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
- 指示导致崩溃的错误类型。在本例中,这是一个程序员错误。
- 指示崩溃发生在模块 firewire_core 中的名为 fw_core_init 的函数中。
- 指示 firewire_core 是最后加载的模块。
- 指示调用函数 fw_core_init 的函数是 do_one_initcall。
- 指示此 oops 消息实际上是内核崩溃,并且系统现在已死锁。
然后我们可以推测,崩溃发生在加载模块 firewire_core 时模块的初始化例程期间。(然后我们可以假设,由于程序员错误,机器的 firewire 硬件与此版本的 firewire 驱动程序模块不兼容,并且必须等待新版本。)同时,使机器再次运行的最简单方法是阻止模块加载。我们可以通过以下两种方式之一来做到这一点
- 如果模块在执行 initramfs 期间加载,请使用内核参数
rd.blacklist=firewire_core
重新启动。 - 否则,使用内核参数
module_blacklist=firewire_core
重新启动。
重启进入 root shell 并修复问题
您将需要 root shell 来对系统进行更改,以便不再发生崩溃。如果崩溃发生在启动时,有几种策略可以在机器死锁之前获得 root shell
- 使用内核参数
emergency
、rd.emergency
或-b
重新启动,以在 root 文件系统挂载且systemd
启动后立即收到登录提示。
- 注意: 此时,root 文件系统将以只读方式挂载。以 root 用户身份执行
mount -o remount,rw /
以进行更改。
- 使用内核参数
rescue
、rd.rescue
、single
、s
、S
或1
重新启动,以在本地文件系统挂载后立即收到登录提示。 - 使用内核参数
systemd.debug_shell
在 tty9 上获得非常早期的 root shell。通过按Ctrl+Alt+F9
切换到它。 - 通过使用不同的内核参数集重新启动来实验,以可能禁用导致崩溃的内核功能。尝试“旧的备用选项”
acpi=off
和nolapic
。
- 提示: 有关所有内核参数,请参阅 kernel-parameters.html。
- 作为最后的手段,使用 Arch Linux 安装介质 启动,并将 root 文件系统挂载到
/mnt
,然后以 root 用户身份执行arch-chroot /mnt
。 - 禁用导致崩溃的服务或程序,回滚错误的更新,或修复配置问题。
调试衰退
请参阅 通用故障排除#调试衰退。
尝试 linux-mainlineAUR 以检查问题是否已在上游修复。置顶评论还提到了一个包含已构建内核的仓库,因此可能没有必要手动构建它,这可能需要一些时间。
也可能值得考虑尝试 LTS 内核 (linux-lts) 来调试最近未出现的问题。旧版本的 LTS 内核可以在 Arch Linux 归档中找到。
如果问题仍然存在,请 二分法 linux-gitAUR 内核并根据内核流程报告 报告衰退 的错误。根据 MAINTAINERS
文件中的 Bugtracker (B:
) 条目,这随后需要通过子系统邮件列表、Kernel Bugzilla 或其他问题跟踪器(如 DRM Gitlab)打开问题。重要的是尝试不带任何补丁的“vanilla”版本,以确保它与它们无关。如果补丁导致问题,请向补丁的作者报告。
构建更小的内核
您可以使用 modprobed-db 或 make localmodconfig
仅构建本地系统所需的模块来缩短内核构建时间。当然,您可以完全删除不相关的驱动程序,例如声音驱动程序来调试网络问题。
参见
- O'Reilly - Linux Kernel in a Nutshell (免费电子书)
- 我应该使用哪个稳定内核? 作者:Greg Kroah-Hartman
- Linux 内核文档