3、内核配置入门:Kconfig语法基础、make menuconfig图形化配置、配置项搜索技巧、保存与加载配置
说实话,很多初学者一上来就急着编译内核,结果编译出来的内核要么缺驱动,要么功能不全。我见过太多人卡在这一步了。内核配置,说白了就是给你的内核「选菜」——哪些功能要,哪些不要,全凭你说了算。但怎么选,怎么搜,怎么保存,这里头门道不少。
今天我们就来聊聊内核配置的入门三板斧:Kconfig语法、图形化配置、以及配置的保存与加载。嗯,这些都是基本功,但也是你后面做定制化编译的基石。
3.1 Kconfig语法基础:内核配置的「语言」
Kconfig 是什么?它是内核用来描述配置选项的一种脚本语言。每个内核模块、每个功能开关,背后都对应一个 Kconfig 条目。你想想看,内核有几千个配置项,如果没有一套统一的描述语言,那不乱套了?
我们先看一个最简单的例子。假设我们要添加一个驱动开关,Kconfig 里大概长这样:
config MY_DRIVER
bool "Enable My Driver"
default n
help
This is a sample driver for demonstration.
Say Y here if you want to use this driver.
这里有几个关键字段:
- config:配置项的名字,编译时会变成
CONFIG_MY_DRIVER宏。 - bool:类型,表示这是一个开关(Y/N)。还有 tristate(三态:Y/M/N)、int、string 等。
- default n:默认值,不选。
- help:帮助信息,告诉别人这个配置是干嘛的。
我在项目中遇到过一种情况:某个驱动依赖另一个驱动,但新人没写 depends on,结果编译出来驱动死活加载不上。所以,依赖关系一定要写清楚。
来看一个带依赖的例子:
config USB_STORAGE
tristate "USB Mass Storage support"
depends on USB && SCSI
help
Say Y here to support USB mass storage devices.
这里 depends on USB && SCSI 表示:只有 USB 和 SCSI 都开启了,这个选项才会出现。说白了,就是「父开关不开,子开关别想露脸」。
还有一种常见写法是 select,它会强制选中另一个配置。比如:
config A
bool "Feature A"
select B
选了 A,B 自动被选上。这个要小心用,我见过有人滥用 select 导致依赖链混乱,编译报错一堆。我的建议是:能用 depends on 就别用 select。
核心要点:Kconfig 是内核配置的「骨架」,理解它你才能看懂内核的配置逻辑。记住三个关键词:bool/tristate、depends on、select。
3.2 make menuconfig 图形化配置:上手最快的方式
说实话,我第一次接触内核配置时,面对几千个选项也是一脸懵。后来发现 make menuconfig 这个工具,简直救星。它基于 ncurses 库,在终端里给你一个图形界面,用方向键和空格就能操作。
怎么启动?很简单:
cd /path/to/linux-source
make menuconfig
前提是你得装了 ncurses 开发库。Ubuntu 上装一下:
sudo apt-get install libncurses-dev
进去之后,你会看到一个分层的菜单结构。上下键移动,回车进入子菜单,空格切换选项状态。Y 表示编译进内核,M 表示编译成模块,N 表示不选。
我个人习惯是:能编成模块的就编成模块,这样内核镜像小,启动快,驱动还能动态加载。但有些核心功能(比如调度器、内存管理)必须编进内核,不能模块化。
这里有个小技巧:按 / 键可以搜索配置项。比如你想找 EXT4 文件系统,按 / 输入 EXT4,它会列出所有匹配项,并告诉你它在菜单里的路径。这个功能我几乎每次配置都会用,省时省力。
提示:在 menuconfig 里,按 ? 键可以查看当前选项的详细帮助信息,包括依赖关系、默认值等。遇到不懂的配置,先按 ? 看看。
3.3 配置项搜索技巧:快速定位你想要的
内核配置项太多了,光靠手动翻菜单,效率太低。你需要学会搜索。刚才说了 / 键,但搜索也有门道。
比如,你想找所有和 USB 相关的配置,直接搜 USB 会出来一大堆。这时候可以加个限定:
- 搜
USB_STORAGE精确匹配某个配置名。 - 搜
/USB会匹配所有包含 USB 的选项。 - 搜
CONFIG_USB可以找到对应的宏定义。
我曾经在调试一个 USB 摄像头驱动时,怎么都找不到对应的配置项。后来用 /UVC 一搜,发现它藏在 Device Drivers → Multimedia support → Media USB Adapters 下面。嗯,路径很深,不搜根本找不到。
还有一个技巧:在搜索界面,按 1、2、3 可以快速跳转到匹配项的位置。这个功能很多人不知道,但非常实用。
注意:搜索出来的结果里,如果某个选项显示为 [=n],表示当前没选;[=y] 表示编进内核;[=m] 表示模块。看清楚再决定要不要改。
3.4 保存与加载配置:别让你的努力白费
配置了半天,结果忘了保存?别笑,我真见过有人干过这事。menuconfig 退出时会问你是否保存,选 Yes 就行。默认保存到 .config 文件。
但这里有个坑:.config 是隐藏文件,你 ls 看不到,得用 ls -a。我建议你养成好习惯,每次配置完,把 .config 备份一份:
cp .config config_my_custom
这样下次想用,直接加载:
cp config_my_custom .config
make menuconfig
或者更优雅的方式:
make KCONFIG_CONFIG=config_my_custom menuconfig
内核还提供了几个默认配置,方便你快速起步:
| 命令 | 说明 |
|---|---|
make defconfig |
生成当前架构的默认配置 |
make allyesconfig |
开启所有选项(编译试试?会很久) |
make allnoconfig |
关闭所有选项(最小内核) |
make oldconfig |
基于现有 .config 更新,只问新增项 |
我个人最常用的是 make oldconfig。比如你从内核 5.10 升级到 5.15,直接 make oldconfig,它只会问新版本新增的配置项,旧配置保持不变。省心。
避坑指南:我曾经在升级内核时,直接用了 make defconfig,结果之前精心调优的配置全丢了。从那以后,我每次升级都用 make oldconfig,或者手动备份 .config。记住:配置是心血,备份是美德。
3.5 知识体系总览
为了让你更直观地理解本章的知识结构,我画了一张图:
这张图把本章的四个核心模块串起来了。Kconfig 是语法基础,menuconfig 是操作工具,搜索技巧帮你快速定位,保存与加载则是工程实践。四者缺一不可。
好了,这一章的内容就到这里。配置入门其实不难,关键是动手练。找个内核源码,打开 menuconfig,随便翻翻,搜几个你感兴趣的驱动,试试改改配置,再保存加载几次。嗯,实践出真知。
公众号:蓝海资料掘金营,微信deep3321