LV085-Kconfig语法简介
一、Kconfig 语法简介
我们已经知道了 scripts/kconfig/mconf 会调用 uboot 根目录下的 Kconfig 文件开始构建图形化配置界面,接下来简单学习一下 Kconfig 的语法。因为后面学习 Linux 驱动开发的时候可能会涉及到修改 Kconfig,对于 Kconfig 语法我们不需要太深入的去研究,关于 Kconfig 的详细语法介绍,可以参考 linux 内核源码(不知为何 uboot 源码中没有这个文件)中的文件 Documentation/kbuild/kconfig-language.txt,本节我们大概了解其原理即可。打开 uboot 根目录下的 Kconfig,这个 Kconfig 文件就是顶层 Kconfig,我们就以这个文件为例来简单学习一下 Kconfig 语法。
1. mainmenu
mainmenu 就是主菜单,也就是输入“make ARCH = arm CROSS_COMPILE = arm-linux-gnueabihf- menuconfig”以后打开的默认界面,在顶层 Kconfig 中有如下代码:
mainmenu "U-Boot $UBOOTVERSION Configuration"上述代码就是定义了一个名为“U-Boot $UBOOTVERSION Configuration”的主菜单,其中 UBOOTVERSION = 2016.03,因此主菜单名为“U-Boot 2016.03 Configuration”,如图所示:

2. 调用其他目录下的 Kconfig 文件
和 makefile 一样, Kconfig 也可以调用其他子目录中的 Kconfig 文件,调用方法如下:
source "xxx/Kconfig"其中 xxx 为具体的目录名,相对路径,以 u-boot 源码顶层目录为根目录。在顶层 Kconfig 中有如下代码:
source "common/Kconfig"
source "cmd/Kconfig"
source "dts/Kconfig"
source "net/Kconfig"
source "drivers/Kconfig"
source "fs/Kconfig"
source "lib/Kconfig"
source "test/Kconfig"可以看出,顶层 Kconfig 文件调用了很多其他子目录下的 Kcofig 文件,这些子目录下的 Kconfig 文件在主菜单中生成各自的菜单项。
3. menu/endmenu 条目
menu 用于生成菜单, endmenu 就是菜单结束标志,这两个一般是成对出现的。在顶层 Kconfig 中有如下代码:

有两个 menu/endmenu 代码块,这两个代码块就是两个子菜单,第 14 行的“menu "General setup"”表示子菜单“General setup”。后边的的“menu "Boot images"”表示子菜单“Boot images”。体现在主菜单界面中就如上图所示了。
在“ General setup”菜单上面还有 “ Architecture select (ARM architecture)”和“ ARM architecture”这两个子菜单,但是在顶层 Kconfig 中并没有看到这两个子菜单对应的 menu/endmenu 代码块,那这两个子菜单是怎么来的呢?这两个子菜单就是 arch/Kconfig 文件生成的。包括主界面中的“Boot timing”、“Console recording”等等这些子菜单,都是分别由顶层 Kconfig 所调用的 common/Kconfig、 cmd/Kconfig 等这些子 Kconfig 文件来创建的。

4. config 条目
顶层 Kconfig 中的“General setup”子菜单内容如下:

可以看出,在 menu/endmenu 代码块中有大量的“config xxxx”的代码块,也就是 config 条目。 config 条目就是“General setup”菜单的具体配置项,如上图所示。“config LOCALVERSION”对应着第一个配置项,“config LOCALVERSION_AUTO”对应着第二个配置项,以此类推。我们以 “ config LOCALVERSION ” 和 “ config LOCALVERSION_AUTO”这两个为例来分析一下 config 配置项的语法:

第 16 和 26 行,这两行都以 config 关键字开头,后面跟着 LOCALVERSION 和 LOCALVERSION_AUTO,这两个就是配置项名字。假如我们使能了 LOCALVERSION_AUTO 这个功能,那么就会下.config 文件中生成 CONFIG_LOCALVERSION_AUTO,这个在上一小节学习如何使能 dns 命令的时候了解过了。由此可知, .config 文件中的“CONFIG_xxx” (xxx 就是具体的配置项名字)就是 Kconfig 文件中 config 关键字后面的配置项名字加上“CONFIG_”前缀。
config 关键字下面的这几行是配置项属性,17~24 行是 LOCALVERSION 的属性。27~44 行是 LOCALVERSION_AUTO 的属性。属性里面描述了配置项的类型、输入提示、依赖关系、帮助信息和默认值等。
第 17 行的 string 是变量类型,也就是“CONFIG_ LOCALVERSION”的变量类型。可以为:bool、 tristate、 string、 hex 和 int,一共 5 种。最常用的是 bool、 tristate 和 string 这三种。string 后面的“Local version - append to U-Boot release”就是这个配置项在图形界面上的显示出来的标题。
(1)bool 类型有两种值: y 和 n,当为 y 的时候表示使能这个配置项,当为 n 的时候就禁止这个配置项。如下图所示:
(2)tristate 类型有三种值: y、 m 和 n,其中 y 和 n 的涵义与 bool 类型一样, m 表示将这个配置项编译为模块,这种的在 linux 内核中使用较多。
(3)string 为字符串类型,所以 LOCALVERSION 是个字符串变量,用来存储本地字符串,选中以后即可输入用户定义的本地版本号,如下图:
第 18 行, help 表示帮助信息,告诉我们配置项的含义,当我们按下“h”或“?”弹出来的帮助界面就是 help 的内容。
第 27 行,说明“CONFIG_LOCALVERSION_AUTO”是个 bool 类型,可以通过按下 Y 或 N 键来使能或者禁止 CONFIG_LOCALVERSION_AUTO。
第 28 行,“default y”表示 CONFIG_LOCALVERSION_AUTO 的默认值就是 y,所以这一行默认会被选中。
5. depends on 和 select
打开 arch/Kconfig 文件,在里面有这如下代码:

第 9 行,“depends on”说明“SYS_GENERIC_BOARD”项依赖于“HAVE_GENERIC_BOARD”, 也就是说“HAVE_GENERIC_BOARD”被选中以后“ SYS_GENERIC_BOARD”才能被选中。
第 17~20 行,“select”表示方向依赖,当选中“ARC”以后, “HAVE_PRIVATE_LIBGCC”、 “HAVE_GENERIC_BOARD”、 “SYS_GENERIC_BOARD” 和 “SUPPORT_OF_CONTROL” 这四个也会被选中。
6. choice/endchoice
在 arch/Kconfig 文件中有如下 choice ... endchoice 代码:
choice
prompt "Architecture select"
default SANDBOX
#...
endchoicechoice/endchoice 代码段定义了一组可选择项,将多个类似的配置项组合在一起,供用户单选或者多选。上图中的代码就是选择处理器架构,可以从 ARC、 ARM、 AVR32 等这些架构中选择,这里是单选。在 uboot 图形配置界面上选择“Architecture select”,进入以后如图

可以在图中通过移动光标来选择所使用的 CPU 架构。第 12 行的 prompt 给出这个 choice/endchoice 段的提示信息为“Architecture select”。
7. menuconfig
menuconfig 和 menu 很类似,但是 menuconfig 是个带选项的菜单,其一般用法为:
menuconfig MODULES
bool "菜单"
if MODULES
# ...
endif # MODULES第 1 行,定义了一个可选的菜单 MODULES,只有选中了 MODULES 第 3~5 行 if 到 endif 之间的内容才会显示。在顶层 Kconfig 中有如下代码:

第 74~99 行使用 menuconfig 实现了一个菜单,路径如下:
General setup
[*] Configure standard U-Boot features (expert users) --->
从图可以看到,前面有“[ ]”说明这个菜单是可选的,当选中这个菜单以后就可以进入到子选项中,也就是图示代码中的第 83~99 行所描述的菜单,如下所示:

如果不选择“Configure standard U-Boot features (expert users)”,那么图示代码中的第 83~99 行所描述的菜单就不会显示出来,进去以后是空白的。

8. comment
comment 用于注释,也就是在图形化界面中显示一行注释,打开文件 drivers/mtd/nand/Kconfig,有如下所示代码:

右侧的路径为【→ Device Drivers → NAND Device Support】,可以看出,在配置项“Configure Arasan Nand”下面有一行注释,注释内容为“*** Generic NAND options ***”。
9. source
source 用于读取另一个 Kconfig,比如:
source "arch/Kconfig"基本上常用的语法就是这些,因为 uboot 相比 Linux 内核要小很多,所以配置项也要少很多,所以使用 uboot 来学习 Kconfig。一般不会修改 uboot 中的 Kconfig 文件,甚至都不会使用 uboot 的图形化界面配置工具,本小节学习 Kconfig 的目的主要还是为了 Linux 内核作准备。
三、自定义一个菜单
这里就不写详细过程了,可以看代码仓库:feat: 添加自定义菜单(Kconfig 语法学习) · 3e4bb1d · linux-dev-org/imx6ull-uboot - Gitee.com。最终的效果过如下:


