ES: The Linux Kernel in Embedded Systems

The Linux kernel is the core operating system software that manages hardware resources and provides services to user-space programs. Understanding its architecture, configuration system, and directory structure is essential for any embedded Linux developer.

The Linux kernel is the software that sits between the hardware and the applications running on an embedded system. It is the most complex component of an embedded Linux system, responsible for managing every hardware resource and providing a stable, consistent interface to user-space programs.


What the Kernel Does

The kernel optimally manages the embedded system's hardware resources and provides essential services to the operating system.

Core services include:

  • Process management — creating, scheduling, and terminating processes
  • Process scheduling — task schedulers that share CPU time fairly
  • Inter-process communication (IPC) — sockets, shared memory, pipes
  • Memory management — virtual memory, page allocation, swapping
  • I/O management — device drivers that abstract hardware
  • Filesystem — virtual filesystem layer (VFS) supporting many formats
  • Networking — network protocol stacks and NIC drivers

Kernel Architecture

The Linux kernel uses a layered operating system architecture dividing the system into two address spaces:

md
+--------------------------------------------+
|  User Space                                |
|  +-----------+  +----------------------+   |
|  | Application|  | System Programs      |   |
|  +-----------+  +----------------------+   |
+--------------------------------------------+
        | System Call Interface
        v
+--------------------------------------------+
|  Kernel Space                              |
|  +------------------+--------------------+ |
|  | Process Mgmt     | Virtual Filesystem | |
|  +------------------+--------------------+ |
|  | Memory Mgmt      | Network Mgmt       | |
|  +------------------+--------------------+ |
|  | Device Drivers (Monolithic Kernel)     | |
|  +----------------------------------------+ |
|  | Loadable Kernel Modules (optional)     | |
+--------------------------------------------+
        | Hardware Access
        v
+--------------------------------------------+
|  Hardware                                  |
+--------------------------------------------+

Monolithic Kernel

Linux uses a monolithic kernel design. All core kernel services — process management, memory, filesystems, device drivers — run in a single address space (kernel space).

Advantages:

  • Good separation between user-space and kernel-space
  • Bugs in user space cannot corrupt the kernel
  • High performance (no context switches between kernel services)

Disadvantages:

  • A bug in one kernel component (e.g. a new device driver) can crash the entire system

Loadable Kernel Modules

Although the kernel is monolithic, its services can be extended at runtime using Loadable Kernel Modules (LKMs).

Modules can be:

  • Loaded with insmod or modprobe
  • Unloaded with rmmod
  • Listed with lsmod

This is how most device drivers are distributed — as modules that are only loaded when the corresponding hardware is present.


How the Kernel Interacts with the System

Linux has two interaction paths:

  1. System Calls — user-space programs request services from the kernel via the system call interface (read, write, open, fork, mmap, etc.)
  2. Hardware Interrupts — hardware devices signal the kernel via interrupts, which are handled by device driver interrupt service routines (ISRs)

md
User Space Program
      |
      | system call (e.g. read())
      v
System Call Interface
      |
      v
Kernel Service (e.g. VFS read)
      |
      v
Device Driver
      |
      v
Hardware

Hardware Event
      |
      | interrupt
      v
Interrupt Handler (ISR in driver)
      |
      v
Kernel processes event


Kernel Responsibilities

ResponsibilityDescription
Manage resourcesCPU time, memory, I/O bandwidth
Interface with hardwareDirect memory access, CPU registers
Provide APISystem calls for user-space programs

Kernel Source Directory Structure

The Linux kernel source tree is organised into well-defined directories:

DirectoryContents
arch/Architecture-specific files (arm, arm64, mips, x86, ...)
Documentation/Kernel documentation
drivers/Hardware support and loadable modules
fs/Filesystem implementations (ext4, vfat, nfs, ...)
include/Header files for kernel and user-space
init/System initialisation code
kernel/Core functions: scheduling, locking, timers
mm/Memory management
net/Network protocol implementations
scripts/Build and utility scripts
tools/User-space tools and utilities

Building the Kernel

The kernel is configured using the KConfig system — a menu-driven configuration framework that controls which features and drivers are compiled in.

KConfig

KConfig files are text-formatted files that define the kernel configuration options. They live alongside the code they configure, for example drivers/char/Kconfig:

md
menu "Character devices"
[...]
config DEVMEM
    bool "/dev/mem virtual device support"
    default y
    help
        Say Y here if you want to support the /dev/mem device.
[...]
endmenu

The most common tool for editing the kernel configuration interactively:

bash
make menuconfig

This provides a text-based graphical interface to browse and change configuration options.

KConfig Option Modes

Each driver or feature can be set to one of three modes:

ModeSymbolMeaning
Off (space)Not built or included
Built-in*Compiled directly into the kernel binary
ModuleMCompiled as a loadable module (.ko file)

Configuration changes are saved to a .config file in the kernel tree:

md
CONFIG_DEVMEM=y
CONFIG_USB=m
CONFIG_SOUND=n

Building After Configuration

bash
make -j$(nproc)      # compile the kernel
make modules         # compile all modules
make modules_install # install modules to sysroot

The output kernel image is typically found at:

  • arch/arm/boot/zImage (ARM 32-bit)
  • arch/arm64/boot/Image (ARM 64-bit)

Kernel Licensing

The Linux kernel is licensed under GPLv2. This has important implications for embedded Linux products:

  • If you use the kernel, you must make the source code available to recipients of the product
  • If you write a custom kernel module and distribute the product, you may need to share that module's source code

Linux Kernel Development

The authoritative Linux kernel source is maintained by Linus Torvalds:

`https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git`

For embedded Linux, vendor-specific kernel forks are common — these are maintained by SoC vendors (NXP, TI, Qualcomm, Broadcom) and add support for their specific hardware before those changes are upstreamed to the mainline kernel.


Final Thoughts

The Linux kernel is the most complex and powerful component in an embedded Linux system. Mastering it requires understanding:

  • How the kernel is structured (monolithic + loadable modules)
  • How user-space communicates with the kernel (system calls)
  • How hardware communicates with the kernel (interrupts)
  • How to configure and build the kernel for a specific target

md
Kernel Mastery Roadmap:
Understand user/kernel space separation
    |
    v
Learn system call interface
    |
    v
Understand device driver model
    |
    v
Configure kernel with menuconfig
    |
    v
Build and boot custom kernel on target

Everything that happens in an embedded Linux system passes through the kernel. It is the heart of the entire system.