| name | linux-kernel-development |
| description | Use when configuring, building, patching, or reviewing Linux kernel code for embedded targets (automotive IVI, HUD, RSE on Linux). Covers Kconfig/menuconfig, defconfig, kernel source tree structure, Kbuild, cross-compilation, applying patches with git/quilt, and kernel versioning for BSP work.
|
| argument-hint | <board-or-topic> [configure|build|patch|review] |
Linux Kernel Development
Practices for configuring, building, and patching the Linux kernel for embedded
automotive IVI, HUD, and RSE targets.
Source of truth:
When to Use This Skill
- Configuring the kernel for a new board with
menuconfig or defconfig.
- Adding or modifying
Kconfig options and Kbuild targets.
- Cross-compiling the kernel for ARM/AArch64 from an x86 host.
- Applying or creating kernel patches with
git am or quilt.
- Saving a reproducible board configuration with
savedefconfig.
- Reviewing kernel code or driver integration for automotive BSP work.
Kernel Source Tree Overview
linux/
arch/ # architecture-specific code (arm, arm64, x86, ...)
block/ # block layer
drivers/ # device drivers (char, net, usb, video, ...)
fs/ # filesystems
include/ # public headers (linux/, asm/, uapi/)
init/ # kernel init code (main.c, Kconfig)
ipc/ # IPC subsystem
kernel/ # core kernel (sched, lock, time, panic, ...)
lib/ # kernel library functions
mm/ # memory management
net/ # networking stack
scripts/ # build scripts and tools
sound/ # ALSA audio subsystem
tools/ # userspace tools (perf, bpftool, ...)
Documentation/ # kernel documentation (RST)
Kconfig — Kernel Configuration
The kernel uses Kconfig for feature selection. Configuration is stored in .config.
Common config targets
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- menuconfig
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- <board>_defconfig
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- olddefconfig
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- listnewconfig
Config fragments (merge_config.sh)
scripts/kconfig/merge_config.sh arch/arm64/configs/myboard_defconfig \
fragments/enable_cgroups.config \
fragments/enable_bpf.config
This saves the merged result into .config.
Building the Kernel
export ARCH=arm64
export CROSS_COMPILE=aarch64-linux-gnu-
export KDIR=/path/to/linux
make -j$(nproc) Image
make -j$(nproc) dtbs
make -j$(nproc) modules
make INSTALL_MOD_PATH=/path/to/staging modules_install
For ARM 32-bit:
export ARCH=arm
export CROSS_COMPILE=arm-linux-gnueabihf-
make <board>_defconfig
make -j$(nproc) zImage dtbs modules
Out-of-tree build directory (O=)
mkdir -p /build/myboard
make O=/build/myboard ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- myboard_defconfig
make O=/build/myboard ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j$(nproc) Image dtbs
Kbuild — Kernel Build System
Every directory under the kernel tree contains a Makefile (called a Kbuild Makefile):
obj-$(CONFIG_MY_DRIVER) += mydriver.o
mydriver-objs := mydriver_core.o mydriver_hw.o
obj-y → built into the kernel.
obj-m → built as a module.
obj-$(CONFIG_SYMBOL) → conditional on Kconfig symbol.
Corresponding Kconfig entry:
config MY_DRIVER
tristate "My hardware driver"
depends on I2C
help
Driver for my custom hardware.
Say M to build as a module.
Add to parent Kconfig and Makefile:
obj-y += mydriver/
# drivers/Kconfig
source "drivers/mydriver/Kconfig"
Kernel Versioning
The kernel version is in the top-level Makefile:
VERSION = 6
PATCHLEVEL = 1
SUBLEVEL = 0
EXTRAVERSION = -myboard
uname -r on the running system returns <VERSION>.<PATCHLEVEL>.<SUBLEVEL><EXTRAVERSION>.
Set CONFIG_LOCALVERSION in .config to add a local suffix: CONFIG_LOCALVERSION="-ivi".
Patching the Kernel
Using git (recommended for BSP trees)
git am 0001-fix-gpio-timeout.patch
git apply 0001-fix-gpio-timeout.patch
git format-patch -1 HEAD
git format-patch HEAD~3..HEAD
Using quilt (for patch stacks on top of a release tarball)
quilt push
quilt pop
quilt push -a
quilt refresh
quilt new 0001-my-fix.patch
quilt add drivers/mydriver/mydriver_core.c
quilt refresh
Saving a Board defconfig
After configuring with menuconfig, save a minimal defconfig (only non-default values):
make ARCH=arm64 savedefconfig
cp defconfig arch/arm64/configs/myboard_defconfig
Checking Kernel Config Symbols
grep CONFIG_MY_FEATURE .config
grep DMA .config | grep -v "^#"
zcat /proc/config.gz | grep CONFIG_MY_FEATURE
Prerequisites
- Linux host machine (Ubuntu 20.04 LTS or Debian 11 recommended).
- Cross-compilation toolchain:
arm-linux-gnueabihf-gcc or aarch64-linux-gnu-gcc.
- Target board with serial console access (USB-to-UART adapter).
ssh access to target (optional but recommended).
Step-by-Step Workflows
Step 1: Set up the cross-compilation environment
Set ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- (adjust for your target architecture).
Step 2: Configure the kernel
Start from the board defconfig: make <board>_defconfig; adjust with make menuconfig.
Step 3: Apply patches
Use git am for patch series or quilt push for a quilt patch stack; review each patch.
Step 4: Build the kernel
Run make -j$(nproc); treat all new warnings as errors (W=1 for stricter output).
Step 5: Deploy and boot
Copy Image / zImage and DTB to the boot partition or TFTP server; boot and verify uname -r.
Troubleshooting
make fails with scripts/basic/fixdep: not found — run make scripts_basic first; or clean with make mrproper and reconfigure.
Linux version mismatch when loading module — the module was built against a different kernel version; rebuild with KERNEL_SRC pointing to the running kernel tree.
- Patch fails to apply — check context with
patch --dry-run; resolve conflicts manually and add a fixup commit.
- Kernel panics on boot — add
earlycon and initcall_debug to kernel cmdline; capture serial output for the full log.
Pre-Commit Checklist
References