一、Kconfig的作用
Kconfig 是 Linux 内核(还有很多项目)用来做配置菜单的系统。当你运行 make menuconfig 时看到的那些菜单、选项、子菜单,其实就是由 Kconfig 文件定义的。
1、它的作用:
(1)告诉内核构建系统:“有哪些功能可以打开或关闭”
(2)定义每个功能之间的依赖关系(例如:WiFi 要依赖网络栈)
(3)控制默认值、显示文本、是否作为模块等
你写的选项最后会生成一个 .config 文件,比如:
CONFIG_NET=y
CONFIG_USB=m
CONFIG_DEBUG=n
这些就是由 Kconfig 文件控制的。
2、举例说明
假设你写了一个小驱动 led.c,你想在 menuconfig 里添加一个“LED 支持”选项。在对应目录下创建一个文件:
Kconfig
内容如下:
config LED
bool "Enable LED driver"
default y
help
This enables the LED driver support.
代码具体含义:
| 语句 | 作用 |
|---|---|
| config LED | 定义一个配置项,名字叫 LED(实际会变成 CONFIG_LED) |
| bool | 表示这是一个开关(yes/no) |
| “Enable LED driver” | 在 menuconfig 中显示的文字 |
| default y | 默认值为 yes |
| help | 下面是帮助信息,会在界面中显示 |
在 make menuconfig 中你就能看到:
[*] Enable LED driver
如果你取消这个选项,.config 文件就会去掉 CONFIG_LED=y。
二、不同类型的配置项
| 类型 | 说明 | 示例 |
|---|---|---|
| bool | 是/否 开关 | CONFIG_FOO=y |
| tristate | 支持三种:y(编进内核)/ m(作为模块)/ n(关闭) | CONFIG_USB=m |
| string | 字符串 | CONFIG_PATH=“/dev/ttyUSB0” |
| int | 整数 | CONFIG_NUM=4 |
| hex | 十六进制数 | CONFIG_MASK=0xFF |
最常用的其实只有 bool 和 tristate。
三、控制依赖关系(depends on)
如果 LED 驱动必须依赖 GPIO,你可以这样写:
config LED
bool "Enable LED driver"
depends on GPIO
help
LED needs GPIO support.
具体含义是:
只有当 CONFIG_GPIO=y 时,才会出现 LED 的选项。否则 menuconfig 里这个选项会被隐藏。
四、控制默认值(default)
有时候默认值取决于条件,比如:
config LED
bool "Enable LED driver"
default y if GPIO
default n
具体含义为:
如果 GPIO 被打开(CONFIG_GPIO=y),默认打开 LED;否则默认关闭。
五、强制打开其他选项(select)
有时你希望打开 A 时自动打开 B,比如:
config LED
bool "Enable LED driver"
select GPIO
具体含义是:
当用户选择 LED 时,系统自动设置 CONFIG_GPIO=y。
!!!注意:
select 是“强制打开”,不会检查依赖关系。如果 B 本身有条件(比如只在 ARM 平台上有效),用 select 可能会出错。
所以一般建议:
能用 depends on 的就不要用 select。
六、菜单与分组(menu / endmenu)
Kconfig 里可以做菜单分组,让配置界面更清晰:
menu "Device Drivers"
config GPIO
bool "GPIO Support"
config LED
bool "LED driver"
depends on GPIO
endmenu
效果如下:
Device Drivers --->
[*] GPIO Support
[*] LED driver
七、互斥选择(choice)
有时你只能选择一种实现,比如日志系统只能选一个:
choice
prompt "Select log system"
default LOG_UART
config LOG_UART
bool "Use UART for log"
config LOG_USB
bool "Use USB for log"
endchoice
效果如下:
Select log system --->
(X) Use UART for log
( ) Use USB for log
只能选一个。
八、条件语句(if / endif)
如果你想让一组选项在某个条件下才显示,可以用 if:
if NETWORK
config WIFI
bool "WiFi support"
config ETHERNET
bool "Ethernet support"
endif
只有当 CONFIG_NETWORK=y 时,这两项才会出现。
九、包含子目录(source)
Linux 内核 Kconfig 文件是层级结构的。比如在顶层 Kconfig 中包含子目录的 Kconfig:
source "drivers/Kconfig"
source "net/Kconfig"
这样 make menuconfig 就会自动加载这些子配置。
十、写完 Kconfig 后如何使用
在 Makefile 里,用配置变量控制编译:
obj-$(CONFIG_LED) += led.o
具体意思是:
(1)如果 CONFIG_LED=y,就把 led.o 编进内核;
(2)如果 CONFIG_LED=m,就编成模块;
(3)如果没选,什么都不编。
十一、一个完整的例子
1、假设你写了三个文件:
drivers/Kconfig
drivers/Makefile
drivers/led.c
(1)drivers/Kconfig内容为:
menu "Device Drivers"
config GPIO
bool "GPIO support"
default y
config LED
bool "LED driver"
depends on GPIO
default y
help
Simple LED driver that toggles GPIO.
endmenu
(2)drivers/Makefile内容为:
obj-$(CONFIG_LED) += led.o
然后在顶层 Kconfig 里加一句:
source "drivers/Kconfig"
(3)运行:
make menuconfig
就能看到菜单:
Device Drivers --->
[*] GPIO support
[*] LED driver
2、总结:写 Kconfig 三步走
(1)定义配置项
config XXX
bool "description"
(2)加依赖项
depends on OTHER
(3)Makefile 中使用
obj-$(CONFIG_XXX) += xxx.o
就这样,你已经能写一个完整的 Linux 内核驱动 Kconfig 了。
824

被折叠的 条评论
为什么被折叠?



