Linux 内核的"make defconfig"到底是做什么的?



我可以使用以下命令为自定义基于ARM的板创建基于指定体系结构默认值的Linux内核.config文件:

ARCH=arm make defconfig KBUILD_DEFCONFIG=var_som_mx6_android_defconfig

我认为这个命令或多或少会将./arch/arm/configs/var_som_mx6_android_defconfig复制到./.config。然而,生成的.config文件并不完全是一个副本:

$ diff --unified arch/arm/configs/var_som_mx6_android_defconfig  .config
--- arch/arm/configs/var_som_mx6_android_defconfig  2017-01-20 12:10:51.891515984 -0800
+++ .config 2017-01-26 15:31:29.000000000 -0800
@@ -407,6 +407,7 @@
CONFIG_ARM_ERRATA_751472=y
CONFIG_ARM_ERRATA_794072=y
CONFIG_ARM_ERRATA_761320=y
+CONFIG_ARM_ERRATA_845369=y
# CONFIG_ARM_ERRATA_753970 is not set
CONFIG_ARM_ERRATA_754322=y
# CONFIG_ARM_ERRATA_754327 is not set
@@ -2683,7 +2684,6 @@
CONFIG_AUTOFS4_FS=y
CONFIG_FUSE_FS=y
# CONFIG_CUSE is not set
-CONFIG_AUFS_FS=y
#
# Caches
@@ -2759,6 +2759,21 @@
# CONFIG_PSTORE is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
+CONFIG_AUFS_FS=y
+CONFIG_AUFS_BRANCH_MAX_127=y
+# CONFIG_AUFS_BRANCH_MAX_511 is not set
+# CONFIG_AUFS_BRANCH_MAX_1023 is not set
+# CONFIG_AUFS_BRANCH_MAX_32767 is not set
+CONFIG_AUFS_SBILIST=y
+# CONFIG_AUFS_HNOTIFY is not set
+# CONFIG_AUFS_RDU is not set
+# CONFIG_AUFS_PROC_MAP is not set
+# CONFIG_AUFS_SP_IATTR is not set
+# CONFIG_AUFS_SHWH is not set
+# CONFIG_AUFS_BR_RAMFS is not set
+# CONFIG_AUFS_BR_FUSE is not set
+CONFIG_AUFS_BDEV_LOOP=y
+# CONFIG_AUFS_DEBUG is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y

我不明白额外的行是从哪里来的,我总是发现内核配置、makefile和构建脚本的内部工作很难理解。有人能解释一下.config中的这些线条可能来自哪里吗?

动机

.config文件不是简单地从defconfig文件中复制的。以这种格式存储defconfig的动机是:在defconfig中,我们只能指定具有非默认值的选项(即我们为董事会更改的选项)。这样我们就可以保持它的小而清晰。每个新的内核版本都会带来一堆新的选项,这样我们就不需要在每次内核发布时更新defconfig文件。此外,需要注意的是,内核构建系统在defconfig文件中保留了非常特定的选项顺序,因此最好避免手动修改。相反,您应该使用make savedefconfig规则。

简化说明

当生成.config文件时,内核构建系统会遍历所有Kconfig文件(来自所有子目录),检查这些Kconfig文件中的所有选项:

  • 如果在defconfig中提到选项,则构建系统将该选项放入.config中,并在defconfig中选择值
  • 如果defconfig中没有提到该选项,则构建系统会使用相应的Kconfig中指定的默认值将该选项放入.config

检查脚本/kconfig/Makefile和脚本/kconfig/conf.c文件,看看它是如何实际完成的。

更精确、更详细的解释

从";Kbuild:Linux内核构建系统";哈维尔·马丁内斯:

定义配置符号:Kconfig文件

配置符号在称为Kconfig文件的文件中定义。每个Kconfig文件可以描述任意数量的符号,并且还可以包括(源)其他Kconfig文件。构造内核编译选项的配置菜单的编译目标,如make menuconfig,读取这些文件以构建树状结构。内核中的每个目录都有一个Kconfig,其中包括其子目录的Kconfig文件。在内核源代码目录的顶部,有一个Kconfig文件,它是选项树的根。menuconfig(scripts/kconfig/mconf)、gconfig(scripts/kconfig/gconf)和其他编译目标调用从该根Kconfig开始的程序,并递归地读取位于每个子目录中的Kconfig文件以构建它们的菜单。访问哪个子目录也在每个Kconfig文件中定义,也取决于用户选择的配置符号值。

存储符号值:.config文件

所有配置符号值都保存在一个名为.config的特殊文件中。每次想要更改内核编译配置时,都要执行一个make目标,例如menuconfigxconfig。这些读取Kconfig文件以创建菜单,并使用.config文件中定义的值更新配置符号的值。此外,这些工具使用您选择的新选项更新.config文件,如果以前不存在,也可以生成一个。

因为.config文件是纯文本的,所以您也可以在不需要任何专用工具的情况下对其进行更改。它也非常方便地保存和恢复以前的内核编译配置。

有用的命令

您可以对make defconfig使用更简单的语法,如:

$ make ARCH=arm your_board_defconfig

查看可用defconfigs的完整列表:

$ make ARCH=arm help | grep defconfig

如果你需要做反向操作(即从大量的.config创建一个整洁的小defconfig),你可以使用savedefconfig规则:

$ make ARCH=arm savedefconfig

此外,正如0andry所提到的,您可以使用diffconfig脚本查看从一个.config到另一个的更改:

$ scripts/diffconfig .config_old .config_new

它还生成include/generated/autoconf.h

这个头文件包含在C源文件中。另一方面,.config用于Makefile系统。

构建系统生成两个文件,并保持它们的一致性。

最新更新