What exactly does Linux kernel’s `make defconfig` do?
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?
2 Answers 2
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
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
Linux build config file
NAME
config — build system configuration files
SYNOPSIS
config [-CVgp] [-d destdir] SYSTEM_NAME config [-x kernel]
DESCRIPTION
The config utility builds a set of system configuration files from the file SYSTEM_NAME which describes the system to configure. A second file tells config what files are needed to generate a system and can be augmented by configuration specific set of files that give alternate files for a specific machine (see the FILES section below). Available options and operands: -V Print the config version number. -C If the INCLUDE_CONFIG_FILE is present in a configuration file, kernel image will contain full configuration files included literally (preserving comments). This flag is kept for backward compatibility. -d destdir Use destdir as the output directory, instead of the default one. Note that config does not append SYSTEM_NAME to the directory given. -m Print the MACHINE and MACHINE_ARCH values for this kernel and exit. -g Configure a system for debugging. -x kernel Print kernel configuration file embedded into a kernel file. This option makes sense only if options INCLUDE_CONFIG_FILE entry was present in your configuration file. -p Configure a system for profiling; for example, kgmon(8) and gprof(1). If two or more -p options are supplied, config configures a system for high resolution profiling. SYSTEM_NAME Specify the name of the system configuration file containing device specifications, configuration options and other system parameters for one system configuration. The config utility should be run from the conf subdirectory of the system source (usually /sys/ARCH/conf), where ARCH represents one of the architectures supported by FreeBSD. The config utility creates the directory ../compile/SYSTEM_NAME or the one given with the -d option as necessary and places all output files there. The output of config consists of a number of files; for the i386, they are: Makefile, used by make(1) in building the system; header files, definitions of the number of various devices that will be compiled into the system. After running config, it is necessary to run “make depend” in the directory where the new makefile was created. The config utility prints a reminder of this when it completes. If any other error messages are produced by config, the problems in the configuration file should be corrected and config should be run again. Attempts to compile a system that had configuration errors are likely to fail.
DEBUG KERNELS
Traditional BSD kernels are compiled without symbols due to the heavy load on the system when compiling a “debug” kernel. A debug kernel contains complete symbols for all the source files, and enables an experienced kernel programmer to analyse the cause of a problem. The debuggers available prior to 4.4BSD-Lite were able to find some information from a normal kernel; gdb(1) provides very little support for normal kernels, and a debug kernel is needed for any meaningful analysis. For reasons of history, time and space, building a debug kernel is not the default with FreeBSD: a debug kernel takes up to 30% longer to build and requires about 30 MB of disk storage in the build directory, compared to about 6 MB for a non-debug kernel. A debug kernel is about 11 MB in size, compared to about 2 MB for a non-debug kernel. This space is used both in the root file system and at run time in memory. Use the -g option to build a debug kernel. With this option, config causes two kernel files to be built in the kernel build directory: · kernel.debug is the complete debug kernel. · kernel is a copy of the kernel with the debug symbols stripped off. This is equivalent to the normal non-debug kernel. There is currently little sense in installing and booting from a debug kernel, since the only tools available which use the symbols do not run on-line. There are therefore two options for installing a debug kernel: · “make install” installs kernel in the root file system. · “make install.debug” installs kernel.debug in the root file system.
FILES
/sys/conf/files list of common files system is built from /sys/conf/Makefile.ARCH generic makefile for the ARCH /sys/conf/files.ARCH list of ARCH specific files /sys/ARCH/compile/SYSTEM_NAME default kernel build directory for system SYSTEM_NAME on ARCH.
SEE ALSO
config(5) The SYNOPSIS portion of each device in section 4. Building 4.3 BSD UNIX System with Config.
HISTORY
The config utility appeared in 4.1BSD. Before support for -x was introduced, options INCLUDE_CONFIG_FILE included entire configuration file that used to be embedded in the new kernel. This meant that strings(1) could be used to extract it from a kernel: to extract the configuration information, you had to use the command: strings -n 3 kernel | sed -n 's/^___//p'
BUGS
The line numbers reported in error messages are usually off by one.
© 2019 Canonical Ltd. Ubuntu and Canonical are registered trademarks of Canonical Ltd.