Warning
当你开始定制内核的时候,你将会有大把时间用来浪(xué)费(xí)。
本文后续会在 gentoo wiki 更新:https://wiki.gentoo.org/wiki/User:Douglarek/Streamlining_kernel
本文灵感来自 reddit1 上一位使用 Gentoo 的老哥,根据他提供的链接一路追到了他在 Gentoo wiki 上的文章2,他这篇文章比较简洁,只是其中一些东西没说太清楚,而且也不太符合 Gentoo 本身的做法,另外文中的 gentoo-sources 似无必要,直接使用 Distribution Kernel3 即可,这两个的唯一区别是如果你需要手动编译那么使用前者即可,如果是使用常规的 emerge 安装,并且享受系统安装带来的各种便利(如各种 portage 钩子),那么使用后者即可。
本文并不打算深入内核定制的细节(目前这方面我也是新手),主打一个清晰明了的流程走通,享受定制内核带来的编译时间的极大缩短(我的测试是大约能节省 2 倍左右的编译时间)。另外亦不介绍定制后内核的引导问题,毕竟这些无论是 Grub 还是 Systemd-boot 都有相关的 portage 钩子可做,假设你已经配置(否则需要手动处理)。
本文以 gentoo-kernel 为例(假设你当前安装的是 gentoo-kernel-bin 内核),分为以下几个步骤。
以 gentoo-kernel 6.11.9 为例:
(user)$: ebuild /var/db/repos/gentoo/sys-kernel/gentoo-kernel/gentoo-kernel-6.11.9.ebuild clean configure
(root)$: cd /var/tmp/portage/sys-kernel/gentoo-kernel-6.11.9/work/modprep
(root)$: make localmodconfig # 基于模块的构建,或者 make localyesconfig 直接编译进内核
Tip
该步的执行基于你当前加载的硬件信息,这里有一个弊端:可能会忽略某些硬件。比如移动硬盘在这之前没插入,那么这时候 USB 相关模块是不会收集的。那么有没有更好的方式收集呢,答案是 modprobed-db 4。那如果执行之前把所有的硬件都插上行不行呢,也可以,但是如果之后买来了新硬件需要不同的驱动,还是需要手动配置内核编译选项。modprobed-db 安装配置完之后可以每 6 个小时收集一次当前的硬件信息更新写入 modprobed.db 文件,那么自定义内核的时候使用 make LSMOD=$HOME/.config/modprobed.db localmodconfig
构建即可,一般建议 modprobed-db 在你的电脑上运行一段时间(比如 2 个月)后进行内核定制。
即便不用 modprobed-db,通过 Gentoo wiki 相关条目也能手动执行 make menuconfig
进行内核项配置,比如这里5以 USB 为例。
Important
以上的步骤不适合大版本之间的升级,比如 6.11.x 升级到 6.12.x ,一般这种升级会有内核选项的变化,跨版本是需要更新这个 .config 文件的。 一般来说两种方式:
make LSMOD=$HOME/.config/modprobed.db localmodconfig
直接在新的内核上开启需要的模块外加自己的配置make olddefconfig
6 将保留旧 .config 中的所有选项,并将新选项设置为推荐(即默认)值
保存自定义配置以便每次新内核构建时使用自定义配置:
(root)$: mkdir -p /etc/portage/savedconfig/sys-kernel/
(root)$: cp /var/tmp/portage/sys-kernel/gentoo-kernel-6.11.9/work/modprep/.config /etc/portage/savedconfig/sys-kernel/gentoo-kernel
Important
savedconfig 和其他 portage 选项一样,都有一致的配置方式,同样遵循配置文件某种形式的优先级,可以在 savedconfig wiki 条目7中具体查看。
自定义 USE 使构建使用自定义配置:
(root)$: mkdir /etc/portage/package.use/
(root)$: echo 'sys-kernel/gentoo-kernel savedconfig' > /etc/portage/package.use/kernel
Tip
启用 savedconfig USE flag 后,编译 gentoo-kernel 内核的时候将使用自定义配置,否则将使用通用编译配置。
(root)$: emerge -W gentoo-kernel-bin
(root)$: emerge -av gentoo-kernel
(root)$: emerge -av @module-rebuild
Note
- 这里解释一下为什么要先取消选择 gentoo-kernel-bin 然后安装 gentoo-kernel 呢,首先这两个不能同时存在,有冲突的;其次 gentoo-kernel 是可编译内核,简单说就是 emerge 的时候会进行编译,而 gentoo-kernel-bin 不会,虽然后者也是带源码和 gentoo 补丁的。
- 如果你是 N 卡用户,@module-rebuild 这一步几乎是必须的,如果你频繁定制同一版本的内核,很容易遗漏这一步;Dracut 只会在内核升级的时候触发 @module-rebuild。
构建时间8(qlop -vHt gentoo-kernel
)9:
前:2024-11-15T21:26:12 >>> sys-kernel/gentoo-kernel-6.11.8: 40 minutes, 8 seconds
后:2024-11-15T23:33:06 >>> sys-kernel/gentoo-kernel-6.11.8: 11 minutes, 28 seconds
安装大小10(qsize gentoo-kernel
):
前:sys-kernel/gentoo-kernel: 24177 files (24175 unique), 4500 non-files, 1.0G
后:sys-kernel/gentoo-kernel: 14565 files (14563 unique), 3550 non-files, 586.0M
显然不是,即便是通过 make localmodconfig
精简后的内核依然有很大的精简空间(比如文件系统,网络等),精简内核一切尽在 make menuconfig
。
这种情况是存在的,基本上两个方法:1. 看 tty 是否可以进 2. 通过 minimal cd 进入。然后通过 emerge -W gentoo-kernel
以及 emerge -av gentoo-kernel-bin
装回通用预编译内核即可。
Footnotes
-
https://www.reddit.com/r/Gentoo/comments/updoaz/comment/i8k5kpl ↩
-
https://wiki.gentoo.org/wiki/User:Flexibeast/guides/A_minimal_Gentoo_kernel_for_your_hardware ↩
-
https://wiki.gentoo.org/wiki/USB/Guide#Mounting_a_USB_mass_storage_device ↩
-
CPU: AMD Ryzen 5 5600X (12) @ 4.65 GHz
,MAKEOPTS="--jobs 8 --load-average 9"
↩ -
qlop 可以使用
emerge --ask app-portage/portage-utils
安装,qsize 也属于该软件包,具体参见:Q_applets ↩ -
这里的安装文件之所以这么大,原因是 gentoo-kernel 默认被开启了 debug,如果 -debug,那么尺寸还能更小(我本机是
152.5M
) ↩