L12: Linux Kernel Configuration

 

 

📚 Linux Kernel Programming Series – Chapter 2

← Previous Lecture
Lecture 12 – Kernel Configuration Part 1
Next Lecture →

Linux Kernel Configuration

Lecture 12 – Part 1 of 2 | Free Linux Kernel Development Course

Understanding the .config file and three practical approaches to configure the Linux kernel for any target hardware

6.x

Kernel Version

kbuild

Build System

Beginner

Level

Topics Covered in This Free Linux Kernel Development Course Lecture

Linux kernel configuration
.config file
kbuild system
menuconfig
defconfig
localmodconfig
embedded Linux
BSP team
ARM SoC config
free embedded system course

🎯 What You Will Learn

  • Why the Linux kernel needs to be configured before it can be built
  • What the .config file is and how it controls every build decision
  • How embedded and desktop kernel configurations are fundamentally different
  • Three proven approaches to create a starting kernel config
  • How to use localmodconfig to get a lean, fast-building kernel
  • How the BSP team fits into the embedded Linux kernel workflow

Prerequisites

Before this lecture you should be comfortable with basic Linux terminal commands (ls, cp, cd, make) and have a general understanding of what a kernel is. Completing Lecture 11 on downloading and extracting the kernel source is recommended.

1. Why Does the Linux Kernel Need Configuration?

This free Linux kernel development course starts this chapter with a question beginners always ask: if Linux is open source, why can’t I just run make and get a kernel? The answer is that the kernel supports an enormous range of hardware – from tiny microcontrollers all the way up to cloud servers with hundreds of CPU cores. Building a single binary that includes every driver, every file system, every protocol stack for every possible piece of hardware is impossible and deeply wasteful. So before compilation, you must tell the kernel exactly what to include.

That decision-making process is called kernel configuration. It is one of the first skills any embedded Linux engineer, device driver developer, or BSP team member must master. This free embedded system course lecture walks you through it from the ground up.

💡 Real-World Analogy

Think of it like ordering a custom laptop. You choose the CPU, RAM, storage, GPU, and display – the factory builds only what you ordered. The kernel configuration system works exactly the same way. You specify what to include; everything else is left out of the final binary.

2. The Heart of Linux Kernel Configuration: The .config File

Every kernel configuration decision ends up in a single plain-text file called .config, located at the root of the kernel source tree. This is the file the kbuild system reads when compiling the kernel. Understanding this file is central to mastering Linux kernel configuration.

Each line in .config represents one configuration option. You will see three patterns:

CONFIG_BLK_DEV_INITRD=y        # built into the kernel image
CONFIG_USB_SERIAL=m            # compiled as a loadable module
# CONFIG_SOUND is not set      # completely disabled

The three states every option can take are:

CONFIG Symbol States in Linux Kernel Configuration

Value | Meaning | What gets built
——–|—————-|———————————————-
=y | Built-in | Code compiled directly into vmlinuz image
=m | Module | Compiled as a separate .ko file, loaded at runtime
not set | Disabled | Not compiled at all — saves space and build time

Because .config is just a text file you could open it in any editor. However, directly editing it is risky. Config options often have dependencies — enabling option A might require option B to also be enabled. Getting those dependencies wrong silently produces a broken or non-booting kernel. That is why we use tools like menuconfig to edit it safely.

How .config Drives the Entire Linux Kernel Build

Linux Kernel Configuration Build Flow

Kconfig files menuconfig / nconfig .config file
(declare all options) –> (you choose values) –> (stores choices)
| |
| syncconfig runs
| |
v v
include/generated/ make -j$(nproc) vmlinuz / bzImage
autoconf.h + headers <– (compiler reads <– (your kernel binary)
(#ifdef CONFIG_X) #ifdef guards)

After you save your config, kbuild automatically runs an internal step called syncconfig which converts .config into C header files under include/generated/. The kernel’s C source files use #ifdef CONFIG_SOME_FEATURE guards to include or exclude code blocks based on those headers. You never call syncconfig manually — the build system handles it.

3. Desktop vs Embedded Linux Kernel Configuration – Key Differences

Before touching any config tool, you need to understand one critical rule in Linux kernel configuration: a kernel config is tightly tied to its target CPU architecture. You cannot take a config written for an x86-64 desktop and use it on an ARM embedded board. The architectures are completely different at the hardware level — the resulting binary will not boot.

Desktop vs Embedded Linux Kernel Configuration Comparison

Feature | Desktop / Server | Embedded / SoC Board
———————|—————————|——————————
CPU architecture | x86-64 | ARM, ARM64, RISC-V, MIPS
Number of drivers | Hundreds (generic) | Only board-specific drivers
.config size | 10,000+ options | Lean, focused option set
Starting point | Distro config or lsmod | arch/*/configs/xxx_defconfig
Config maintenance | Community maintained | BSP team maintained
Build time | Very long (distro config) | Faster (only what’s needed)
Goal | Supports all hardware | Tailored to one product

For embedded targets, the kernel source tree ships with ready-made starting configs called defconfig files. These live inside the arch/ directory for each supported architecture:

arch/arm/configs/        # defconfigs for 32-bit ARM boards
arch/arm64/configs/      # defconfigs for 64-bit ARM (AArch64) boards
arch/riscv/configs/      # defconfigs for RISC-V boards
arch/mips/configs/       # defconfigs for MIPS boards

Each file is named after the SoC or board family it supports. For example, if you are working with a Samsung Exynos SoC on a 32-bit ARM board, your starting point is:

arch/arm/configs/exynos_defconfig

To use it, copy it to .config at the root of the kernel source tree, then fine-tune from there:

# Copy the Exynos defconfig as your starting .config
cp arch/arm/configs/exynos_defconfig .config

# Open menuconfig to review and adjust options
make ARCH=arm menuconfig

On kernel 6.x you can also invoke the defconfig target directly, which does the copy for you:

# Let kbuild do the copy automatically
make ARCH=arm exynos_defconfig

🏭 What is a BSP Team?

BSP stands for Board Support Package. In companies that build embedded Linux products — routers, cameras, set-top boxes, automotive systems — a dedicated BSP team is responsible for porting the Linux kernel to the specific hardware. One of their primary tasks is carefully crafting the kernel .config for that product: enabling only the drivers the hardware actually has, disabling debug features in production, enabling security hardening options, and tuning performance-related config symbols. A well-crafted BSP kernel config directly impacts boot time, memory footprint, power consumption, and attack surface of the final product.

A quick way to discover which defconfig files are available for a given architecture is to list the directory:

# See all available ARM defconfigs
ls arch/arm/configs/

# See all available ARM64 defconfigs
ls arch/arm64/configs/

On the target board itself you can run make help and look under the “Architecture specific targets” section. Note: this only works for cross-compilation targets and not for the native x86-64 host.

4. Three Practical Approaches to Linux Kernel Configuration

There is no single correct way to get your first .config. The right choice depends on your hardware target and your goals. Here are the three most widely used approaches in this free Linux kernel development course.

Three Linux Kernel Configuration Strategies at a Glance

Approach | Method | Best For
———|———————————-|————————————
1 | Architecture defconfig | Embedded / SoC cross-compilation
2 | Copy distro’s existing config | x86-64 desktop, need everything
3 | localmodconfig (lsmod snapshot) | x86-64 desktop, fast lean build

Approach 1 – Use the Architecture defconfig (Best for Embedded)

Pick the defconfig file that matches your SoC, copy it to .config, and you have a verified starting point the kernel maintainers have already tested for that platform. This is the standard method used by every BSP team and embedded Linux engineer.

# Configure for Samsung Exynos (32-bit ARM) cross-compilation
export ARCH=arm
export CROSS_COMPILE=arm-linux-gnueabihf-

# Approach A: manual copy
cp arch/arm/configs/exynos_defconfig .config
make menuconfig

# Approach B: let kbuild copy it (kernel 6.x recommended)
make ARCH=arm exynos_defconfig

After running the defconfig target you can immediately open menuconfig to add any product-specific options your board needs.

Approach 2 – Copy Your Distro’s Existing Config (Best for Desktop)

If you are building a kernel for an x86-64 desktop or server, the fastest shortcut is to start with the config your current Linux distribution already uses. This config has been tested by thousands of users and handles almost all common hardware out of the box.

# The running kernel's config is stored in /boot
# Copy it as the starting .config for your new build
cp /boot/config-$(uname -r) /path/to/kernel/source/.config

# Then update it for any new symbols in the newer kernel version
cd /path/to/kernel/source
make olddefconfig

The olddefconfig step is important: if you are building a newer kernel version than you are currently running, there will be new config symbols that do not exist in the old .config. olddefconfig sets them all to their kernel-defined defaults without asking you anything — perfect for automated workflows.

Keep in mind: distro configs tend to be very large because they support every possible piece of hardware. Build times will be long. If you want a leaner, faster build, use Approach 3.

Approach 3 – localmodconfig (Recommended for Desktop / Learning)

This is the smartest approach for x86-64 development. The idea is simple: why compile drivers for hardware you do not even have? The localmodconfig target looks at which kernel modules are currently loaded on your running system, and builds a .config that only includes those — plus core kernel features. Everything else is disabled, giving you a much smaller config and significantly faster build times.

How localmodconfig Works – Step by Step

Step 1: lsmod > /tmp/mods.txt
Lists all currently loaded kernel modules and saves to a file.Step 2: make LSMOD=/tmp/mods.txt localmodconfig
kbuild reads the module list and generates a lean .config
that enables exactly those modules plus core kernel options.
Everything else is set to “not set” (disabled).Result: A compact .config tailored to your machine’s actual hardware.
Faster to build, smaller image, nothing wasted.

# Step 1: Snapshot the currently loaded kernel modules
lsmod > /tmp/lsmod_snapshot.txt

# Step 2: Generate lean .config from that snapshot
cd /path/to/kernel/source
make LSMOD=/tmp/lsmod_snapshot.txt localmodconfig

When you build a newer kernel version than you are currently running (common — building kernel 6.x but running 5.x), kbuild will encounter new config options that did not exist before. For each one it will ask you what value to set. Pressing Enter accepts the default. To automate this:

# Accept all defaults for new options automatically
yes "" | make LSMOD=/tmp/lsmod_snapshot.txt localmodconfig

Pro Tip: Before running any config target on a fresh kernel source tree, always run make mrproper first. This removes any stale generated files from previous builds and ensures a completely clean starting state. Skipping this step can cause confusing build errors.

# Clean slate first — always
make mrproper

# Then configure
make LSMOD=/tmp/lsmod_snapshot.txt localmodconfig

5. Choosing Your Linux Kernel Configuration Approach – Quick Reference

Linux Kernel Configuration Approach Selection Guide

Situation | Best Approach | Key Command
———————————————|———————-|——————————————
Building for a specific ARM / RISC-V SoC | Approach 1 defconfig | make ARCH=arm xxx_defconfig
x86-64 desktop, need full hardware support | Approach 2 distro | cp /boot/config-$(uname -r) .config
x86-64 desktop, want a fast lean build | Approach 3 lsmod | make LSMOD=… localmodconfig
Smallest possible kernel for learning | tinyconfig | make tinyconfig
Fresh source tree or switching kernel version| Clean first | make mrproper

6. Reviewing and Editing the Config with menuconfig

Regardless of which approach you used to generate your starting .config, you will almost always want to review and tweak it. The most popular tool is menuconfig — a text-based, ncurses-driven menu you navigate with arrow keys and the spacebar. It works over SSH and requires no desktop environment, making it the standard for both embedded and server work.

# Open the interactive menu configurator
make menuconfig

menuconfig Keyboard Navigation Reference

Key | Action
————-|——————————————————
Arrow keys | Move between menu entries
Enter | Go into a sub-menu
Space | Toggle option: off –> module (m) –> built-in (y)
/ | Search for a config option by symbol name
? | Show help text for the highlighted option
Esc Esc | Go back one menu level / exit
Tab | Cycle between [Select] [Exit] [Help] buttons at bottom

Other interactive tools are also available. nconfig provides an alternative ncurses interface with function-key shortcuts shown at the bottom of the screen. xconfig opens a Qt-based graphical window (requires a display and Qt dev libraries). gconfig uses GTK+. For headless servers and embedded cross-compilation workflows, menuconfig or nconfig are standard choices.

Common Mistake – Editing .config Manually Without Running menuconfig After

If you manually edit .config in a text editor and then run make without running make olddefconfig first, the build may pick up inconsistent dependency states. Always run make olddefconfig after any manual edit to let kbuild resolve and validate dependencies before building.

7. Best Practices for Linux Kernel Configuration

  • Always start with mrproper on a fresh kernel source tree to clear stale files.
  • Never use an x86-64 config for ARM or any other architecture. Always match the defconfig to your target SoC.
  • Version your .config in git or a backup location. A good config for your hardware takes time to tune — do not lose it.
  • Use savedefconfig to create a minimal config snapshot. This is how the upstream defconfig files in arch/*/configs/ are maintained.
  • Run make olddefconfig when you upgrade to a newer kernel version, before opening menuconfig. This sets all new symbols to safe defaults first.
  • Search before browsing inside menuconfig. Use / and the symbol name — it is far faster than navigating the entire menu tree manually.
  • Document your changes with comments. menuconfig does not save notes, so keep a separate file explaining why certain options were enabled or disabled for your product.

📝 Lecture 12 Summary – Linux Kernel Configuration Part 1

  • Linux kernel configuration decides what gets compiled into the kernel binary
  • All decisions are stored in the plain-text .config file at the source root
  • Each config symbol is built-in (=y), a module (=m), or disabled
  • kbuild converts .config to C headers via syncconfig — you never call this manually
  • For embedded work, always start from the correct architecture defconfig for your SoC
  • For x86-64 desktops, localmodconfig gives the leanest and fastest build
  • The distro config approach works but produces a very large, slow-building kernel
  • Always run make mrproper before starting a fresh configuration
  • Use menuconfig to safely review and adjust options with dependency validation

← Previous Lecture
Next Lecture: kbuild Config Targets →

FAQ – Linux Kernel Configuration Interview Questions

Q1. What is the .config file in the Linux kernel and why is it important?

The .config file is a plain-text file at the root of the kernel source tree that stores all configuration choices for a particular build. Every feature, driver, and subsystem is represented by a config symbol set to y (built-in), m (module), or left unset (disabled). The kbuild system reads this file to decide what code to compile. Without a valid .config, the kernel cannot be built.

Q2. Why can you not use an x86-64 kernel .config for an ARM embedded board?

A kernel config is tightly tied to the CPU architecture. x86-64 and ARM have completely different hardware — different instruction sets, memory management units, interrupt controllers, and boot mechanisms. An x86-64 config enables drivers and options that do not exist or make no sense on ARM hardware. Even if the build does not fail, the resulting binary will not work on the ARM board. You must always start from an architecture-appropriate defconfig.

Q3. What is localmodconfig and when would you use it?

localmodconfig is a kbuild target that builds a .config based on the kernel modules currently loaded on the running system. You first save the output of lsmod to a file and pass it via the LSMOD variable. The result enables only the modules your hardware actually uses, disabling everything else. It is the recommended approach for developers who want to quickly build and test a custom kernel on their own x86-64 machine. It is not suitable for embedded targets where the hardware is different from the build host.

Q4. What does make mrproper do and why should you run it first?

make mrproper removes all generated files including the .config, auto-generated headers, and leftover object files from any previous build. If you skip it on a fresh kernel source, stale headers can cause subtle and confusing build errors. Running mrproper guarantees you are starting from a completely clean state. The name comes from the German word for “proper” — it means a spotless clean.

Q5. What is the role of the BSP team in kernel configuration for embedded products?

BSP stands for Board Support Package. The BSP team in an embedded product company adapts the Linux kernel to specific hardware. A major part of their work is crafting the kernel .config for that product: enabling only the drivers the hardware has, disabling debug features for production builds, enabling security hardening options, and tuning performance-related symbols. A well-crafted BSP config directly impacts boot time, memory usage, power consumption, and attack surface of the product.

Q6. What is syncconfig and when does it run?

syncconfig is an internal kbuild step that converts .config into C header files under include/generated/ and include/config/. The kernel’s C source files use #ifdef CONFIG_XXX guards that read from these generated headers to include or exclude code. You never call syncconfig manually — kbuild runs it automatically when you invoke make after a .config is created or changed. It was previously called silentoldconfig before being renamed.

Q7. What is the difference between make clean and make mrproper?

make clean removes most generated object and binary files but preserves the .config and enough support to rebuild. Use it when you have changed source files and want to recompile without reconfiguring. make mrproper removes everything including .config, generated headers, and all backup files — it gives you an absolutely clean source tree. Use it when starting a completely fresh configuration from scratch.

Article SEO Information

SEO Details – Free Linux Kernel Development Course

SEO Title : Linux Kernel Configuration Explained – Free Linux Kernel Development Course
Focus Phrase : linux kernel configuration free linux kernel development course
Meta Desc : Learn Linux kernel configuration from scratch. Understand .config, kbuild, defconfig
and localmodconfig in this free Linux kernel development course. (154 chars)
URL Slug : linux-kernel-configuration-free-linux-kernel-development-course
Targets : free linux kernel development course
free linux device drivers course
free embedded linux course
free embedded system course

📚 Linux Kernel Programming Series – Chapter 2

← Previous Lecture
Lecture 12 – Kernel Configuration Part 1
Next Lecture →

Leave a Reply

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