Other languages:Deutsch
English
español
français
magyar
русский
中文(中国大陆)
日本語
한국어
本文档旨在介绍手动配置内核的思路并详细说明一些最常见的配置陷阱。
Contents
1 介绍
2 内核配置的相关概念
2.1 基础
2.2 内建对比模块
2.3 硬件支持
2.4 内核特性
2.5 准备好了么?
3 配置内核
3.1 启用必要的配置选项
3.2 为典型的系统部件开启内核支持
3.3 SATA 和 NVMe 磁盘
3.4 File system support
3.5 USB 主机控制器
3.6 多处理器、超线程和多核系统
3.7 压缩内核模块
3.8 PPPoE
3.9 Signed kernel modules and SecureBoot
3.9.1 Signing the kernel image (Secure Boot)
3.10 Architecture specific kernel configuration
3.10.1 amd64
3.11 x86
4 Compiling and installing
5 内核配置简记法
5.1 简介
5.2 将 CONFIG_FOO 转换为实际的内核配置位置
6 其他内核配置文档
7 故障排除
7.1 配置更改不生效
7.2 模块不会自动加载
8 另请参阅
介绍
Gentoo 为用户提供了两种处理内核配置、安装和升级的方式:自动(例如通过 genkernel)和手动。虽然对于大多数用户来说自动配置更加简单,但仍有很多原因使得很大一部分 Gentoo 用户选择手动配置他们的内核:
更强的灵活性和对配置的控制权
更小的(内核)尺寸
更短的编译时间
学习并积累经验
{{Note|尽管[[:Project::Distribution_Kernel/zh-cn|发行版内核]]的体积会比自行配置的内核稍大,请注意Linu只会在需要时才加载内核模块,所以在运行时使用的内存上不会有很大差别。
本指南并不包含手动配置内核的详尽流程——配置内核需要大量的技术基础知识和对目标系统的较深的了解。相反,本指南仅介绍手动配置的思路,并详细说明用户配置时最常遇到的陷阱。
附注本指南是针对常见计算机架构的最新内核编写的。对于较旧的内核或较特殊的架构,某些细节可能有所不同;但是大部分内容仍然是适用的。
本文假设用户已经在硬盘上(通常在 /usr/src 路径下)解压了 Linux 内核源代码,并且了解如何进入基于 ncursers 的 menuconfig 菜单系统并在其中浏览。如果用户尚未了解相关内容,可以参阅其它文档以获取帮助。推荐阅读以下文章后再继续阅读本指南:
文章 内核源码概述 包含Portage树里提供的多个内核源码包的信息。
文章 内核升级 中说明了如何升级一个内核或者从一个内核切换到另一个内核。
内核配置的相关概念
基础
配置内核的答题过程实际上相当简单:只需在分类显示为单独的菜单和子菜单的一系列选项中选择所需的硬件支持和与目标系统相关的内核功能。
内核包含一个“默认配置”,其会在 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 页面并选择系统所需的内核选项应该不是一件难事了。
这个教程的剩余部分将会理清常见的误解点,并且提供避免常见问题的建议。祝你好运!
配置内核
启用必要的配置选项
在使用sys-kernel/gentoo-sources时,强烈建议开启一些特定于Gentoo系统的配置选项。下列步骤启用了Gentoo系统正常工作所需内核特性的最小子集:
内核 Enabling Gentoo-specific options Gentoo Linux --->
[*] Gentoo Linux support
[*] Linux dynamic and persistent device naming (userspace devfs) support
[*] Select options required by Portage features
Support for init systems, system and service managers --->
[*] OpenRC, runit and other script based systems and managers
[*] systemd
自然地,最后两行配置的具体选择取决于用户使用的 init 系统(OpenRC 或者 systemd)。同时在内核中启用为两个不同 init 系统提供的选项不会产生副作用。
sys-kernel/vanilla-sources内核没有这些额外为 init 系统考虑的配置选项。可以手动开启相关支持。
为典型的系统部件开启内核支持
确保全部系统启动所必需的驱动程序(比如SATA控制器,NVMe块设备支持,文件系统支持等等)都内建于内核镜像中而不是构建为模块,否则系统可能完全无法启动。
Next select the exact processor type. It is also recommended to enable MCE features (if available) so that users are able to be notified of any hardware problems. On some architectures (such as x86_64), these errors are not printed to dmesg, but to /dev/mcelog. This requires the app-admin/mcelog package.
Also select Maintain a devtmpfs file system to mount at /dev so that critical device files are already available early in the boot process (CONFIG_DEVTMPFS and CONFIG_DEVTMPFS_MOUNT):
内核 Enabling devtmpfs support (CONFIG_DEVTMPFS) Device Drivers --->
Generic Driver Options --->
[*] Maintain a devtmpfs filesystem to mount at /dev
[*] Automount devtmpfs at /dev, after the kernel mounted the rootfs
SATA 和 NVMe 磁盘
大部分现代桌面系统将存储设备(硬盘以及CD/DVD驱动器)挂载在一个[wikipedia:SATA|串行 ATA]总线上,而不是老式的(使用带状电缆的) [wikipedia:Parallel ATA| 并行 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用户。
内核 libata的配置选项 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中列出。
内核 Enable basic NVMe support for Linux 5.x.x (CONFIG_BLK_DEV_NVME) Device Drivers --->
NVME Support --->
<*> NVM Express block device
It does not hurt to enable the following additional NVMe support:
内核 Enabling additional NVMe support (CONFIG_NVME_MULTIPATH, CONFIG_NVME_MULTIPATH, CONFIG_NVME_HWMON, CONFIG_NVME_FC, CONFIG_NVME_TCP, CONFIG_NVME_TARGET, CONFIG_NVME_TARGET_PASSTHRU, CONFIG_NVME_TARGET_LOOP, CONFIG_NVME_TARGET_FC, CONFIG_NVME_TARGET_FCLOOP, CONFIG_NVME_TARGET_TCP) [*] NVMe multipath support
[*] NVMe hardware monitoring
[*] NVMe Target Passthrough support
< > NVMe over Fabrics FC Transport Loopback Test driver (NEW)
Now go to File Systems and select support for the filesystems that will be used by the system. Do not compile the file system that is used for the root filesystem as module, otherwise the system may not be able to mount the partition. Also select Virtual memory and /proc file system. Select one or more of the following options as needed by the system:
File system support
内核 Enable file system support (CONFIG_EXT2_FS, CONFIG_EXT3_FS, CONFIG_EXT4_FS, CONFIG_BTRFS_FS, CONFIG_XFS_FS, CONFIG_MSDOS_FS, CONFIG_VFAT_FS, CONFIG_PROC_FS, and CONFIG_TMPFS) File systems --->
< > Second extended fs support
< > The Extended 3 (ext3) filesystem
<*> The Extended 4 (ext4) filesystem
<*> Btrfs filesystem support
<*> XFS filesystem support
DOS/FAT/NT Filesystems --->
<*> MSDOS fs support
<*> VFAT (Windows-95) fs support
Pseudo Filesystems --->
[*] /proc file system support
[*] Tmpfs virtual memory file system support (former shm fs)
Note that ext2 and ext3 are redundant since the ext4 driver already supports all ext versions.
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 HCI00: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 所需的配置选项。一般地,启用全部三个选项可以最大化地支持可能的设备,精确的配置是因系统而异的:
内核 USB 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
压缩内核模块
在内核 3.18.x (以及更高)的版本,压缩内核模块是可行的。在编译一个启用压缩模块的内核“之前” 用正确的 USE 标志 emerge sys-apps/kmod 是很重要的。
文件 /etc/portage/package.use/kmod为 kmod 启用压缩支持 sys-apps/kmod lzma zlib
重新 emerge sys-apps/kmod:
root #emerge --ask --oneshot --changed-use sys-apps/kmod
启用模块压缩并且选择首选的压缩格式:
内核 Enable module compression
[*] Enable loadable module support Search for CONFIG_MODULES
to find this item. --->
Module compression mode () --->
( ) None
(X) GZIP
( ) XZ
( ) ZSTD
PPPoE
If PPPoE is used to connect to the Internet, or a dial-up modem, then enable the following options (CONFIG_PPP, CONFIG_PPP_ASYNC, and CONFIG_PPP_SYNC_TTY):
内核 Enabling PPPoE support (PPPoE, CONFIG_PPPOE, CONFIG_PPP_ASYNC, CONFIG_PPP_SYNC_TTY) Device Drivers --->
Network device support --->
<*> PPP (point-to-point protocol) support
<*> PPP over Ethernet
<*> PPP support for async serial ports
<*> PPP support for sync tty ports
通常make modules_install会运行depmod。如果第一次运行sys-apps/kmod时没有为其设置正确的 USE 标志(参见上文的 package.use一步),依赖列表将会是空的。系统将无法加载任何以压缩方式构建的模块。
在重新编译 kmod 之后,重新运行depmod可以解决此问题:
root #depmod -a
root #modprobe
Signed kernel modules and SecureBoot
To automatically sign the kernel modules enable CONFIG_MODULE_SIG_ALL:
内核 Sign kernel modules (CONFIG_MODULE_SIG_ALL) [*] Enable loadable module support
-*- Module signature verification
[*] Automatically sign all modules
Which hash algorithm should modules be signed with? (Sign modules with SHA-512) --->
Optionally change the hash algorithm if desired.
To enforce that all modules are signed with a valid signature, enable CONFIG_MODULE_SIG_FORCE as well:
内核 Enforce signed kernel modules (CONFIG_MODULE_SIG_FORCE) [*] Enable loadable module support
-*- Module signature verification
[*] Require modules to be validly signed
[*] Automatically sign all modules
Which hash algorithm should modules be signed with? (Sign modules with SHA-512) --->
To use a custom key, specify the location of this key in CONFIG_MODULE_SIG_KEY. If unspecified, the kernel build system will generate a key. It is recommended to generate one manually instead. This can be done with:
root #openssl req -new -nodes -utf8 -sha256 -x509 -outform PEM -out kernel_key.pem -keyout kernel_key.pem
OpenSSL will ask some questions about the user generating the key, it is recommended to fill in these questions as detailed as possible.
Store the key in a safe location, at the very least the key should be readable only by the root user. Verify this with:
root #ls -l kernel_key.pem -r-------- 1 root root 3164 Jan 4 10:38 kernel_key.pem
If this outputs anything other then the above, correct the permissions with:
root #chown root:root kernel_key.pem
root #chmod 400 kernel_key.pem
内核 Specify signing key (CONFIG_MODULE_SIG_KEY) -*- Cryptographic API --->
Certificates for signature checking --->
(/path/to/kernel_key.pem) File name or PKCS#11 URI of module signing key
To also sign external kernel modules installed by other packages via linux-mod-r1.eclass, enable the modules-sign USE flag globally:
文件 /etc/portage/make.confEnable module signing USE="modules-sign"