Linux:了解Kconfig的基本语法,顺便在linux源码中添加自定义菜单选项

前言

其实不管在kernel还是其他项目,Kconfig文件给我们最直观的体验就是用于make menuconfig时的可视化配置。接下来主要可以分为两部分:了解Kconfig语法、添加自己的选项。如果想快速添加自己的菜单,那么可以直接跳过第1部分直接按照第2部的步骤来操作即可。

1、Kconfig简介

1.1 Kconfig与Makefile、.config的联系

在内核文档Documentation/kbuild/makefiles.txt中有介绍:

Makefile包含5部分:
  Makefile:顶层Makefile
  .config:内核配置文件
  arch/$(ARCH)/Makefile:CPU架构目录的Makefile
  scripts/Makefile.*:普通的kbuild、Makefiles规则
  kbuild Makefiles:等等文件
顶层Makefile会读取从内核配置的程序得到的.config文件。

现以i2c的配置为例看下三者的语法:

① drivers/i2c/Kconfig

config I2C
  tristate "I2C support"
  select RT_MUTEXES
  ---help---
    I2C (pronounce: I-squared-C) is a slow serial bus protocol used in
    ...

.config:(相比于Kconfig文件中的配置,可以看到I2C前面多了“CONFIG_”前缀)

CONFIG_I2C=y

③ drivers/i2c/Makefile:(根据“CONFIG_I2C”的值是“y”、“m”或“没被设置”来决定将源码的编译)

obj-$(CONFIG_I2C)   += i2c-core.o

相信从上面三者的语法可以很容易猜想到它们之间的联系,但具体是如何建立起联系的这里就不做研究了,简单了解即可。

1.2 make menuconfig 流程

既然使用了make命令,那么很理所当然地可以从Makefile文件查找目标,发现有如下定义:

%config: scripts_basic outputmakefile FORCE
	$(Q)$(MAKE) $(build)=scripts/kconfig $@

其中,以上使用的变量定义及所在文件如下:

# $(Q):顶层Makefile
ifeq ("$(origin V)", "command line")
  KBUILD_VERBOSE = $(V)
endif
ifndef KBUILD_VERBOSE
  KBUILD_VERBOSE = 0
endif

ifeq ($(KBUILD_VERBOSE),1)
  quiet =
  Q =
else
  quiet=quiet_
  Q = @
endif

# $(MAKE)
MAKE=make

# $(build):scripts/Kbuild.include
build := -f $(srctree)/scripts/Makefile.build obj

如果make时没有指定参数“V”,展开后就是:

%config: scripts_basic outputmakefile FORCE
	@ make -f ./scripts/Makefile.build obj=scripts/kconfig menuconfig

而在scripts/Makefile.build文件中又继续包含其他目录的文件:

src := $(obj)
...
kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src))
kbuild-file := $(if $(wildcard $(kbuild-dir)/Kbuild),$(kbuild-dir)/Kbuild,$(kbuild-dir)/Makefile)
include $(kbuild-file)

最后,在scripts/kconfig/Makefile就可以看到:

menuconfig: $(obj)/mconf
	$< $(silent) $(Kconfig)

将变量代替进去简化一下就是:

menuconfig: scripts/kconfig/mconf
	scripts/kconfig/mconf Kconfig

可以看到,最终就是scripts/kconfig/mconf这个可执行文件去解析Kconfig文件,它的源码(mconf.c等)就在同一个目录下。

1.3 内核中的Kconfig关键字

事实上,Kconfig是不需要我们自己从0开始写起,只需要大概了解语法,因为在使用时最多也就是需要添加某个菜单而已。Kconfig的语法可以从内核文档Documentation/kbuild/kconfig-language.txt中查看,这里就看看经常会碰到以下关键字:

1.3.1 菜单相关

  • mainmenu:顶部主菜单说明;
  • menu/endmenu:两者搭配使用,选项后面显示 “—>”,里面会再包含一系列的具体选项;
  • menuconfig:里面包含一系列的菜单,选项前面显示 “[ ]”,而且后面还显示 “ —>”。

1.3.2 选项相关

  • config:需要配置的选项,不需要加“CONFIG_”前缀;
  • tristate:三态:编进内核、编成模块、不编译;选项前面显示 “< >”;
  • bool:布尔型,只有选择或不选择,选项前面显示 “[ ]”;
  • int/hex:整型数值,选项前面显示 “( )”;
  • range:用于限定前面int/hex整型数值的取值范围,不在范围内无法设置成功,语法为“rang 最小值 最大值”;
  • string:设置字符串,选项前面显示 “( )”;
  • depends on:依赖的选项,只有依赖的选项被配置了,才能配置该选项,可以通过逻辑运算符“&&”、“||”或“!”取反配置多个选项;
  • default:默认取值;
  • select:当前选项被选中后,select对应的选项也同时被选中;
  • help:帮助信息,按下“?”键或选择“< Help >”菜单时的描述。

1.3.3 其他

  • source:执行其他目录下的Kconfig文件,如:source “arch/$SRCARCH/Kconfig”;
  • comment:注释,解析;选项前后显示“***”;

2、在make menuconfig中添加自己的选项

以最简单的驱动为例,把它归类到字符设备(根据自己需求),所以放到内核的drivers/char目录下,修改和添加的内容如下(如果没有特殊说明,都是在前面所说的drivers/char目录下操作):

2.1 先准备好自己的源码test.c

#include <linux/ide.h>
#include <linux/module.h>
#include <linux/cdev.h>
#include <linux/device.h>

static int __init test_init(void)
{
	printk("test_init!\n");
	return 0;
}

static void __exit test_exit(void)
{
	printk("test_exit!\n");
}

module_init(test_init);
module_exit(test_exit);

MODULE_LICENSE("GPL");

2.2 修改Kconfig

source "drivers/char/imx_amp/Kconfig"

# add
config TEST_DRV
  tristate "My test driver"
  help
    This is my test driver!

2.3 修改Makefile

obj-$(CONFIG_XILLYBUS)    += xillybus/

# add
obj-$(CONFIG_TEST_DRV) += test.o

2.4 查看效果

在这里插入图片描述
保存之后查看.config文件即可看到“CONFIG_TEST_DRV”选项是否被设置了。


以上为本人见解,如有错误,希望大家不吝赐教,感谢!

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

R-QWERT

你的鼓励是我最大的动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值