Kconfig、Makefile、.config 关系

Linux kernel 的目录结构下一般都会存在 Kconfig 和 Makefile 两个文件,分布在各级目录中的 Kconfig 构成了一个分布式的内核配置数据库。每个 Kconfig 分别描述了所属目录源文件相关的内核配置菜单。

在执行 make menuconfig 时,从 Kconfig 读出内核配置菜单,用户配置完后保存为 .config。

内核在编译时,主 Makefile 调用 .config,就知道用户对内核做了哪些配置。

简单来说:

Kconfig 是饭店菜单,Makefile 是菜谱,.config 是用户在菜单上的勾选。

make 这个自动炒菜机,挑选 .config 中勾选的菜,根据 Makefile 菜谱进行做菜,一切顺利的话,一道道菜肴就做好了。

Kconfig

构建内核的第一步始终是配置。Kconfig 有助于使内核高度模块化和定制化。Kconfig 为用户提供了许多配置目标:

preview

其中,menuconfig 是这些目标中最受欢迎的。一些目标有 GUI (为了方便用户),而大多数没有。与 Kconfig 相关的工具和源代码主要位于 scripts/kconfig/ 下。这里有几个主程序,包括 confmconfnconf。除了 conf 之外,每个都负责一个基于 GUI 的配置目标,因此,conf 处理大多数目标。

从逻辑上讲,Kconfig 的基础结构有两部分:一部分实现一种新语言 来定义配置项(参见内核源代码下的 Kconfig 文件),另一部分解析 Kconfig 语言并处理配置操作。

大多数配置目标具有大致相同的内部过程(如下所示):

img

请注意,所有配置项都具有默认值。

第一步读取源代码根目录下的 Kconfig 文件,构建初始配置数据库;然后它根据如下优先级读取现有配置文件来更新初始数据库:

  1. .config
  2. /lib/modules/$(shell,uname -r)/.config
  3. /etc/kernel-config
  4. /boot/config-$(shell,uname -r)
  5. ARCH_DEFCONFIG
  6. arch/$(ARCH)/defconfig

如果你通过 menuconfig 进行基于 GUI 的配置或通过 oldconfig 进行基于命令行的配置,则根据你的自定义更新数据库。最后,该配置数据库被转储到 .config 文件中。

Kbuild

组件式构建,称为递归 make,是 make 管理大型项目的常用方法。Kbuild 是递归 make 的一个很好的例子。

通过将源文件划分为不同的模块/组件,每个组件都由其自己的 makefile 管理。当开始构建时,顶级 makefile 以正确的顺序调用每个组件的 makefile,构建组件,并将它们收集到最终的执行程序中。

.config.old

.config.old 为上一次的 .config 的内容

参考

探索 Linux 内核:Kconfig/kbuild 的秘密

浅析Kbuild系统