L21: Linux Kernel .config File, kbuild Internals & diffconfig Explained

📚 Linux Kernel Programming Series
Chapter 2
Part 3 of 5

Chapter 2 · Part 3

Linux Kernel .config File, kbuild Internals & diffconfig Explained

Master how kernel configuration is stored, what happens inside kbuild after you save, how to search config options, and how to compare two kernel configs — all updated for Linux kernel 6.x

⚙️ Kernel 6.x Updated
🎯 Beginner to Intermediate
⏱ 20 Min Read
🆓 Free Course

What You Will Learn

Linux .config file format
CONFIG_FOO macros
kbuild syncconfig
autoconf.h explained
menuconfig search
scripts/diffconfig
Kconfig files
kernel module vs built-in

Most students stop at pressing save and exit in menuconfig and think the job is done. But understanding what happens after you save — and what the resulting files actually mean — is what separates a confident embedded Linux developer from someone who just follows steps blindly.

In this part, we dig into the Linux kernel configuration system from the inside. You will see exactly what is written to disk, how the build system transforms your choices into C macros and Makefile variables, and how to inspect and compare configurations like a kernel developer does. Everything in this tutorial is verified for Linux kernel 6.x.

1. Saving Your Configuration and Exiting menuconfig

After toggling all the options you need inside make menuconfig, navigate to the < Exit > button using the right arrow key and press Enter. A dialog box appears asking whether you want to save your new configuration.

menuconfig — Save and Exit Flow
Press < Exit >
in main menu
“Save new config?”
Dialog appears
< Yes > — saves .config ✓
< No > — all changes lost ✗
Esc Esc — back to config menu

💡 Tip — Esc does NOT discard changes

Pressing Esc twice on the save dialog takes you back to the configuration menu without losing anything. Your changes are still pending. Only selecting < No > permanently discards all the options you toggled in the current session.

2. The Linux Kernel .config File — What It Is and Where It Lives

When you choose < Yes >, the entire kernel configuration is written to a plain ASCII text file named .config, placed at the root of the kernel source tree. This single file is the authoritative record of every option you enabled, disabled, or marked as a module.

Linux Kernel Source Tree — .config Location
linux-6.x/              ← kernel source root
  ├── arch/
  ├── drivers/
  ├── include/
  ├── kernel/
  ├── Makefile
  ├── Kconfig             ← top-level Kconfig definition
  ├── .config             ← YOUR CONFIGURATION IS HERE
  └── .config.old        ← automatic backup of previous config

2.1 The Three States of a Kernel Configuration Option

Open any .config file and every option follows a CONFIG_<NAME> pattern. There are exactly three states an option can be in:

CONFIG Option States in .config
CONFIG_FOO=y
Built-in
Feature is compiled directly into the kernel image. Always present at boot.
menuconfig: <*>
CONFIG_FOO=m
Module
Feature is built as a loadable .ko file. Can be loaded/unloaded at runtime.
menuconfig: <M>
# CONFIG_FOO is not set
Disabled
Feature is completely excluded from the build. No code, no module.
menuconfig: < >

2.2 A Real .config Snippet — IKCONFIG Example

If you enabled Kernel .config support and its /proc/config.gz interface during your menuconfig session, your .config will contain the following entries. You can verify this with grep:

$ grep IKCONFIG .config
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y

CONFIG_IKCONFIG=y tells the build system to compile kernel-config support directly into the kernel binary. CONFIG_IKCONFIG_PROC=y means the /proc/config.gz pseudo-file will exist at runtime on any machine running this kernel, letting you inspect the exact configuration that was used to build it.

⚠️ Never Manually Edit .config

It is tempting to open .config in a text editor and change a line directly. Do not do this. Kernel configuration options have hidden inter-dependencies. Enabling one option may require others to be set, and the kbuild system enforces these rules automatically. Manual edits bypass all dependency checks and can silently break your configuration, leading to build failures or a non-booting kernel. Always use make menuconfig or another kbuild front-end.

2.3 How CONFIG Macros Flow Into Kernel C Code

Every option you set becomes a C preprocessor macro. Inside kernel source files you will see patterns like this constantly:

/* From kernel/smp.c — simplified example */
#ifdef CONFIG_SMP
    /* Multi-processor code path */
    smp_call_function_many(mask, func, info, wait);
#else
    /* Single-processor fallback */
    func(info);
#endif

And in kernel Makefiles, the same macros control which source files get compiled:

# drivers/net/ethernet/intel/Makefile — simplified
obj-$(CONFIG_E1000)      += e1000/
obj-$(CONFIG_VIRTIO_NET) += virtio_net.o

When CONFIG_E1000=y, the e1000 folder is compiled into the kernel. When CONFIG_E1000=m, it becomes a loadable module. When it is not set, the folder is completely ignored by the build.

3. What Happens Behind the Scenes — kbuild and syncconfig

Saving .config is not the final step in the kbuild pipeline. As soon as the file is written, kbuild automatically runs an internal target called syncconfig. You never need to call this manually — it triggers on its own. This target was previously named silentoldconfig, a name that was confusing and not descriptive, so it was renamed in modern kernels.

The job of syncconfig is to transform your plain-text .config into multiple generated files that the rest of the build system can actually use.

kbuild Configuration Pipeline — Full Picture

make menuconfig
User interaction
.config
Saved to disk
syncconfig
Runs automatically

↓ generates

include/generated/autoconf.h
C macros for kernel source files
Powers all #ifdef CONFIG_ guards
include/config/auto.conf
Make-readable config variables
Used in all kernel Makefiles
include/config/*.h
Empty sentinel headers
Used for dependency tracking

↓ enables
make (kernel build)
Compiles only the files and code paths that match your configuration

3.1 autoconf.h — The Bridge Between Config and C Code

The file include/generated/autoconf.h contains one #define per enabled configuration option. Kernel source files include this header indirectly through other headers, which is how #ifdef CONFIG_SMP and similar guards actually work at compile time.

/* Snippet from include/generated/autoconf.h */
#define CONFIG_IKCONFIG 1
#define CONFIG_IKCONFIG_PROC 1
#define CONFIG_SMP 1
#define CONFIG_MODULES 1
/* ... hundreds more options ... */

3.2 auto.conf — The Bridge Between Config and Makefiles

While autoconf.h serves C source files, include/config/auto.conf serves the Makefile infrastructure. It lists CONFIG options in a format GNU Make can evaluate directly in conditional expressions and variable substitutions.

3.3 Empty Sentinel Headers — How kbuild Tracks Changes

Under include/config/ you will find many tiny, empty .h files — one for each configuration option. These files exist for one purpose only: incremental build dependency tracking. When you change a config option, kbuild updates the corresponding sentinel file’s timestamp. Make then knows exactly which object files depend on that option and recompiles only those. This is what makes kernel incremental builds fast even with thousands of source files.

4. Searching for a Config Option Inside menuconfig

The Linux kernel 6.x has over 15,000 configuration options. Nobody navigates to them by hand. The menuconfig UI has a built-in search — triggered exactly like the search in the vi text editor.

How to Search Inside menuconfig
1

Press the / (forward slash) key

The Search Configuration Parameter dialog opens
2

Type your keyword

Works with or without the CONFIG_ prefix. In kernel 6.x you can also use regular expressions (e.g. NET.*IPv6)
3

Select < Ok > and press Enter

Results appear showing every matching option
4

Read the result dialog

Each result tells you the full menu path so you can navigate there directly

4.1 Understanding the Search Result Fields

The result dialog for each matching option gives you far more information than just where to find it. Here is what every field means:

menuconfig Search Result — Field Reference
Field What It Tells You Example
Symbol: The option name. Prepend CONFIG_ to get the macro name IKCONFIG → CONFIG_IKCONFIG
Type: Data type — bool (y/n only), tristate (y/m/n), int, string tristate
Prompt: The text shown next to the option inside the menu “Kernel .config support”
Location: Full menu path — follow this to navigate there manually General setup → …
Defined at: The Kconfig source file and line number where this option is declared kernel/Kconfig:2
Depends on: Other options that must be enabled before this one becomes available MODULES [=y]
Selects: Options automatically turned on when you enable this one DRM_KMS_HELPER [=m]

4.2 What Are Kconfig Files?

All the information the search result shows comes from plain text files called Kconfig. Every subsystem in the kernel has its own Kconfig file — for example, drivers/net/Kconfig defines all network driver options, arch/arm64/Kconfig defines ARM64-specific options, and so on. The kbuild system reads every Kconfig file in the entire source tree to build the menuconfig UI.

# What a Kconfig entry looks like (conceptual — from kernel/Kconfig area)
config IKCONFIG
    tristate "Kernel .config support"
    help
      This feature stores the kernel's own configuration inside
      the running kernel. Access it at /proc/config.gz if
      CONFIG_IKCONFIG_PROC is also enabled.

✅ Kernel 6.x Tip — Regex Search in menuconfig

In current kernel versions you can use regular expressions as search terms. For example, typing E1000 finds all Intel e1000 driver options. Typing USB.*SERIAL finds all USB serial adapter drivers. To see the search help inline, press / → Tab → Tab to highlight the Help button, then press Enter.

5. Comparing Two Kernel Configurations — scripts/diffconfig

Every time kbuild writes a new .config, it first backs up the old one as .config.old automatically. This gives you a before-and-after pair to compare whenever you want to review what you changed.

Using standard diff on two .config files is painful — the files are hundreds of lines long, full of comments, and the output is hard to interpret. The kernel source tree includes a dedicated script for exactly this task: scripts/diffconfig.

5.1 Basic Usage

# See what you changed compared to your previous configuration
$ scripts/diffconfig .config.old .config

5.2 Reading the Output

# Example diffconfig output
-DEBUG_KERNEL n         <-- was present, now removed/disabled
+IKCONFIG y             <-- newly added, value: y (built-in)
+IKCONFIG_PROC y        <-- newly added, value: y
 SMP y                  <-- unchanged (no prefix)

diffconfig Output — Symbol Guide
+
Option was added or enabled in the new config
Option was removed or disabled in the new config
Option is unchanged between both configs

5.3 The -m Flag — Minimal Config Fragment

# Produce a minimal config fragment (only the differences)
$ scripts/diffconfig -m .config.old .config

The -m flag produces output in a format you can use as a config fragment — a small file containing only the changed options. This is useful when you want to share a patch of config changes or apply specific options on top of a base distribution config.

6. Suggested Images for This Tutorial

📸 Image 1 — Featured / Hero

A terminal screenshot showing the actual make menuconfig save dialog (the “Do you wish to save your new configuration?” prompt with Yes/No options highlighted).

Alt text: make menuconfig save dialog asking to save kernel configuration in Linux kernel 6.x

📸 Image 2 — Mid Article

A terminal showing grep IKCONFIG .config with the output lines CONFIG_IKCONFIG=y and CONFIG_IKCONFIG_PROC=y. Shows students what a real .config line looks like.

Alt text: grep command showing CONFIG_IKCONFIG entries in Linux kernel .config file

📸 Image 3 — Search Section

A screenshot of the menuconfig search results dialog — showing Symbol, Type, Location, Depends on fields for a searched term like IKCONFIG or E1000.

Alt text: Linux menuconfig search result dialog showing config symbol location and dependencies

📸 Image 4 — diffconfig Section

Terminal output of scripts/diffconfig .config.old .config showing clearly the + and – prefixed lines. Helps students understand the output format visually.

Alt text: scripts/diffconfig output comparing old and new Linux kernel .config files

7. Quick Reference — Files and Commands

Key Files Generated by kbuild Configuration Step
File / Command Purpose Created By
.config Your full kernel configuration make menuconfig (you)
.config.old Automatic backup of previous config kbuild (automatic)
include/generated/autoconf.h C macros — powers #ifdef CONFIG_ in source syncconfig (automatic)
include/config/auto.conf Make variables — used in all Makefiles syncconfig (automatic)
include/config/*.h Empty sentinels for incremental build tracking syncconfig (automatic)
scripts/diffconfig old new Compare two .config files cleanly You run manually
/ (in menuconfig) Search for any config option by name or regex You press in menuconfig

Frequently Asked Questions

Can I copy a .config from one kernel version to another?

Yes, but you should run make oldconfig or make olddefconfig after copying. These commands go through the copied config and handle any new options added in the newer kernel version — either asking you interactively (oldconfig) or silently applying defaults (olddefconfig). Never just copy a config and build without this step.

What is the difference between =y and =m? When should I use which?

Use =y (built-in) for features that must be available at boot before any filesystem is mounted — for example, filesystem drivers for your root filesystem, essential hardware drivers, or core security features. Use =m (module) for features that are optional, used rarely, or large — like extra filesystem support, optional network protocols, or hardware you may or may not have. Modules reduce kernel image size and can be loaded or unloaded without rebooting.

Where does /proc/config.gz come from and how is it useful?

When you enable CONFIG_IKCONFIG=y and CONFIG_IKCONFIG_PROC=y, the kernel embeds a compressed copy of its own .config inside the kernel image and exposes it through /proc/config.gz. This lets you inspect the exact configuration of a running kernel at any time with zcat /proc/config.gz | grep SOMETHING — very useful for debugging or replicating a known-good configuration.

Can I have multiple .config files and switch between them?

Yes. Simply rename your current .config to something like .config.desktop or .config.embedded to save it, then copy the one you want to use back as .config and run make olddefconfig to validate it. Many kernel developers maintain separate config files for different hardware targets or use cases.

What happens if I enable a config option that has unmet dependencies?

menuconfig prevents this from happening interactively — if an option’s dependencies are not met, it appears greyed out and you cannot select it until the required options are enabled first. If you somehow get a .config with unmet dependencies (for example by manually editing it), running make olddefconfig will automatically resolve them by applying default values.

🎯 Interview Questions

These are real questions asked in embedded Linux and kernel development interviews. Try answering them without looking up.

Q1. Where is the kernel configuration saved after make menuconfig exits?

In a plain ASCII text file named .config at the root of the kernel source tree. Every option is recorded as a CONFIG_<NAME> variable set to y, m, or marked as not set.

Q2. What is the difference between CONFIG_FOO=y and CONFIG_FOO=m?

=y means the feature is compiled statically into the kernel image — always present. =m means it is built as a loadable kernel module (.ko file) that can be inserted or removed at runtime with insmod/modprobe.

Q3. What is syncconfig and what does it generate?

syncconfig is a kbuild-internal target (renamed from the old silentoldconfig) that runs automatically after .config is written. It generates include/generated/autoconf.h (C macros for kernel source files), include/config/auto.conf (Makefile variables), and empty sentinel headers under include/config/ for incremental build dependency tracking.

Q4. How do you search for a specific CONFIG option inside make menuconfig?

Press / (forward slash) to open the search dialog. Enter the option name with or without the CONFIG_ prefix. In kernel 6.x you can also use regular expressions. Results show the option’s type, menu location, source file, dependencies, and what it auto-selects.

Q5. How do you cleanly compare your old and new kernel configuration?

kbuild automatically backs up the previous config as .config.old. Run scripts/diffconfig .config.old .config from the kernel source root. Lines starting with + are new or enabled options; lines starting with - are removed or disabled options.

Q6. Why must you never manually edit the .config file?

Kernel config options have hidden inter-dependencies enforced by the kbuild menu system. Manual edits bypass all dependency checks and can silently produce an invalid configuration that causes build failures or a non-booting kernel.

Q7. What is include/generated/autoconf.h and why does every kernel driver indirectly depend on it?

It is a C header generated by syncconfig that contains one #define CONFIG_XXX 1 per enabled option. All #ifdef CONFIG_ guards inside kernel source code depend on these macros. If this file is missing or stale, the compiler will not correctly select which code paths to compile.

Q8. What are Kconfig files and how do they relate to what you see in menuconfig?

Kconfig files are source files (one per subsystem) that define configuration options — their names, types, default values, help text, and dependencies. The kbuild system reads all Kconfig files across the entire source tree to construct the menuconfig UI. Every option you see in menuconfig is described by an entry in some Kconfig file.

Q9. You are debugging a kernel on a target board. How can you check which CONFIG options were active when that kernel was built?

If CONFIG_IKCONFIG=y and CONFIG_IKCONFIG_PROC=y were enabled at build time, run zcat /proc/config.gz on the running system to view the full configuration. If those were not enabled, check if the kernel image itself has the config appended (some distributions do this) or look for the .config file used during the build.

SERIES NAVIGATION

EmbeddedPathashala · Free Linux Kernel & Embedded Systems Education · embeddedpathashala.com

Leave a Reply

Your email address will not be published. Required fields are marked *