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 / nbool "Enable debug output"
tristate三态:y / m / ntristate "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_DRIVERCONFIG_MY_DRIVERCONFIG_MY_DRIVER=y
USB_STORAGECONFIG_USB_STORAGECONFIG_USB_STORAGE=m
BUFFER_SIZECONFIG_BUFFER_SIZECONFIG_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 配置选项类型详解

类型取值范围典型用途示例
booly / n功能开关、特性启用bool "Enable debug"
tristatey / m / n驱动支持(可模块化)tristate "Network driver"
string任意字符串设备名、路径、参数string "Root device"
int整数缓冲区大小、超时值int "Timeout (ms)"
hex十六进制数内存地址、寄存器偏移hex "MMIO base"
嵌入式建议: 在资源受限的嵌入式系统中,优先使用 bool 而非 tristate,因为模块加载器本身也会占用内存。对于必须动态加载的驱动,才使用 tristate。

4.6 Kconfig 配置流程 SVG 图

Kconfig 配置解析与 .config 生成流程 Kconfig 文件 配置工具 (menuconfig) 用户交互选择 依赖解析 (depends on / select) 生成 .config 文件 内核编译 (make) 说明 Kconfig 定义选项结构; 配置工具解析并展示给用户; 依赖关系自动处理; 最终输出 .config 供编译。

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 以减小内核体积。