📘 Free Linux Kernel Development Course — Chapter 2
What Will You Learn in This Free Linux Kernel Development Lecture?
Welcome to Lecture 5 of EmbeddedPathashala’s free Linux kernel development course. Before you write a single line of kernel code, you need to understand how the Linux kernel is configured and built. The kernel runs on everything from tiny microcontrollers to cloud servers — and the configuration system is what makes that possible. In this lecture you will learn exactly how that system works, from first principles.
- Why the Linux kernel needs a configuration step before compiling
- What Kconfig and Kbuild are, and how they work together
- The three states every feature can be in: built-in, module, or excluded
- What the
.configfile is and how to read it - How
CONFIG_symbols control compilation in Makefiles and C code - Which packages you need installed before running
make menuconfig - All available kernel configuration frontends in Linux 6.x
Key Concepts in This Lecture
Kbuild
.config file
CONFIG_ symbols
make menuconfig
Boolean / Tristate
Built-in vs Module
kernel Makefile
obj-y obj-m
Linux 6.x kernel
Prerequisites
This is part of a structured free Linux kernel development course. Before this lecture you should have completed:
- Lecture 1–4: Linux Kernel workspace setup and source tree overview
- Basic familiarity with the Linux command line (cd, ls, grep, make)
- A working Ubuntu 22.04 / 24.04 or Fedora system (physical or VM)
- At least 20 GB of free disk space for the kernel source and build
No prior kernel programming experience is needed for this lecture. We start from the ground up.
1. Why Does the Linux Kernel Need Configuration?
The Linux kernel supports an enormous range of hardware — from a Raspberry Pi to a 512-core server rack. It includes drivers for hundreds of bus types, filesystems, network protocols, and security frameworks. If every single feature was compiled into every kernel build, the resulting binary would be impractically large and would contain code that is completely irrelevant to most hardware.
This is why the kernel uses a configuration step before compilation. In this step — which is a core topic in every free Linux kernel development course — you decide what your kernel will contain. Every kernel feature has exactly three possible states:
| State | Symbol in .config | What it means | Best for |
|---|---|---|---|
| Built-in (y) | CONFIG_FOO=y | Code compiled directly into the kernel image. Always available from boot. | Root filesystem driver, core networking stack |
| Module (m) | CONFIG_FOO=m | Compiled as a separate .ko file. Loaded on demand at runtime. | Device drivers, optional subsystems |
| Excluded (n) | # CONFIG_FOO is not set | Not compiled at all. Zero memory, zero binary overhead. | Drivers for hardware you don’t have |
2. What is the Kbuild System?
Kbuild is the name of the Linux kernel’s custom build infrastructure. It is a collection of Makefiles, shell scripts, and helper programs that work together to read your configuration, compile the selected source files, and link the final kernel image and modules. Many other open-source projects (BusyBox, U-Boot) adopted a very similar approach because Kbuild is well-structured and easy to extend.
Understanding Kbuild is central to any free Linux kernel programming course. Here is the flow from your configuration choice to the final compiled kernel:
3. What Are Kconfig Files?
Inside the Linux kernel source tree, there are thousands of files named Kconfig — typically one or more per directory. Each file describes the configuration options available for that subsystem using a special domain-specific language. As of Linux 6.x, there are over 1,700 Kconfig files in the tree.
These files define menu entries, their types (bool or tristate), default values, dependencies on other options, and the help text you see when you press ? in the menuconfig UI. Here is a simplified example of a Kconfig entry:
config IKCONFIG
tristate "Kernel .config support"
help
Enable this to embed the kernel's .config file
inside the running kernel image. Useful for
debugging and build reproducibility.
| config IKCONFIG | Declares a symbol. Becomes CONFIG_IKCONFIG in your .config file. |
| tristate “…” | Three states: y (built-in), m (module), n (off). The quoted text is the menu label. |
| bool “…” | Two states only: y (on) or n (off). Cannot be a module. |
| help | The text shown when you press ? in menuconfig. Also reveals the exact CONFIG_ symbol name. |
CONFIG_ name — critical knowledge when searching the kernel source or setting options in a script.
4. The .config File — Where Your Choices Are Stored
Every time you configure the kernel using any frontend (menuconfig, nconfig, xconfig), your choices are saved to a plain text file called .config in the root of the kernel source directory. Kbuild reads this file when compiling. Here is a real snippet from a .config file:
#
# General setup
#
CONFIG_LOCALVERSION="-embeddedpathashala"
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
# CONFIG_PROFILING is not set
CONFIG_UIO=m
# CONFIG_HAMRADIO is not set
The pattern is simple: a disabled feature appears as a comment line starting with #. An enabled built-in feature is CONFIG_NAME=y. A module is CONFIG_NAME=m.
.config directly with a text editor, but this is not recommended for beginners. Config options have complex dependencies — changing one option manually may silently break others. Always use make menuconfig or a similar tool to change options safely.5. All Configuration Frontends in Linux 6.x
The kernel provides several configuration frontends for different preferences and environments. All of them read the same Kconfig files and write to the same .config file — only the user interface differs. This is a key concept in our free Linux device driver development course content.
| Command | Interface | Best For |
|---|---|---|
| make menuconfig | Text color menus in terminal | Most popular — works over SSH, no desktop needed |
| make nconfig | Enhanced text UI with function key shortcuts | Users who prefer keyboard-shortcut-driven navigation |
| make xconfig | Qt-based graphical GUI | Desktop Linux with Qt libraries installed |
| make gconfig | GTK-based graphical GUI | Desktop Linux with GTK libraries installed |
| make oldconfig | CLI — asks only about new options | Upgrading kernel version while keeping existing choices |
| make defconfig | No UI — applies arch defaults | Quick start, CI systems, or a known-good baseline |
| make localmodconfig | No UI — uses loaded modules | Minimal config for embedded targets based on current hardware |
make menuconfig because it is the industry standard, works without a graphical desktop, and is the tool you will encounter in every embedded and systems job.6. Required Packages Before You Begin
Running make menuconfig on a fresh Ubuntu or Debian system requires several development packages to be installed first. The most common beginner error in this free Linux kernel programming course is missing bison or flex — the build system generates a Kconfig parser at build time and these tools are needed for that.
Install on Ubuntu / Debian
sudo apt update
sudo apt install build-essential bison flex libncurses-dev \
libssl-dev libelf-dev bc
Install on Fedora / RHEL
sudo dnf install gcc make bison flex ncurses-devel \
openssl-devel elfutils-libelf-devel bc
| bison | Parser generator — needed to process the Kconfig grammar. Missing this is the #1 first error. |
| flex | Lexical scanner — works alongside bison to parse Kconfig files. |
| libncurses-dev | Powers the terminal UI drawing (colors, boxes, menus) in menuconfig. |
| libssl-dev | Required for kernel module signing (mandatory since kernel 3.7+). |
| libelf-dev | Handles ELF binary format operations during the kernel build. |
/bin/sh: 1: bison: not found when running make menuconfig, install bison and try again. If you see flex: not found, install flex. These are always the first two packages to check on a fresh system.7. How Kbuild Uses CONFIG_ Symbols
Once your choices are saved in .config, Kbuild processes them in two ways. This dual usage is one of the most elegant parts of the Linux kernel build system — and a concept every student in a free Linux device driver course must understand deeply.
In Makefiles — Controlling Which Files Get Compiled
Every kernel subsystem’s Makefile uses the obj-$(CONFIG_XXX) pattern:
# drivers/uio/Makefile
obj-$(CONFIG_UIO) += uio.o
obj-$(CONFIG_UIO_PDRV_GENIRQ) += uio_pdrv_genirq.o
In C Source Code — Conditional Compilation
The same CONFIG_ symbols are available inside kernel C source files as C preprocessor macros:
/* Inside kernel C code */
#ifdef CONFIG_SMP
/* This code only compiles on SMP (multi-processor) kernels */
smp_call_function(my_func, NULL, 1);
#endif
#if IS_ENABLED(CONFIG_UIO)
/* Compiles if UIO is y or m */
register_uio_device(&my_dev);
#endif
This is what makes the Linux kernel so portable — the same source code compiles into drastically different kernels depending purely on configuration choices.
Best Practices for Linux Kernel Configuration
- Always back up your .config after getting a working kernel build. A single
make mrproperwill delete it. - Use make olddefconfig when upgrading to a newer kernel version. It preserves all your old choices and sets new options to sensible defaults automatically.
- Prefer modules over built-in for hardware drivers unless the driver is needed at boot time (e.g., your root filesystem’s storage driver).
- Use make localmodconfig to generate a minimal config for embedded targets — it builds only what your current hardware actually needs.
- Never disable CONFIG_SECURITY on anything other than a throwaway test kernel. It enables the entire LSM (AppArmor, SELinux) framework.
- Press ? in menuconfig before changing any option you are unsure about — the help text explains consequences and reveals dependencies.
Common Mistakes and Troubleshooting
| Error / Mistake | Fix |
|---|---|
bison: not found when running menuconfig |
Run sudo apt install bison (Ubuntu) or sudo dnf install bison (Fedora) |
flex: not found |
Run sudo apt install flex |
| menuconfig screen is garbled / blank | Install libncurses-dev. Also resize your terminal to at least 80×25 characters. |
| Option is greyed out in menuconfig | A dependency is not met. Press ? to see what the option depends on, then enable the parent option first. |
.config file missing after make mrproper |
make mrproper deletes .config by design. Always save a backup copy before running it. |
| Module fails to load on new kernel | Ensure you ran make modules_install and that the kernel version in uname -r matches the compiled modules directory. |
🎯 Key Takeaways — Lecture 5
- The Linux kernel uses a configuration step to select exactly which features to compile — keeping the kernel lean and portable.
- Kconfig is the language and tool system that describes options and builds menus. Kbuild is the Makefile infrastructure that uses those choices to compile the kernel.
- Every option becomes a
CONFIG_symbol: y (built-in), m (module), or not set (excluded). - Your choices are saved in the
.configfile — back it up after every successful configuration. make menuconfigis the standard tool in every free Linux kernel development course — it runs in any terminal, with or without a desktop.- Install
bison,flex, andlibncurses-devbefore runningmake menuconfig.
Frequently Asked Questions — Linux Kernel Configuration
Q1. Is this free Linux kernel development course suitable for complete beginners?
Yes. EmbeddedPathashala’s free Linux kernel development course starts from workspace setup and gradually builds up to writing kernel modules and device drivers. Lecture 5 (this lecture) assumes only basic Linux command-line knowledge.
Q2. What is the difference between a kernel feature compiled as built-in (y) versus a module (m)?
A built-in feature is part of the kernel image and is always available from the moment the kernel boots — even before the root filesystem is mounted. A module is a separate .ko file that can be loaded and unloaded at runtime with modprobe. Modules reduce the kernel image size and only consume memory when loaded. Use built-in for anything needed at boot; use module for optional drivers and features.
Q3. What is the .config file and can I edit it manually?
The .config file is a plain text file in the kernel source root directory that stores all your configuration choices as CONFIG_NAME=y/m or # CONFIG_NAME is not set. You can edit it with a text editor, but this is risky for beginners because kernel options have complex dependencies that the tools manage automatically. Always prefer make menuconfig for interactive changes.
Q4. What is the difference between bool and tristate in a Kconfig file?
A bool config option has only two states: on (y) or off (n). A tristate option has three states: built-in (y), module (m), or off (n). Most device drivers use tristate because they can sensibly run as loadable modules. Core kernel infrastructure uses bool because it must be compiled in or not at all — it cannot be a module.
Q5. How do CONFIG_ symbols work in kernel Makefiles?
Kernel Makefiles use the obj-$(CONFIG_FOO) pattern. When CONFIG_FOO=y this expands to obj-y and the file is compiled into the kernel. When CONFIG_FOO=m it becomes obj-m and the file is built as a module. When the option is not set, the expansion produces nothing and the file is skipped. The same symbols also work as C preprocessor macros inside kernel source with #ifdef CONFIG_FOO.
Q6. How do I keep my .config when upgrading to a newer kernel version?
Use make oldconfig — it reads your existing .config, keeps all your current choices, and only prompts for options that are new in the newer kernel. For a fully automated approach, use make olddefconfig which sets all new options to their defaults without prompting. Both are far faster than reconfiguring from scratch.
Q7. What does make localmodconfig do?
make localmodconfig generates a minimal .config based on the kernel modules currently loaded on your running system (from lsmod). This produces a much smaller and faster-to-compile kernel that only includes support for the hardware currently present. It is especially useful for embedded development and cross-compilation where you want the smallest possible kernel footprint.
Q8. Does this free Linux kernel development course cover ARM and embedded targets?
Yes. While this lecture uses x86-64 examples for clarity, the Kconfig and Kbuild concepts apply identically to ARM, RISC-V, and any other architecture the Linux kernel supports. Later lectures in this free embedded systems course cover cross-compilation and embedded-specific configuration in detail.
References and Further Reading
- Linux Kernel Documentation — Kconfig language reference (docs.kernel.org/kbuild/kconfig-language.html)
- Linux Kernel Documentation — Configuration targets and editors (docs.kernel.org/kbuild/kconfig.html)
- kernel.org — Official Linux kernel source and release notes
- Linux Journal — Kbuild: The Linux Kernel Build System (linuxjournal.com)
