内核配置基础:从 defconfig 到 menuconfig
内核配置,说白了就是告诉编译器:哪些功能要编译进内核,哪些编译成模块,哪些干脆不要。我刚开始接触 Rockchip 平台时,觉得这步就是跑个 make menuconfig 完事。后来才发现,配置不对,轻则功能缺失,重则系统都起不来。
这一章,我们就把内核配置的底牌翻出来看看。
4.1 三板斧:defconfig、menuconfig、.config
Rockchip 平台的内核配置,核心就三个东西:
- 默认配置(defconfig):芯片厂商提供的“标准答案”
- 图形化配置(menuconfig):你手动调整的交互界面
- .config 文件:最终生效的配置文件
三者的关系,我画了张图,你看一眼就明白了。
4.2 第一步:加载默认配置
拿到 Rockchip 的内核源码后,第一件事就是加载芯片对应的默认配置。以 RK3588 为例:
make ARCH=arm64 rockchip_linux_defconfig
这条命令干了什么?它把 arch/arm64/configs/rockchip_linux_defconfig 文件复制到源码根目录,重命名为 .config。
我的习惯:每次执行 defconfig 前,我都会先看一眼 arch/arm64/configs/ 目录下有哪些文件。Rockchip 平台通常有多个 defconfig,比如 rockchip_linux_defconfig 是通用版,rockchip_linux_defconfig_debug 是调试版。选错了,后面全是坑。
4.3 第二步:图形化微调
默认配置能满足大部分场景,但总有些功能需要你手动开关。这时候就该 menuconfig 上场了。
make ARCH=arm64 menuconfig
界面出来后,你会看到按功能分类的菜单树。我常用的操作就三个:
- 搜索:按
/键,输入关键词,快速定位配置项 - 切换状态:按
Y编译进内核,按M编译成模块,按N禁用 - 保存退出:按左右箭头选
Save,再选Exit
我曾经踩过的坑:有次我改了配置后直接按 Exit,没点 Save。结果编译出来的内核跟之前一模一样,排查了半天才发现配置根本没保存。记住:Exit 不保存,Save 才保存。
4.4 .config 文件结构
打开 .config 文件,你会看到成百上千行配置项。结构其实很简单:
# 注释行,以 # 开头
# CONFIG_XXX is not set
# 配置项被启用(编译进内核)
CONFIG_ROCKCHIP_I2S=y
# 配置项被编译成模块
CONFIG_ROCKCHIP_CRYPTO=m
# 配置项带参数
CONFIG_ROCKCHIP_GRF_BASE=0xFE000000
每个配置项的值有三种可能:
| 值 | 含义 | 说明 |
|---|---|---|
y |
编译进内核 | 功能直接集成到内核镜像中,启动时可用 |
m |
编译成模块 | 生成 .ko 文件,需要时手动加载 |
n 或未设置 |
禁用 | 该功能完全不编译 |
我的建议:驱动开发阶段,尽量把相关驱动设为 y。设为 m 虽然灵活,但模块加载顺序、依赖关系处理起来很麻烦。等产品稳定了,再考虑把不常用的驱动改成模块。
4.5 配置依赖:你动一个,可能牵出一串
内核配置项之间是有依赖关系的。比如你想启用某个 Rockchip 的音频驱动,它可能依赖 I2C 控制器、DMA 引擎、时钟框架等。如果你只选了音频驱动,没选依赖项,menuconfig 会自动帮你选上,或者直接灰掉让你选不了。
这种依赖关系定义在 Kconfig 文件中。举个例子:
config ROCKCHIP_I2S
tristate "Rockchip I2S controller"
depends on ARCH_ROCKCHIP
select SND_SOC_GENERIC_DMAENGINE_PCM
help
Say Y here to include support for Rockchip I2S controller.
这里 depends on 表示前置条件,select 表示自动选中。我刚开始看这些时,总觉得 depends on 和 select 差不多。后来才搞明白:depends on 是“你必须有”,select 是“我帮你选上”。
4.6 保存与备份:别让配置丢了
配置调好后,我建议你做两件事:
- 保存一份到 defconfig:
make ARCH=arm64 savedefconfig,这条命令会生成一个精简版的 defconfig,只包含你修改过的配置项。 - 备份 .config:
cp .config config_$(date +%Y%m%d),万一改坏了还能回滚。
我的工作流:每次调完配置,我都会用 diff .config arch/arm64/configs/rockchip_linux_defconfig 看看改了哪些地方。这样心里有数,也方便写提交说明。
4.7 常见问题与避坑
- 配置冲突:两个配置项互斥时,menuconfig 会提示。别硬来,看看依赖关系再决定。
- 配置丢失:执行
make distclean会删除 .config,记得备份。 - 配置不生效:改了 .config 后一定要重新编译,
make不会自动检测配置变化。
嗯,内核配置这块,说难不难,说简单也不简单。关键是理解 defconfig、menuconfig、.config 这三者的关系,以及配置项之间的依赖。掌握了这些,后面编译内核、调试驱动,才能顺风顺水。