Kconfig

Kconfig (Kernel Config) is the system that configures the kernel options (which is a very important part on the build system). You can find the Kconfig file in the root directory and see it’s recursive approach:

# SPDX-License-Identifier: GPL-2.0
#
# For a description of the syntax of this configuration file,
# see Documentation/kbuild/kconfig-language.rst.
#
mainmenu "Linux/$(ARCH) $(KERNELVERSION) Kernel Configuration"

source "scripts/Kconfig.include"

source "init/Kconfig"

source "kernel/Kconfig.freezer"

[...]

By looking at for example the init/Kconfig file we see how Kconfig is used to define some “”macros“” based on system checks (for example the compiler):

[...]
config CC_IS_GCC
	def_bool $(success,test "$(cc-name)" = GCC)

config GCC_VERSION
	int
	default $(cc-version) if CC_IS_GCC
	default 0

config CC_IS_CLANG
	def_bool $(success,test "$(cc-name)" = Clang)
[...]

Or to define user-entered configurations:

config SECURITY
	bool "Enable different security models"
	depends on SYSFS
	depends on MULTIUSER
	help
	  This allows you to choose different security modules to be
	  configured into your kernel.

	  If this option is not selected, the default Linux security
	  model will be used.

	  If you are unsure how to answer this question, answer N.

We can see how the option is a plain boolean and depends on other configurations.

Then, by using cscope we can see how the macro is used during the code:

Text string: CONFIG_SECURITY

  File        Line
0 commoncap.c 1449 #ifdef CONFIG_SECURITY
1 commoncap.c 1485 #endif /* CONFIG_SECURITY */
2 inode.c      316 #ifdef CONFIG_SECURITY
3 inode.c      344 #ifdef CONFIG_SECURITY
[...]

By looking at commoncap.c:

#ifdef CONFIG_SECURITY

static struct security_hook_list capability_hooks[] __lsm_ro_after_init = {
	LSM_HOOK_INIT(capable, cap_capable),
	LSM_HOOK_INIT(settime, cap_settime),
	LSM_HOOK_INIT(ptrace_access_check, cap_ptrace_access_check),
	LSM_HOOK_INIT(ptrace_traceme, cap_ptrace_traceme),
[...]

The syntax it uses is it’s own, which can be consulted here1.

To configure each option defined in root’s Kconfig (which includes the rest), you just have to run make menuconfig to get the menu based configurator:

B6NgJZ.png

There are other versions such as GTK make gconfig or QT make xconfig or curses make nconfig. You can also “update” the current config with make oldconfig so new configuration values are prompted so you can choose.

Side note, there are other crazy configuration approaches:

And other more specific options

Once configured, the configuration will be stored in .config.

How can we add a new configuration? We’ll, if we created a new feature or we need some system checks, we can just follow the syntax from Kconfig and add it in the corresponding Kconfig file.

For example, in the kernel’s root Kconfig:

# SPDX-License-Identifier: GPL-2.0
#
# For a description of the syntax of this configuration file,
# see Documentation/kbuild/kconfig-language.rst.
#
mainmenu "Linux/$(ARCH) $(KERNELVERSION) Kernel Configuration"

config DUMYCONFIG
	bool "Completely crafted configuration"
	help
	  This is just made for demonstration purposes

source "scripts/Kconfig.include"

[...]

34EXZP.png

We can see our new configuration and set it’s T/F value. Also we got a cool notification that the configuration is new (will disappear on next menuconfig).

To see how to “properly” configure a default Kconfig to start working with, go to TODO

The generated .config looks like the following:

#
# Automatically generated file; DO NOT EDIT.
# Linux/x86 5.4.214 Kernel Configuration
#

#
# Compiler: gcc (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0
#
CONFIG_CC_IS_GCC=y
CONFIG_GCC_VERSION=90400
CONFIG_CLANG_VERSION=0
CONFIG_CC_CAN_LINK=y
CONFIG_CC_HAS_ASM_GOTO=y
CONFIG_CC_HAS_ASM_INLINE=y
[...]
CONFIG_X86_DEBUG_FPU=y
# CONFIG_PUNIT_ATOM_DEBUG is not set
# CONFIG_UNWINDER_ORC is not set
CONFIG_UNWINDER_FRAME_POINTER=y
# CONFIG_UNWINDER_GUESS is not set
# end of Kernel hacking

After the .config creation, when we actually build the kernel it will call syncconfig to build the source headers that include these configurations. For example with metaheaders in include/config and include/generated/autoconf.h (more commonly).

Footnotes: