Linux Kconfig

Last update: 2022-07-06 20:06:54 +0800 +0800
tags: Kconfig | Kernel | Linux
Available translations: 日本語 / 中文(简体) / 中文(繁體)

Kconfig describes the choices from which a Linux kernel configuration is built. Kernel developers edit Kconfig files to define symbols and their relationships; users select values through front ends such as make menuconfig, make nconfig, make xconfig, or noninteractive targets such as olddefconfig.

The resulting .config is an input to Kbuild, not a complete build script. Configuration synchronization generates files consumed by Make and C, including include/config/auto.conf and include/generated/autoconf.h.

From the Root File to One Configuration #

Parsing begins at the top-level Kconfig. Its source statements include subsystem files, and the architecture selection brings in arch/$(SRCARCH)/Kconfig. Other inclusion forms are:

  • rsource, whose path is relative to the including file;
  • osource, which ignores a missing file;
  • orsource, which combines relative and optional behavior.

mainmenu sets the front end’s title. menu/endmenu, if/endif, choice/endchoice, comment, config, and menuconfig build the entry structure.

The same symbol can be defined in more than one included file. Kconfig combines the symbol’s properties; it does not create architecture-local variables. Definitions must use a consistent type, dependency clauses accumulate, and the order of defaults still matters. A common file can therefore declare an invisible capability while an architecture definition selects it.

kconfig
# lib/Kconfig
config HAVE_FAST_CHECKSUM
    bool

config FAST_CHECKSUM
    bool "Use the generic fast checksum implementation"
    depends on HAVE_FAST_CHECKSUM

# arch/example/Kconfig
config EXAMPLE
    bool
    select HAVE_FAST_CHECKSUM

HAVE_* symbols express implementation capability. A user-visible feature then depends on that capability, which avoids using select to bypass the feature’s real dependencies.

The Macro and Preprocessor Layer #

Kconfig performs textual expansion before the menu-entry language consumes a line. Its variable syntax resembles Make:

makefile
immediate := $(ARCH)
deferred = $(ARCH)
message = architecture $(1), compiler $(2)

$(info,configuring $(immediate))
label := $(message,$(ARCH),$(CC))
  • := expands the right-hand side immediately.
  • = stores a recursively expanded value.
  • += appends according to the variable’s existing expansion flavor.
  • $(name) expands a variable.
  • $(name,arg1,arg2) expands a parameterized variable, where $(1), $(2), and so on are positional arguments.

Unlike Make, a parameterized Kconfig variable is invoked directly; there is no $(call ...). Commas separate function arguments. Built-in functions include shell, info, warning-if, error-if, filename, and lineno. The kernel adds functions such as compiler-option probes through the Kconfig function mechanism.

Macro expansion is textual, so quoting and whitespace remain significant to the language that receives the result. Use preprocessing for small repeated expressions and feature probes rather than generating large, difficult-to-audit menu fragments.

Symbols, Types, and Prompts #

config NAME defines a symbol named NAME; .config and C expose it as CONFIG_NAME. menuconfig defines the same kind of symbol but tells compatible front ends that the entry is intended to contain a submenu.

Five symbol types are available:

TypeExample in .configGenerated C Form
boolCONFIG_FOO=y or # CONFIG_FOO is not set#define CONFIG_FOO 1 or absent
tristateCONFIG_FOO=y, CONFIG_FOO=m, or unsetCONFIG_FOO, CONFIG_FOO_MODULE, or neither
stringCONFIG_FOO="value"a quoted string macro
intCONFIG_FOO=42an integer macro
hexCONFIG_FOO=0x2aa hexadecimal integer macro

bool "Enable foo" and tristate "Build foo" combine a type with a prompt. A symbol without a visible prompt is not editable in a configuration front end, although defaults, select, or other expressions can still give it a value.

kconfig
config FOO
    tristate "Foo transport"
    depends on NET
    default m if MODULES
    help
      Build support for the Foo transport.

def_bool EXPR and def_tristate EXPR are shorthands for a type plus default EXPR. range MIN MAX limits an int or hex symbol when its optional condition is true.

Tristate Expressions #

Logical Kconfig expressions use the ordered values n = 0, m = 1, and y = 2. Consequently:

  • A && B is the minimum of the two values;
  • A || B is the maximum;
  • !A is 2 - A.

Comparisons produce a tristate result. Parentheses control grouping, and quoted literals represent string values. A bool cannot retain m; module-related expressions collapse according to the symbol type and whether modules are enabled.

Direct dependencies impose an upper bound:

kconfig
config USB_WIDGET
    tristate "USB widget"
    depends on USB && HAS_IOMEM

If USB=m, USB_WIDGET cannot become y. The optional condition on a prompt affects whether the prompt is visible, while the symbol’s direct dependencies constrain its value regardless of front-end presentation.

Defaults, Reverse Dependencies, and Visibility #

Properties solve different problems:

  • default VALUE if CONDITION supplies a value only when the user has not already set one. If several defaults are visible, the first visible default wins. Defaults do not override a value preserved from an existing .config.
  • depends on EXPR limits the symbol’s maximum value and prompt visibility.
  • select TARGET if CONDITION creates a reverse dependency and raises TARGET to at least the selecting expression’s value. It does not honor TARGET’s own direct dependencies, so it should select only simple, invisible symbols whose prerequisites are already guaranteed.
  • imply TARGET if CONDITION is a weak reverse dependency. It supplies a lower bound that can still be reduced by a visible user choice, and the target’s direct dependencies continue to cap the result.
  • visible if EXPR limits the visibility of a menu block without changing the values of symbols inside it.

For example:

kconfig
config DRIVER_FOO
    tristate "Foo device"
    depends on PCI
    select CRC32
    imply FW_LOADER

CRC32 should be an internal helper with no unmet dependencies. FW_LOADER is merely encouraged because the driver can operate without it. Adding select to repair a dependency cycle is incorrect because Kconfig rejects recursive dependencies and does not use a SAT solver to infer a preferred solution.

Source order and explicit containers determine most displayed positions:

kconfig
menu "Network drivers"
    visible if NET

config NET_VENDOR_EXAMPLE
    bool "Example devices"

if NET_VENDOR_EXAMPLE
source "drivers/net/ethernet/example/Kconfig"
endif

endmenu

Front ends also infer an implicit submenu when a later entry depends on the preceding entry strongly enough that the child cannot be visible unless the parent is visible. The language documentation describes the precise prompt-dependency rule.

Dependencies do not otherwise relocate entries. A symbol can depend on another symbol displayed in a different section, and select does not make the target appear below the selector. Therefore menu layout communicates navigation, while dependency expressions communicate valid values. Treating one as a rendering of the other produces confusing Kconfig files.

Generated Configuration Artifacts #

After a front end writes .config, Kbuild synchronizes generated inputs. The important representations are:

text
.config
include/config/auto.conf
include/generated/autoconf.h

.config is the persistent, user-facing assignment file. auto.conf presents assignments to Make, so rules can use expressions such as:

makefile
obj-$(CONFIG_USB_WIDGET) += usb-widget.o

autoconf.h presents enabled symbols to C preprocessing. Kernel C code should include the normal kernel headers rather than include autoconf.h directly. Helpers such as IS_ENABLED(CONFIG_FOO) handle built-in and module forms without open-coding every preprocessor combination.

Configuration updates can add symbols introduced by a newer tree. make oldconfig asks about new choices, whereas make olddefconfig accepts their defaults. make savedefconfig writes a minimal defconfig relative to defaults; it is not interchangeable with archiving the full .config.

References #

Comments

Read or comment on GitHub (sign-in required to comment)