Kernel/Gentoo 内核配置指南
本文档旨在介绍手动配置内核的概念并详细说明一些最常见的配置陷阱。
介绍
Gentoo 为用户提供了两种处理内核配置、安装和升级的方式:自动(通过 genkernel)和手动。虽然对于大多数用户来说自动配置是比较容易的方式,但是很多原因使得很大一部分 Gentoo 用户选择手动配置他们的内核:
- 更强的灵活性
- 更小的(内核)尺寸
- 更短的编译时间
- 学习并积累经验
- 闲着无聊
- 内核配置的绝对知识,和/或
- 对内核的完全控制
本指南不包括自动方式(通过 genkernel)。如果你想使用 genkernel 作为处理内核相关事务的首选方法,请参阅 Genkernel 文章以了解详细信息。
本指南并不尝试从头到尾记录手动配置的全过程——配置过程依赖于大量的常识和对所用系统的相对较高水平的技术知识。相反,本指南仅介绍手动配置的概念和详细说明用户面临的最常见的陷阱。
本指南是针对常见计算机架构的最新内核编写的。对于较旧的内核或较特殊的架构,某些细节可能有所不同;但是大部分内容仍然是适用的。
此时,假设用户已经在硬盘上(通常在 /usr/src 下)解压了 Linux 内核源代码,并且应该具有进入基于 ncursers 的 menuconfig 菜单系统并在其中浏览的知识。如果用户不在此阶段,可以参阅其它文档以获取帮助。阅读以下文章,然后返回到本指南:
- 文章 内核源码概述 包含Portage树里提供的多个内核源码包的信息。
- 文章 内核升级 中说明了如何升级一个内核或者从一个内核切换到另一个内核。
- Gentoo Handbook中的 内核配置章节 涵盖了内核安装的部分内容,选择对应的CPU构架,再查看“配置Linux内核”章节。
配置有关概念
基础
总体的过程实际上相当简单:在一系列分类显示为单独的菜单和子菜单的选项中选择所需的硬件支持和与系统相关的内核功能。
内核包含一个“默认配置”,其会在 menuconfig 第一次在一套内核源码上执行时显示。默认配置总体来说已经合理地配置了大部分选项,因此大部分用户只需要对基础的内核配置作较少的更改即可。当决定禁用一个内核默认配置中打开的选项时,确认自己已经彻底理解了这个选项所做的事情以及禁用它的结果。
第一次配置内核时,请保守一些;不要过于激进,尽可能尽可能少得改动默认配置。同时牢记有一些特定于设备的配置必须要正确定制才能够让内核正常启动。
内建对比模块
大部分配置选项都是“三态”的:可以选择完全不编译 (N)
,直接内建到内核 (Y)
,或者作为一个模块编译 (M)
。相比于独立于内核镜像存放在文件系统上的模块,内建的内容直接构建进内核镜像。
内建对比模块有一个重要的,存在一些例外的不同点,内核从不会尝试加载任何外部模块,即使系统可能需要它们;模块何时,或者何时不加载完全由用户决定。尽管系统的其他组件可能有需要时加载的机制,也有一些自动模块加载的工具,把硬件支持和内核特性内建进内核仍然是推荐的做法。这样内核可以确保需要某些功能和硬件支持时,它们总是可用的。这可以通过把每个内核特性都设置为(Y)
来实现。要与这种内核配置配合工作,在内核中包含固件支持也是必要的。详情请参阅 Linux 固件 一文。
对一些内核配置而言,内建至内核是必须的。例如,如果根分区是 btrfs 格式而 btrfs 被作为模块构建,系统就无法启动。系统必须查找根分区来找到 btrfs 模块(因为模块存储在根分区内),但是内核无法查找根分区,除非它已经加载 btrfs 支持了!如果 btrfs 不内建到内核,init 进程会无法找到根设备。
请参阅内核模块以获得更多信息,配置内核的相关步骤请参阅使用 menuconfig 一节。
硬件支持
除了检测系统的“架构类型”,内核配置工具不会尝试检测系统商存在的而硬件。尽管默认配置已经开启了“一些”硬件支持,用户基本一定需要查找并选择和每个设备的硬件相关的配置选项。
选择正确的配置选项需要了解计算机内部和连接到计算机的各种部件。大多数情况下这些部件可以在不关机设备的情况下被确定。对大部分内部部件而言,用户需要确定每个设备使用的“芯片组”,而不是零售时使用的商品名称。大部分扩展卡的商品名品牌和实际使用的芯片组制造商并不相同。
有一些可以帮助用户确定应该使用哪些内核配置选项的工具。lspci(包含于sys-apps/pciutils包中)识别基于 PCI 和 AGP 的硬件,这其中包括了主板板载的硬件。lsusb(由sys-apps/usbutils包提供)识别连接到设备USB端口上的各种设备。
由于硬件设备的标准化程度不同,情况有些混乱。除非用户对默认配置修改过度,IDE 硬盘、PS/2键鼠应该“正常工作”。基础的VGA显示也属于这类情况。然而,类似以太网适配器的一些设备则几乎不存在标准;这些设备的用户必须辨识以太网芯片组的型号并且为特定的适配器选择恰当的硬件支持以访问网络。
此外,即使一些设备使用默认配置即可基本工作,要利用全部的功能可能还是需要启用一些更专用的选项。例如如果对合适的IDE芯片组的支持没有被启用,IDE硬盘将会运转地“相当”慢。
建议将需要固件的驱动配置为模块以简化从硬盘加载固件的过程。这类驱动通常包括GPU和(在不使用NFS或者类似的基于网络的根文件系统时)网络设备。
内核特性
除了硬件支持之外,用户也需要考虑需要内核中的哪些软件特性。这类特性的一个重要例子就是文件系统支持:用户必须选择他们在硬盘上和可能在外部存储设备上使用的文件系统(例如USB设备上的VFAT文件系统)。
另一个常见的这类软件特性是高级的网络功能。为了实现一些路由或者防火墙功能,相关的配置项必须在内核配置中打开。
准备好了么?
现在大致的概念已经介绍过了,识别系统硬件,浏览 menuconfig 页面并选择系统所需的内核选项应该不是一件难事了。
这个教程的剩余部分将会理清常见的误解点,并且提供避免常见问题的建议。祝你好运!
常见的问题和困惑点
SATA 硬盘是 SCSI 设备
大部分现代桌面系统将存储设备(硬盘以及CD/DVD驱动器)挂载在一个串行 ATA总线上,而不是使用老式的(使用带状电缆的) IDE总线上。
Linux内核中的SATA支持是通过一个称为“libata”的中间层实现的,其位于SCSI子系统中。因此SATA驱动在配置中位于SCSI驱动一节。此外系统中的存储设备也会被作为SCSI设备对待,这意味着SCSI磁盘/CD驱动器支持也是必须的。第一个SATA硬盘将会被命名为/dev/sda,第一个SATA CD/DVD驱动器将会被命名为/dev/sr0。
尽管其中大多数驱动是为SATA控制器编写的,libata并非特定于SATA设计的。所有常见的IDE驱动也已经被移植到了libata中,在文章编写时,以上的注意事项也同样适用于IDE用户。
Device Drivers --->
SCSI device support --->
<*> SCSI device support
<*> SCSI disk support
<*> SCSI CDROM support
[ ] SCSI low-level drivers --->
<*> Serial ATA and Parallel ATA drivers (libata) --->
非标准的芯片组驱动在上文
Serial ATA and Parallel ATA drivers (libata)
内核配置框的SCSI low-level drivers
中列出。USB 主机控制器
USB是一种广泛应用于外设与计算机连接的总线。USB 成功背后的原因之一是其标准化的协议,然而计算机主机上实现的 USB“主机控制器设备(HCD)”各有一定差异。主要有四种类型:
UHCI
是通用主机控制器接口。它支持 USB 1.1,常见于基于 VIA 或 Intel 芯片组的主板。OHCI
是开放主机控制器接口。它支持 USB 1.1,常见于基于 NVIDiA 或者 SIS 芯片组的主板。EHCI
是扩展主机控制器接口。它是唯一被广泛使用的支持 USB 2.0 的主机控制器,一般见于任何支持 USB 2.0 的计算机上。XHCI
是可扩展主机控制器接口。它是为 USB 3.0 设计的主机控制器,并且兼容 USB 1.0,1.1,2.0,3.0 以及将来可能定义的其它速率。主板支持 USB 3.0 时需要启用这个特性。
大多数设备都搭载上述的两种接口类型:XHCI(USB 3.0)“以及”EHCI(USB 2.0)。使用 USB 设备不再需要同时启用这两个选项,因为 XHCI 兼容更慢的 USB 控制器。用户也可以启用 EHCI 来“额外地保险一些”;它在 USB 2.0 控制器不存在时不会带来副作用。
如果与系统上的 USB HCD 种类相搭配的选项没有被打开,那么可能会存在一些“坏”USB 端口。可以通过一个正常的设备插入某 USB 端口时没有被供电或对其作出相应来判断这种情况。
有一个利用lspci(由sys-apps/pciutils提供)来简化检测系统上存在的 HCD 的方便技巧。忽略被误匹配的 SATA 控制器,很容易发现此系统需要 EHCI 和 XHCI 支持。
root #
lspci -v | grep HCI
00:14.0 USB controller: Intel Corporation 8 Series/C220 Series Chipset Family USB xHCI (rev 04) (prog-if 30 [XHCI]) 00:1a.0 USB controller: Intel Corporation 8 Series/C220 Series Chipset Family USB EHCI #2 (rev 04) (prog-if 20 [EHCI]) 00:1d.0 USB controller: Intel Corporation 8 Series/C220 Series Chipset Family USB EHCI #1 (rev 04) (prog-if 20 [EHCI]) 00:1f.2 SATA controller: Intel Corporation 8 Series/C220 Series Chipset Family 6-port SATA Controller 1 [AHCI mode] (rev 04) (prog-if 01 [AHCI 1.0])
启用系统上存在的 HCD 所需的配置选项。一般地,启用全部三个选项可以最大化地支持可能的设备,精确的配置是因系统而异的:
Device Drivers --->
USB support --->
<*> Support for Host-side USB
--- USB Host Controller Drivers
<*> xHCI HCD (USB 3.0) support
<*> EHCI HCD (USB 2.0) support
< > OHCI HCD (USB 1.1) support
< > UHCI HCD (most Intel and VIA) support
在 3.12.13 或者更新的 Linux 内核中,如果 USB 控制器是 OCHI 类型并且使用了 USB 键盘或者鼠标,OHCI support for PCI-bus USB controllers
(USB_OHCI_HCD_PCI
)必须被启用。
多处理器、超线程和多核系统
很多系统以一种不明显的方式使用了多处理器技术。
- 几乎全部较新的 Intel/AMD/IBM CPU 都支持同时多线程(SMT)技术,这项技术也被称为超线程。这项技术使得一个 CPU 核心可以被系统视作两个或者更多个“逻辑”处理器。
- 大多数较新的 CPU 在一个封装中包含了多个物理处理器,这些处理器被称为多核处理器。
- 一些高端计算机系统确实在特殊的主板上安装有多个物理处理器,以提供相比于“单处理器”系统更大的性能提升。这些系统的用户有很大可能知道他们的系统的特殊性,因为这类系统并不廉价。
在以上所有情况中,必须开启下列配置中的恰当内核选项才能获得最好的性能:
Processor type and features --->
[*] Symmetric multi-processing support
[*] SMT (Hyperthreading) aware nice priority and policy support
[*] Multi-core scheduler support (NEW)
下一个选项不仅启用了电源管理特性,同时可能是让所有 CPU 对系统均可用所必需的。
Power management and ACPI options --->
[*] ACPI (Advanced Configuration and Power Interface) Support
x86 高端内存支持
由于 x86 架构受限于 32-bit 地址空间,使用默认配置的内核只能支持最大 896MB 的内存。一个有更多内存的系统也只有前 896MB 内存对系统是可见的,除非启用高端内存支持。
这个限制是x86(IA32)架构所特有的。其他架构天生支持大容量内存,不需要调整配置。
高端内存支持默认未被打开,因为其会造成少量系统资源消耗。但不要被此所误导,相比于更多可用内存带来的性能提升而言,这些消耗是微不足道的!
选择下面的 4 GB 选项,除非系统上有超过 4 GB 的内存。
Processor type and features --->
High Memory Support --->
(X) 4GB
( ) 64GB
压缩内核模块
在内核 3.18.x (以及更高)的版本,压缩内核模块是可行的。在编译一个启用压缩模块的内核“之前” 用正确的 USE 标志 emerge sys-apps/kmod 是很重要的。
sys-apps/kmod lzma zlib
重新 emerge sys-apps/kmod:
root #
emerge --ask --oneshot --changed-use sys-apps/kmod
启用模块压缩并且选择首选的压缩格式:
[*] Enable loadable module support --->
Module compression mode () --->
( ) None
(X) GZIP
( ) XZ
( ) ZSTD
通常make modules_install会运行depmod。如果第一次运行sys-apps/kmod时没有为其设置正确的 USE 标志(参见上文的 package.use一步),依赖列表将会是空的。系统将无法加载任何以压缩方式构建的模块。
在重新编译 kmod 之后,重新运行depmod可以解决此问题:
root #
depmod -a
root #
modprobe <module_name>
内核配置简记法
简介
阅读内核配置相关文档时,配置选项经常被描述为CONFIG_<something>的形式。这种简记法就是内核配置内部使用的记法,也是存储在内核配置文件的格式(位于 /usr/src/linux/.confg 或者在自动生成的 /proc/config.gz 文件中)。当然,使用简记法只有在能将其转换到内核配置的所在的实际位置时才有好处。make menuconfig 工具可以做到这点。
将 CONFIG_FOO 转换为实际的内核配置位置
假设要启用 CONFIG_TMPFS_XATTR 特性。启动内核配置菜单(make menuconfig)并且按 / 键。这会打开一个搜索框。在搜索框中输入 CONFIG_TMPFS_XATTR。
以下是上述搜索的一个示例输出:
Symbol: TMPFS_XATTR [=n]
Type : boolean
Prompt: Tmpfs extended attributes
Defined at fs/Kconfig:138
Depends on: TMPFS [=y]
Location:
-> File systems
-> Pseudo filesystems
(1) -> Virtual memory file system support (former shm fs) (TMPFS [=y])
Selected by: TMPFS_POSIX_ACL [=n] && TMPFS [=y]
这个输出提供了很多有用的信息。
条目 | 描述 |
---|---|
Symbol: TMPFS_XATTR [=n] | 指示被搜索的内核配置项名字。也表示这个配置项目前“未被启用” ([=n]). |
Type: boolean | 所搜索的配置是一个布尔值(这意味着它可以是两个选项之一:启用或禁用)。一些配置是数字值或字符串值。 |
Prompt: Tmpfs extended attributes | 这是控制 .config 文件中对应变量(TMPFS_XATTR)的 make menuconfig 配置显示的文本。它实际上就是变量名更人类可读的形式。 |
Depends on: TMPFS [=y] | 在这个配置可见之前,CONFIG_TMPFS 必须被启用。在这个例子中它已经被启用了(因此这里有 [=y]),但是如果情况并非如此,请先查找(并启用)CONFIG_TMPFS。 |
Location: ... | 这是 make menuconfig 配置层次中这个配置所在的位置。记住要查找的配置是“Tmpfs extended attributes"。 |
Selected by: TMPFS_POSIX_ACL [=n] && TMPFS [=y] | 如果这里描述的配置都启用了(这个例子中第一个配置并未启用),那么 CONFIG_TMPFS_XATTR 将会被自动启用并且无法被禁用,除非禁用这里描述的配置。 |
有了这些信息,启用任何 CONFIG_* 选项应当相当容易了。简单来说,用户必须要:
- 启用“Depends on”条目中描述的配置
- 导航到“Location”指向的位置
- 调整"Prompt"引用的配置值
注意括号中的数字;用户可以通过在搜索时按数字来跳转到对应的配置项或者尽可能近地跳转到被启用的菜单附近。在上面的例子中,按键盘上的 1 将会跳转到该选项或者其附近
其他内核配置文档
到现在为止,我们只讨论了内核配置有关的总体概念和特定的问题;精确的细节留给用户自行发掘。不过 Gentoo 文档集的其他部分为这个主题合适地提供了特定的细节。
这些文档可能能帮助配置内核的特定部分。尽管这个警告在前文已经提到过了,但还是请牢记:新接触内核配置的用户不应该在配置他们的内核时过于激进。从配置一个基本的系统并使其运行开始,诸如音频、打印此类的支持总是可以推迟一些再配置。
先使内核的基本部分先运作起来可以在之后的配置过程中起到帮助,因为用户可以知道系统上哪些部分是有问题的,哪些部分是正确工作的。在尝试添加新特性或者硬件支持“之前”先备份基础的(已经工作的)内核配置到内核源码目录之外的目录总是个明智的选择。
- ALSA 文档详细讲述了声卡支持所需的内核配置选项。注意,ALSA 是不要将内核组件编译为模块这一方案的例外:ALSA 在相关组件被编译为模块时配置起来简单得多。
- 蓝牙文档详细讲述了使用蓝牙设备所需的内核配置选项。
- IPv6 路由教程描述了如何配置内核以使用新一代的网络地址格式进行路由。
- 如果将要使用闭源 NVIDIA 图形驱动来提升 3D 图形性能,NVIDIA 教程列出了一些在这类系统上应当和不应当选择的内核选项。
- 这些之外,电源管理指南解释了如何配置内核以获得 CPU 频率调节、挂起和睡眠功能。
- 如果正在运行的是一个 PowerPC 系统,PPC FAQ 包含了一些关于 PPC 内核配置的章节。
- Template:Link"Printing列出了在 Linux 上支持打印所需的内核选项。
- USB 指南 详细说明了使用常见的 USB 设备,例如键盘、鼠标、存储设备以及 USB 打印机所需的配置选项。
故障排除
配置更改不生效
用户更改配置后在实际启动到他们新配置的内核的过程中却犯了一个小错误是很常见。他们重新启动到了并非刚刚重新配置的内核映像中并发现他们试图解决的问题仍然存在,并错误地得出这个配置更改不能解决问题的结论。
编译和安装内核的过程超出了本文档的范围;请参阅 Kernel/Upgrade以获得总体上的指导。简而言之,应用更改后的内核的过程如下:
- 配置
- 编译
- 挂载 /boot (如果还没有挂载)
- 复制新的内核镜像到 /boot
- 确保引导加载程序将会使用新内核
- 重启
如果缺少了这些阶段之一,则更改将无法正确生效。
检查启动的内核是否是硬盘上新编译的内核是可行的。这可以通过检查内核的构建日期和时间来实现。假设系统架构为 x86 并且内核源代码安装在了 /usr/src/linux,可以使用如下的命令:
root #
uname -v
#4 SMP PREEMPT Sat Jul 15 08:49:26 BST 2006
上面的命令将显示当前启动的内核的编译日期和时间。
root #
ls -l /usr/src/linux/arch/i386/boot/bzImage
-rw-r--r-- 1 dsd users 1504118 Jul 15 08:49 /usr/src/linux/arch/i386/boot/bzImage
上面的命令显示硬盘上的内核镜像最后一次编译的日期和时间。
如果上述命令的时间戳之差超过了两分钟,说明重新安装内核的过程存在问题,系统没有从新修改的内核镜像启动。
模块不会自动加载
正如前文中所提及的,内核配置系统隐藏了将一个内核组件编译为模块 (M)
和内建入内核之间 (Y)
相当大的行为差异。由于许多用户掉入了这个陷阱,值得再次重复这一点。
当选择一个组件为内建时,代码构建进内核镜像(bzImage)。当内核需要使用这个组件时,它无需任何用户干涉即可初始化并自动加载它。
当选择一个组件为模块时,代码构建进一个内核模块文件并且安装在文件系统上。大多数情况下,内核无法需要使用这个组件时找到它。除了一些例外情况,内核不会尝试真正加载这些模块——这项任务需要用户完成。
当一个网卡的支持被构建为模块时发现无法访问网络,很可能是因为模块没有加载——这个操作要么需要手动完成,要么系统必须被配置好在启动时自动加载模块。
除非用户有不去这么做的理由,把这些组件直接构建进内核镜像可以省下一些时间,这样内核可以自行配置这些琐碎的设置。
另请参阅
- Genkernel — Gentoo 创建的一个用来自动化构建 kernel 和 initramfs 的软件。
- proc 文件系统(安全手册)——运行时动态改变内核参数和变量
This page is based on a document formerly found on our main website gentoo.org.
The following people contributed to the original document: Daniel Drake, Curtis Napier, Justin Robinson, Lukasz Damentko, Jonathan Smith, nightmorph
They are listed here because wiki history does not allow for any external attribution. If you edit the wiki article, please do not add yourself here; your contributions are recorded on each article's associated history page.