2. Kconfig 数据类型:bool / tristate / string / hex / int 定义与使用场景
Kconfig 是 Linux 内核配置系统的核心语言,用于定义配置选项的数据类型、依赖关系和默认值。理解每种数据类型的语义与适用场景,是编写正确 Kconfig 文件、避免嵌入式配置故障的基础。
2.1 数据类型总览
Kconfig 支持五种基本数据类型,其核心差异在于可选值范围和编译行为:
| 数据类型 | 可选值 | 编译行为 | 典型使用场景 |
|---|---|---|---|
| bool | y / n | 编译进内核 / 不编译 | 功能开关、驱动启用/禁用 |
| tristate | y / m / n | 编译进内核 / 编译为模块 / 不编译 | 可模块化的驱动或子系统 |
| string | 任意字符串 | 编译时字符串常量 | 设备树路径、固件文件名、命令行参数 |
| hex | 十六进制数(0x…) | 编译时常量 | 内存地址、寄存器基址、硬件 ID |
| int | 十进制整数 | 编译时常量 | 缓冲区大小、超时值、通道数 |
嵌入式选型提示: 在资源受限的嵌入式平台中,优先使用 bool 而非 tristate,避免因模块加载引入额外的内存碎片和启动延迟。只有需要运行时动态加载/卸载的场景才使用 tristate。
2.2 数据类型定义语法与默认值设置
每种数据类型通过 default 关键字指定默认值。默认值可以是常量、另一个配置选项的引用,或条件表达式。
2.2.1 bool 类型
config FEATURE_FASTBOOT
bool "Enable fast boot optimization"
default y
help
Say Y here to enable fast boot sequence for embedded devices.
This reduces kernel init time by skipping non-critical probes.
- 默认值:
y或n。不写 default 时默认为n。 - 使用场景: 功能级开关,如是否启用某种优化、是否包含某个调试接口。
2.2.2 tristate 类型
config DRIVER_I2C_GPIO
tristate "GPIO-based I2C driver"
default m
depends on GPIOLIB
help
This driver supports I2C bus over GPIO pins.
Can be built as module (m) or built-in (y).
- 默认值:
y/m/n。不写 default 时默认为n。 - 使用场景: 驱动或子系统同时支持静态编译和模块加载的场景。
- 依赖约束: 如果父选项是
bool,子选项的 tristate 会被强制降级为 bool。
2.2.3 string 类型
config DTB_PATH
string "Device Tree Blob path"
default "/boot/dtb/kernel.dtb"
help
Specify the full path to the device tree blob file
used by the bootloader.
- 默认值: 双引号包裹的字符串,如
"default_value"。 - 使用场景: 文件路径、设备名称、IP 地址、日志前缀等可变文本。
2.2.4 hex 类型
config UART_BASE_ADDR
hex "UART controller base address"
default 0x10000000
range 0x10000000 0x1FFFFFFF
help
Base address of the UART controller in the memory map.
Must be within the peripheral address range.
- 默认值: 十六进制数,不加
0x前缀(Kconfig 自动按十六进制解析)。 - range 约束: 使用
range关键字限定合法区间,防止配置越界。 - 使用场景: 硬件寄存器地址、DMA 通道掩码、内存映射基址。
2.2.5 int 类型
config RX_RING_SIZE
int "RX ring buffer size (entries)"
default 256
range 64 4096
help
Number of entries in the receive ring buffer.
Must be a power of 2 for optimal performance.
- 默认值: 十进制整数。
- range 约束: 同样支持
range限定范围。 - 使用场景: 缓冲区大小、超时秒数、最大连接数、采样率等数值参数。
常见故障点: hex 类型的默认值如果写成
0x1000 带 0x 前缀,Kconfig 解析会报语法错误。正确的写法是 default 0x1000 中的 0x1000 本身是合法的,但更规范的写法是 default 0x1000(Kconfig 内部自动识别十六进制)。注意:不要写成 default 0x1000 以外的格式,如 default 0X1000 或 default 0x1000U。
2.3 数据类型选择决策流程
以下 SVG 流程图帮助开发者在编写 Kconfig 时快速确定数据类型:
2.4 默认值的高级用法
default 支持条件表达式,使配置选项的默认值随平台或依赖选项动态变化:
config CACHE_LINE_SIZE
int "Cache line size (bytes)"
default 64 if ARM64
default 32 if ARM
default 64
range 16 256
help
Default cache line size varies by architecture.
- 条件默认值: 使用
if后缀,Kconfig 按顺序匹配第一个条件为真的默认值。 - 回退默认值: 最后一个不带条件的
default作为全局回退。 - 覆盖规则: 用户显式配置的值始终优先于任何默认值。
嵌入式调试技巧: 在
.config 文件中,未配置的 bool/tristate 选项显示为 # CONFIG_XXX is not set;string/hex/int 如果未配置则不会出现在 .config 中,但会使用 Kconfig 中定义的默认值。排查配置故障时,优先检查 .config 中是否存在预期选项及其值。
2.5 数据类型与依赖关系
数据类型影响依赖传播行为。以下表格总结了关键规则:
| 父选项类型 | 子选项类型 | 子选项可见性 | 典型陷阱 |
|---|---|---|---|
| bool (y/n) | tristate | 父为 y 时子可选 y/m/n;父为 n 时子隐藏 | 子选项的 m 被强制转为 y |
| tristate (y/m/n) | bool | 父为 y 或 m 时子可选 y/n;父为 n 时子隐藏 | 父为 m 时子选项只能 y 或 n |
| tristate (y/m/n) | tristate | 父为 y 时子可选 y/m/n;父为 m 时子可选 m/n;父为 n 时子隐藏 | 模块依赖链中 m 的传递限制 |
| bool / tristate | string / hex / int | 父为 y 或 m 时子可见并可配置 | 父为 n 时子选项完全不可见 |
嵌入式故障案例: 某 ARM 平台将 DMA 驱动定义为
tristate,但其依赖的 DMA_ENGINE 是 bool。结果导致 DMA 驱动只能编译进内核(y),无法以模块加载,浪费了 Flash 空间。修复方法:将 DMA_ENGINE 改为 tristate 或显式在子选项中使用 depends on DMA_ENGINE=y。
2.6 数据类型与 menuconfig 界面呈现
不同数据类型在 menuconfig / nconfig 界面中的交互方式不同:
- bool: 显示为
[ ]复选框,按空格切换 y/n。 - tristate: 显示为
< >三态选择,按空格循环 y → m → n。 - string: 显示为
( )输入框,直接键入字符串。 - hex: 显示为
[ ]输入框,输入十六进制数(可带0x前缀)。 - int: 显示为
[ ]输入框,输入十进制整数。
理解这些交互细节,有助于在嵌入式调试时快速通过 make menuconfig 定位配置项。
2.7 本章小结
| 数据类型 | 核心关键词 | 默认值示例 | 嵌入式首选 |
|---|---|---|---|
| bool | 功能开关 | default y |
✅ 推荐 |
| tristate | 模块化驱动 | default m |
⚠️ 按需使用 |
| string | 路径/名称 | default "/path" |
✅ 推荐 |
| hex | 地址/掩码 | default 0x1000 |
✅ 推荐 |
| int | 大小/计数 | default 256 |
✅ 推荐 |