目录结构中,某一层的内容无非就是,要么全是目录,要么全是文件,要么既有目录又有文件,我们的Kconfig文件通常是分布在各级目录中。那么,这些Kconfig如何一层一层地去组织起来呢?
首先明确下,什么时候需要Kconfig呢?在某个层级中的文件需要用CONFIG_XX_XX宏来控制的时候,就可以在该层级下写一个Kconfig。我们知道,Kconfig是从上到下层层调用的,所以,我们每写一个Kconfig,都需要将其和上层的Kconfig给关联起来。
举例:linux/drivers/i2c
就以linux/drivers/i2c这个驱动目录为例
向上,它有drivers这一层
向下,也有几个目录加一些文件
每个层级下,都有一个Kconfig
我们从最底层开始分析,所以,先分别进入algos目录、busses目录以及muxes目录查看对应的Kconfig。
注意,我们查看或者写Kconfig时,不需要关注里面有哪些文件,只需要关注当前目录下这些文件里需要使用到哪些配置项即可,所以,一般是一边写程序一边完善Kconfig文件。如果不需要用到任何配置项,那压根就不需要Kconfig。不过一般都是需要的,因为通常同目录下的Makefile都需要用对应的配置项来进行条件编译,所以Makefile一般都是和Kconfig一起出现的。
↓algos目录
其中,一个config就表示一个配置项,其语法如下所示:
其中,配置项名、配置项类型、配置项提示语是必选的,其他选项按需选择。
配置项提示语以prompt开头,后跟一个空格字符,然后就是用双引号包围的文字提示语。作用就是在menuconfig图形界面中作为配置项的提示语。所以,不要以为我们界面上看到的就是配置项,其实不是的,真正显示的是提示语,而最终写到.config里的,是CONFIG_配置项名,配置项类型决定的是当前宏定义可以赋予什么类型的值。
另外,配置项提示语其实可以和类型合并在一起从而省略 prompt 关键字。以下示例中的两个配置效果是等价的:
config KCONFIG_DEMO_ITEM1boolprompt "demonstate item1"config KCONFIG_DEMO_ITEM2bool "demonstate item2"
所以,上述algos目录中的Kconfig里其实就是最简单的几个配置项。
除了config配置项,还有一个menu和endmenu,这是啥?
menu 就是一个纯粹的菜单项,menu本身不可配置,只是用来标记其内部可能拥有子配置项,menu项最后在.config中会将菜单提示语作为注释一并写入。
↓busses目录
这个目录下的Kconfig配置项很多,不过,结构也是一个menu加很多config的形式。
↓muxes目录
好了,这个目录下的Kconfig也是类似的。
.i2c目录
再接着上一层,看看i2c目录下的Kconfig
大体上,也是menu加上好多config配置项。
不过,除了这一层文件用到的配置项,还因为这层目录下面有三个子目录,每个子目录里都有一个Konfig,而menuconfig界面展示各个配置项的时候是从顶层开始从上往下一层一层地展开,所以,必然要将这层的Kconfig和下层目录的Kconfig关联起来,为了完成这个关联,就要在这层目录的Kconfig里导入下一层目录里的Kconfig,比如
这里用到source模块
source条目用于读取另一个Kconfig文件,一般都是上级目录中的Kconfig包含下级目录中的Kconfig,从而形成层级结构,在menuconfig的体现就是菜单展开,稍后展示i2c这个目录的总体menuconfig效果。
↑dirvers目录
我们再往上看一层,看看dirvers这层目录里的Kconfig是什么样的。
这一层没有任何配置项,全是source导入,也就是说,这一层没有专用于该层的一些配置项。
这里要注意,这一层虽然没有源文件或者头文件,几乎全是子目录,但是有Makefile文件,Makefile里用到了很多配置项,比如:
这些配置项,虽然没有在这一层的Kconfig里定义,但并不是不能用,只是并不是这一层专用的罢了。
事实上,这里有个容易误解的地方,以为每一层只能使用这一层的Kconfig定义的配置项,其实不是的,我们在各层定义各层专用的配置项,只是出于模块化的考虑,实际上,各层定义的所有配置项,最终都会统一保存到.config中去,我们所使用的也是.config文件里的带CONFIG_前缀的配置项,linux已经在顶层Makefile中导入了.config,所以可以看做是全局的配置项,我们在任何地方都能引用。这一点一定要注意。
根据上面的分析可知,每一层其实都只用管本层的配置项以及下一层Kconfig的导入,下一层如果再有子目录里的Kconfig,那也是下一层Kconfig的事情了,不是你本层Kconfig要管的。按此逻辑依次展开。
↑↑顶层目录
反正都分析到这里了,我们不妨再往上一层,看看顶层Kconfig的内容,按照常理,里面应该是所有下一级目录的导入吧?看看吧
看起来并不是,只是为啥?
并没有导入所有子目录里的Kconfig,而只是导入了arch/$SRCARCH/Kconfig这个目录,其实source引用的是绝对路径,我们可以链接到任意的路径下的Kconfig,只是,我们最终需要将所有需要的Kconfig个贯穿起来。
其中,mainmenu 是主菜单项。它用于定义在图形化配置界面中显示的主菜单名称。当输入“make menuconfig”命令后,打开的默认界面就是由 mainmenu 定义的。
mainmenu
关键字表示这是一个主菜单项,其后引号内的内容"Linux/$ARCH $KERNELVERSION Kernel Configuration"
则是菜单的名称。其中$ARCH
和$KERNELVERSION
是变量,它们会在具体的环境中被替换为相应的值,例如处理器架构(如 ARM)和内核版本(如5.10.0
)。mainmenu 通常出现在 Kconfig 文件的最顶部,用于设置整个配置界面的主题名称。
这里的配置项会根据我们的配置,然后source不同架构的Kconfig,我们以ARM为例,进去看看ARM架构下的Kconfig,不同的架构需要不同的配置项。
这里面的内容很多
有很多ARM架构需要的配置项以及需要导入的所有目录下的Kconfig
整个逻辑其实是顶层的Kconfig跳到架构下的Kconfig,再跳到各个顶层目录下。
对应的menuconfig
上面的思路是自底向上来分析的,但实际menuconfig是从顶层自上而下逐层展开的。
OK,我们就顺着这个思路从上到下看看实际menuconfig是不是跟我们上面分析的一样吧。
linux下切到源码顶层,输入make menuconfig,打开menuconfig界面
红框里标题对应着顶层的Kconfig
然后看主页面的菜单
这是从哪开始的?
根据界面标题可知,这里用的是x86的架构,所以,去arch/x86下找到对应的Kconfig
待补充。。。