4. 内核配置基础:Kconfig 语法入门
Linux 内核的配置系统基于 Kconfig 语言,它定义了内核功能的组织方式、依赖关系和默认值。理解 Kconfig 是进行内核裁剪和嵌入式系统定制的前提。本章将系统讲解 Kconfig 的核心语法、.config 文件结构以及配置选项的类型。
学习目标:
- 掌握 Kconfig 中
config、menuconfig、choice等关键关键字的使用。 - 理解
depends on和select的依赖与反向依赖机制。 - 能够解读
.config文件的结构与变量命名规则。 - 区分
bool、tristate、string、int等配置选项类型及其适用场景。
4.1 Kconfig 语法基础
Kconfig 文件通常位于内核源码的 Kconfig 或 arch/<arch>/Kconfig 中,通过 source 语句层层包含。每个配置条目由关键字引导,形成树状结构。
4.1.1 核心关键字
| 关键字 | 作用 | 示例 |
|---|---|---|
config | 定义一个配置选项 | config MY_FEATURE |
menuconfig | 定义一个带子菜单的配置选项 | menuconfig NET |
menu/endmenu | 定义一个纯菜单容器(无开关) | menu "Networking support" |
choice/endchoice | 定义一组互斥选项 | choice ... endchoice |
if/endif | 条件包含一组选项 | if EXPERT ... endif |
source | 引入另一个 Kconfig 文件 | source "drivers/usb/Kconfig" |
4.1.2 属性关键字
| 属性 | 说明 | 示例 |
|---|---|---|
bool | 布尔值:y / n | bool "Enable debug output" |
tristate | 三态:y / m / n | tristate "Driver support" |
string | 字符串 | string "Device name" |
int | 整数 | int "Buffer size" |
hex | 十六进制数 | hex "Base address" |
default | 默认值 | default y |
depends on | 依赖另一个选项 | depends on PCI |
select | 反向选择(强制选中) | select CRC32 |
help | 帮助文本 | help ... endhelp |
提示:
tristate 中的 m 表示编译为可加载模块,仅在支持模块化的内核中有效。对于嵌入式系统,通常只使用 y 或 n。
4.1.3 完整 Kconfig 条目示例
config MY_DRIVER
tristate "My custom driver support"
depends on PCI && ARM
select CRC32
default y if ARM
default n
help
This enables support for My custom hardware.
Say Y here if you have this device.
4.2 依赖与反向依赖
4.2.1 depends on —— 前置依赖
当选项 A depends on B 时,只有 B 被选中(y 或 m),A 才可见并可被选中。如果 B 为 n,A 自动被隐藏或强制为 n。
config USB_STORAGE
tristate "USB storage support"
depends on USB && SCSI
4.2.2 select —— 反向依赖
当选项 A select B 时,选中 A 会自动将 B 设为 y(或 m,如果 B 是 tristate 且 A 为 m)。常用于库功能或底层驱动的自动启用。
config CRYPTO_AES
tristate "AES cipher"
select CRYPTO_ALGAPI
注意: 滥用
select 可能导致依赖循环或意外启用大量功能。嵌入式系统中应谨慎使用,避免内核膨胀。
4.3 choice —— 互斥选项组
choice 用于定义一组互斥的配置选项,用户只能选择其中之一。常用于 CPU 类型、总线协议、调度算法等场景。
choice
prompt "CPU frequency scaling governor"
default CPU_FREQ_GOV_PERFORMANCE
config CPU_FREQ_GOV_PERFORMANCE
bool "Performance"
help
CPU runs at maximum frequency.
config CPU_FREQ_GOV_POWERSAVE
bool "Powersave"
help
CPU runs at minimum frequency.
config CPU_FREQ_GOV_ONDEMAND
bool "Ondemand"
help
CPU frequency scales dynamically.
endchoice
4.4 .config 文件结构
内核配置完成后,所有选项的值被写入顶层 .config 文件。该文件是纯文本格式,每行一个配置项,遵循 CONFIG_<NAME>=<VALUE> 的格式。
4.4.1 变量命名规则
| Kconfig 中的名称 | .config 中的变量名 | 示例 |
|---|---|---|
MY_DRIVER | CONFIG_MY_DRIVER | CONFIG_MY_DRIVER=y |
USB_STORAGE | CONFIG_USB_STORAGE | CONFIG_USB_STORAGE=m |
BUFFER_SIZE | CONFIG_BUFFER_SIZE | CONFIG_BUFFER_SIZE=1024 |
4.4.2 典型 .config 片段
#
# General setup
#
CONFIG_INIT_ENV_ARG_LIMIT=32
CONFIG_LOCALVERSION=""
CONFIG_LOCALVERSION_AUTO=y
#
# Processor type and features
#
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
CONFIG_CPU_FREQ_GOV_ONDEMAND=m
#
# Device Drivers
#
CONFIG_USB=y
CONFIG_USB_STORAGE=m
CONFIG_MY_DRIVER=n
关键点:
- 以
#开头的行为注释,通常用于分组标题或未设置的选项。 - 未设置的选项以
# CONFIG_XXX is not set形式出现。 - 字符串和整数直接赋值,如
CONFIG_LOCALVERSION=""。 - 三态选项:
y(编译进内核)、m(编译为模块)、n(不编译)。
4.5 配置选项类型详解
| 类型 | 取值范围 | 典型用途 | 示例 |
|---|---|---|---|
bool | y / n | 功能开关、特性启用 | bool "Enable debug" |
tristate | y / m / n | 驱动支持(可模块化) | tristate "Network driver" |
string | 任意字符串 | 设备名、路径、参数 | string "Root device" |
int | 整数 | 缓冲区大小、超时值 | int "Timeout (ms)" |
hex | 十六进制数 | 内存地址、寄存器偏移 | hex "MMIO base" |
嵌入式建议: 在资源受限的嵌入式系统中,优先使用
bool 而非 tristate,因为模块加载器本身也会占用内存。对于必须动态加载的驱动,才使用 tristate。
4.6 Kconfig 配置流程 SVG 图
4.7 本章小结
- Kconfig 语法 是内核配置的基石,
config定义选项,menuconfig和menu组织层次,choice处理互斥。 - 依赖关系 通过
depends on实现前置条件,select实现反向强制选中。 .config文件 是配置的最终输出,格式为CONFIG_XXX=y/m/n或CONFIG_XXX="value"。- 选项类型 决定用户可输入的值范围:
bool用于开关,tristate用于模块化,string/int/hex用于参数传递。
实践建议: 在嵌入式项目中,建议从
defconfig 开始,使用 make menuconfig 逐项裁剪,并定期检查 .config 中是否有不必要的 m 选项,将其改为 y 或 n 以减小内核体积。