一、简介
menuconfig是Linux平台用于管理代码工程、模块及功能的实用工具。上至决定某一程序模块是否编译,下到某一行具体的代码是否需要编译以及某个项的值在本次编译时该是什么都可由menuconfig来定义。
menuconfig的使用方式通常是在编译系统之前在系统源代码根目录下执行 make menuconfig 命令从而打开一个图形化配置界面,再通过对各项的值按需配置从而达到影响系统编译结果的目的。一个典型的 menuconfig 配置界面如下图所示:
menuconfig 配置后的结果将会保存在对应模块根目录下的 .config 文件中。如kernel源码根目录或应用程序源码根目录。Linux在编译系统镜像时会加载这些 .config 文件中的配置项来决定编译结果。
menuconfig 其实只能算是一个“前端”,用于支撑它、决定它拥有什么配置项的“后端”则被称为 Kconfig。
Kconfig 严格来讲是一种编程语言,它拥有自己的语法及结构。正是这些语法和结构组成了menuconfig在用户眼前不同的表现形式。
不过幸好,Kconfig这门“编程语言”的内容很少,通常只需花上半个小时就能掌握大半了。而这篇博文主要也是在介绍Kconfig的知识。
总得来说,menuconfig是Linux平台基于Kconfig用于管控代码实用工具。
二、常用的Kconfig语法
Kconfig的语法及代码结构非常简单。本博文只介绍Kconfig中常用的几个知识点。更详尽的内容可以参阅Linux官方提供的帮助文档。这份文档们于内核源码目录下的 ./Document/kbuild/kconfig-language.txt 。本文也已将此文档作为附件贴在文末了。
所谓 Kconfig,其实就是一个位于要被控制的程序模块源码目录下的文件名为 Kconfig 的普通的文本文件而已。
Kconfig文件在Linux系统中的数量是不确定的。我们既可以将所有配置项写在一个Kconfig文件上,又可以分模块分功能将它们分别写在不同的Kconfig文件中。一般来讲,都是在各个程序或模块的根目录下创建一个Kconfig用于记录所有配置该程序/模块的配置项。然后再在其父级目录的Kconfig中通过 souce code_demo/Kconfig 的形式将其引入到menuconfig系统中去。
Kconfig常用的几个知识点有以下五个:
1、config模块
2、menuconfig模块
3、menu模块
4、choice模块
5、if 与 depends on 模块
2.1、config模块
config模块是Kconfig最基础最重要的知识点。一个config就表示一个配置项。其语法如下所示:
config 配置项名 配置项类型 配置项提示语 其它选项
配置项名表示最终保存在 .config 文件中的键值对项的键名,通常用全大写和单词之间以下划线隔开的形式书写。
配置项类型就是基础类型,可选的类型有:bool、tristate、string、hex、int。
bool 表示布尔型在.config中以 y 和 n 表示。
tristate是三态类型,通常用在内核驱动控制中。在.config中以 y 、n和m表示。y表示将驱动编译进内核镜像,n表示不编译,m表示将驱动编译为ko形式。
string是普通字符串类型,直接将在menuconfig图形界面中用户输入的值原样保存在.config中。
hex是十六进制形式,只能输入0~F的内容。
int是十进制整数形式,只能输入数字。
配置项提示语以prompt开头,后跟一个空格字符,然后就是用双引号包围的文字提示语。作用就是在menuconfig图形界面中作为配置项的提示语。如下图所示:
其它选项这里暂且不管。
下面我们尝试编写一个包含了 config 内容的Kconfig。
在目录menu_demo下新建一个Kconfig文件,内容如下所示:
config KCONFIG_DEMO_ITEM1
bool
prompt "demonstate item1 for bool learning"
config KCONFIG_DEMO_ITEM2
string
prompt "demonstate item2 for string learning"
config KCONFIG_DEMO_ITEM3
hex
prompt "demonstate item3 for hex learning"
然后再其父目录上的Kconfig中将此Kconfig文件加载进来:
#
# For a description of the syntax of this configuration file,
# see scripts/kbuild/config-language.txt.
#
mainmenu "Users Configuration"
# menu "Applications Settings"
source "menu_demo/Kconfig"
然后在系统源码根目录下执行 make menuconfig 后即可看到我们刚添加进去的几个配置项了,如下图所示:
如果配置项是 bool、tristate 类型,则通过空格键来切换它们的选项值。其它类型值则通过回车键打开输入框来键入对应的值完成配置。
这里我们将第一项选上,第二项随意输入一个字符串,第三项留空,然后一路退出menuconfig并保存,可以看到.config文件关于我们新增的配置项的内容如下所示:
root@ubuntu:~/workspace/rtl8197/rtl819x# head -n 20 users/.config
#
# Automatically generated make config: don't edit
# RLX Linux builder
# Wed Jun 30 21:20:58 2021
#
CONFIG_KCONFIG_DEMO_ITEM1=y
CONFIG_KCONFIG_DEMO_ITEM2="hello world"
CONFIG_KCONFIG_DEMO_ITEM3=
此即为最基础的配置方式。
2.2、menuconfig模块
menuconfig可以认为是上一节 config 中的升级版。
首先它自己也是一个正常的配置项,通过自己的配置值来决定另外一组配置项是否作为子菜单的形式显示出来并供用户配置。具体语法如下所示:
1 menuconfig KCONFIG_DEMO_MENUCONFIG1
2 bool
3 prompt "menuconfig learning"
4
5 if KCONFIG_DEMO_MENUCONFIG1
6
7 config MENUCONFIG_SUBITEM1
8 bool
9 prompt "menuconfig subitem1"
10
11 config MENUCONFIG_SUBITEM2
12 bool
13 prompt "menuconfig subitem2"
14
15 endif
第一行通过menuconfig配置了一个bool类型的配置项。第五行的if语句暂且不深究,只需要知道它的作用是当第一行的配置项被选中时会将if/endif之内的配置项作为 KCONFIG_DEMO_MENUCONFIG1 项的子配置项显示即可。
此配置项在menuconfig中的显示效果及其菜单内部的显示效果如下面两张图所示:
此时我们选中menuconfig配置项,其子菜单内部的效果如下图所示:
2.3、menu模块
如果说上一节的menuconfig是一个带了菜单功能的配置项,那么这个 menu 就是一个纯粹的菜单项了。menu本身不可配置,只是用来标记其内部可能拥有子配置项。
以下是示例语法:
menu "menu learning"
config MENU_SUBITEM1
bool
prompt "subitem1"
config MENU_SUBITEM2
bool
prompt "subitem2"
config MENU_SUBITEM3
bool
prompt "subitem3"
endmenu
对应的menuconfig显示效果如下图所示:
menu项在.config中会将菜单提示语作为注释一并写入,如下所示:
root@ubuntu:~/workspace/rtl8197/rtl819x# head -n 20 users/.config
#
# Automatically generated make config: don't edit
# RLX Linux builder
# Wed Jun 30 21:45:28 2021
#
#
# menu learning
#
CONFIG_MENU_SUBITEM1=y
# CONFIG_MENU_SUBITEM2 is not set
# CONFIG_MENU_SUBITEM3 is not set
2.4、choice模块
choice是单选模块。具体语法如下所示:
choice
bool
prompt "choice learning"
config CHOICE_ITEM1
bool
prompt "choice1"
config CHOICE_ITEM2
bool
prompt "choice2"
config CHOICE_ITEM3
bool
prompt "choice3"
endchoice
在menuconfig中的显示效果如下图所示:
2.5、if与depends on模块
if 与 depends on 模块都属于 config 配置项中的”其它选项“。
它们的作用是等价的,都是根据指定的配置项是否被配置来决定本配置项的显示与否。
它们的语法如下所示:
config MY_CONFIG1
bool
prompt "my config1"
config MY_CONFIG2
bool
prompt "my config2" if MY_CONFIG1
config MY_CONFIG3
bool
prompt "my config3"
depends on MY_CONFIG2
此配置项表示当第一个配置项为y时,就可以配置第二个配置项,当第二个配置项为y时,才能够配置第三个配置项。其效果如下图所示:
选中第一项,效果如下图所示:
选中第二项,效果如下图所示:
2.6、其它知识点
1、
配置项提示语其实可以和类型合并在一起从而省略 prompt 关键字。以下示例中的两个配置效果是等价的:
config KCONFIG_DEMO_ITEM1
bool
prompt "demonstate item1"
config KCONFIG_DEMO_ITEM2
bool "demonstate item2"
2、
配置项的其它选项中可以通过 default 关键字来配置选项的默认值,如:
config MY_CONFIG1
bool "my config1"
default y
3、
Kconfig中还有一个模块被称为 comment,其作用就是单纯的为在其之后的配置项添加注释说明。并且会将说明内容一并写进 .config 文件中。具体效果与上面 2.3 节menu模块的注释一样。其语法如下所示:
comment "I am a comment"
config MY_CONFIG1
bool
prompt "my config1"
config MY_CONFIG2
bool
prompt "my config2" if MY_CONFIG1
comment "I'm a comment2"
config MY_CONFIG3
bool
prompt "my config3"
depends on MY_CONFIG2
在menuconfig中的效果如下图所示:
在.config中的效果如下所示:
root@ubuntu:~/workspace/rtl8197/rtl819x# head -n20 users/.config
#
# Automatically generated make config: don't edit
# RLX Linux builder
# Wed Jun 30 22:03:01 2021
#
#
# I am a comment
#
CONFIG_MY_CONFIG1=y
CONFIG_MY_CONFIG2=y
#
# I'm a comment2
#
# CONFIG_MY_CONFIG3 is not set
4、
在配置项的其它选项中还有一个 help 关键字。它的作用是为配置项添加一个更详细的说明文档。用户在menuconfig图形配置界面通过 ? 键来唤出详细文档的展示。
其语法如下所示:
config MY_CONFIG1
bool
prompt "my config1"
help
I am a help document.
This document can be a long length
在menuconfig界面,将光标移动到my config1项上,然后通过 ? 键来唤出此帮助文档的展示窗口,如下图所示:
以上即是menuconfig与Kconfig中最常用的知识点的简要介绍了。更多完整详尽的知识请参阅附件贴出的官方文档。
官方文档下载链接: https://files.cnblogs.com/files/chorm590/kconfig-language.zip
Kconfig Language — The Linux Kernel documentation