50

I can use the following command to create a Linux kernel .config file based on a specified architecture default for a custom ARM-based board:

ARCH=arm make defconfig KBUILD_DEFCONFIG=var_som_mx6_android_defconfig

I thought that this command more or less copies ./arch/arm/configs/var_som_mx6_android_defconfig to ./.config. However the resulting .config file isn't exactly a copy:

$ 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

I don't understand where the extra lines are coming from, and I have always found the internal workings of the kernel configuration, makefiles, and build scripts to be difficult to understand. Can anyone explain where those lines in the .config might be coming from?

Sam Protsenko
  • 14,045
  • 4
  • 59
  • 75
Michael Burr
  • 333,147
  • 50
  • 533
  • 760

2 Answers2

85

Motivation

The .config file is not simply copied from your defconfig file. The motivation for storing defconfig in such a format is next: in defconfig we can specify only options with non-default values (i.e. options we changed for our board). This way we can keep it small and clear. Every new kernel version brings a bunch of new options, and this way we don't need to update our defconfig file each time the kernel releases. Also, it should be mentioned that kernel build system keeps very specific order of options in defconfig file, so it's better to avoid modifying it by hand. Instead you should use make savedefconfig rule.

Simplified explanation

When .config file is being generated, kernel build system goes through all Kconfig files (from all subdirs), checking all options in those Kconfig files:

  • if option is mentioned in defconfig, build system puts that option into .config with value chosen in defconfig
  • if option isn't mentioned in defconfig, build system puts that option into .config using its default value, specified in corresponding Kconfig

Check scripts/kconfig/Makefile and scripts/kconfig/conf.c files to see how it's actually done.

More precise and detailed explanation

From "Kbuild: the Linux Kernel Build System" by Javier Martinez:

Defining Configuration Symbols: Kconfig Files

Configuration symbols are defined in files known as Kconfig files. Each Kconfig file can describe an arbitrary number of symbols and can also include (source) other Kconfig files. Compilation targets that construct configuration menus of kernel compile options, such as make menuconfig, read these files to build the tree-like structure. Every directory in the kernel has one Kconfig that includes the Kconfig files of its subdirectories. On top of the kernel source code directory, there is a Kconfig file that is the root of the options tree. The menuconfig (scripts/kconfig/mconf), gconfig (scripts/kconfig/gconf) and other compile targets invoke programs that start at this root Kconfig and recursively read the Kconfig files located in each subdirectory to build their menus. Which subdirectory to visit also is defined in each Kconfig file and also depends on the config symbol values chosen by the user.

Storing Symbol Values: .config File

All config symbol values are saved in a special file called .config. Every time you want to change a kernel compile configuration, you execute a make target, such as menuconfig or xconfig. These read the Kconfig files to create the menus and update the config symbols' values using the values defined in the .config file. Additionally, these tools update the .config file with the new options you chose and also can generate one if it didn't exist before.

Because the .config file is plain text, you also can change it without needing any specialized tool. It is very convenient for saving and restoring previous kernel compilation configurations as well.

Useful commands

You can use simpler syntax for make defconfig, like:

$ make ARCH=arm your_board_defconfig

See the full list of available defconfigs with:

$ make ARCH=arm help | grep defconfig

If you need to do reverse action (i.e. create a neat small defconfig from extensive .config), you can use savedefconfig rule:

$ make ARCH=arm savedefconfig

Also, as 0andriy mentioned, you can use diffconfig script to see changes from one .config to another one:

$ scripts/diffconfig .config_old .config_new
Sam Protsenko
  • 14,045
  • 4
  • 59
  • 75
  • 1
    Thanks for this great answer (and the link to an article that I'm surprised I didn't come across already). While waiting for some replies I had already figured that the additional lines came from validating the config through the Kconfig files, but this answer gives me so much more information and better understanding. Thanks again. – Michael Burr Jan 27 '17 at 19:30
  • So in short, `make defconfig KBUILD_DEFCONFIG=var_som_mx6_android_defconfig` is the same as `make var_som_mx6_android_defconfig`, and so you basically never want to use `make defconfig` as it is more verbose. – Ciro Santilli OurBigBook.com Jun 27 '18 at 07:55
  • I've received a pre-configured kernel tarball. On untarring and examining the `.config` file, I can see it was targetted at the vexpress board. However is there a `make` way to check which exact defconfig was it configured with? – AjB Jan 03 '19 at 06:35
  • @HighOnMeat You can use `scripts/diffconfig` with `-m` option to compare your `.config` file with each defconfig file from `arch/arm/configs/` directory (if your architecture is ARM32). Or you can use `make savedefconfig` rule to obtain `defconfig` file from your `config`, and then compare it with each defconfig using `diff` tool. Using `diffconfig` script is probably a better idea, as some defconfig files could be out of sync, as compared to `make savedefconfig` output. I don't know any automatic way to tell which defconfig was used originally, but it's not too hard to come up with one. – Sam Protsenko Jan 03 '19 at 14:00
  • @SamProtsenko so this means this script can be embedded inside of another bash script to do the grunt work. We do not want to do this manually. I believe this script can be called from such a bash script right? – AjB Jan 04 '19 at 00:32
  • @HighOnMeat The point is, you can change the kernel whatever you like, it can work in many ways. But it will be only your local changes on top of kernel. Ideally you should do that in upstreamable way, and actually upstream it. And what is the right way that will satisfy everyone -- it's entirely another question. Btw, I think it's better to actually ask i on SO as a separate question :) – Sam Protsenko Jan 04 '19 at 18:41
  • "if option isn't mentioned in defconfig, build system puts that option into .config using its default value, specified in corresponding Kconfig" But it looks like for some options no default value is specified in Kconfig. – xiaokaoy Aug 14 '20 at 03:36
  • @xiaokaoy If there is no default specified, it's `n` (default's default). Please see documentation for details: https://www.kernel.org/doc/html/latest/kbuild/kconfig-language.html – Sam Protsenko Aug 15 '20 at 09:30
  • @xiaokaoy "But it looks like some options are not specified in Kconfig" -- can you provide some example please? – Sam Protsenko Aug 15 '20 at 09:32
  • Thanks. There was some typo in my first comment. Just ignore it. I didn't know I could delete it. Sorry about that. I've just removed it. Your answer is great. – xiaokaoy Aug 15 '20 at 11:11
3

It also generates include/generated/autoconf.h.

This header file is included by C source files. On the other hand, .config is for the Makefile system.

The build system generates two files, and keeps them consistent.

Lorraine
  • 1,189
  • 14
  • 30
liuyang1
  • 1,575
  • 1
  • 15
  • 23