Kernel Development Environment Setup
Complete guide for setting up a safe kernel development environment.
Quick Start (Recommended)
Option 1: Virtual Machine (Safest)
Using VirtualBox
- Download and Install VirtualBox
# Ubuntu/Debian sudo apt-get install virtualbox # Or download from: https://www.virtualbox.org/ - Create VM
- OS: Linux
- Version: Ubuntu 22.04 LTS (or preferred distro)
- RAM: 2GB minimum (4GB recommended)
- Disk: 20GB minimum (40GB recommended)
- Install Guest Additions
sudo apt-get install build-essential dkms linux-headers-$(uname -r) # Insert Guest Additions CD from Devices menu sudo sh /media/*/VBoxLinuxAdditions.run - Setup Shared Folder
- VirtualBox → Settings → Shared Folders
- Add folder: e.g.,
~/kernel-dev→/home/user/host - In VM:
sudo usermod -aG vboxsf $USER # Logout and login
- Take Snapshot
# Before any testing, take snapshot in VirtualBox # VM → Snapshots → Take
Using QEMU/KVM (Advanced)
# Install QEMU
sudo apt-get install qemu-kvm libvirt-daemon-system
# Create VM
virt-install \
--name kernel-dev \
--ram 2048 \
--disk path=/var/lib/libvirt/images/kernel-dev.qcow2,size=20 \
--vcpus 2 \
--os-type linux \
--os-variant ubuntu22.04 \
--graphics none \
--console pty,target_type=serial \
--location 'http://archive.ubuntu.com/ubuntu/dists/jammy/main/installer-amd64/' \
--extra-args 'console=ttyS0,115200n8 serial'
Option 2: Docker Container (Limited)
Warning: Limited functionality, can’t load kernel modules normally.
# Dockerfile
FROM ubuntu:22.04
RUN apt-get update && apt-get install -y \
build-essential \
linux-headers-generic \
kmod \
vim \
git
WORKDIR /workspace
# Build and run
docker build -t kernel-dev .
docker run -it --privileged kernel-dev
Option 3: WSL2 on Windows
# Enable WSL2
wsl --install
# Install Ubuntu
wsl --install -d Ubuntu-22.04
# In WSL:
sudo apt-get update
sudo apt-get install build-essential linux-headers-$(uname -r)
Required Software
Essential Packages
# Ubuntu/Debian
sudo apt-get update
sudo apt-get install -y \
build-essential \
linux-headers-$(uname -r) \
git \
vim \
libncurses-dev \
flex \
bison \
libssl-dev \
libelf-dev
# Fedora/RHEL
sudo dnf group install "Development Tools"
sudo dnf install kernel-devel kernel-headers
# Arch
sudo pacman -S base-devel linux-headers
Debugging Tools
# Ubuntu/Debian
sudo apt-get install -y \
gdb \
crash \
kexec-tools \
systemtap \
linux-tools-generic \
trace-cmd \
kernelshark
# For static analysis
sudo apt-get install -y sparse cppcheck
Editor Setup
VS Code with Extensions
# Install VS Code
snap install code --classic
# Recommended extensions:
# - C/C++
# - Linux Kernel Helper
# - GitLens
.vscode/c_cpp_properties.json:
{
"configurations": [
{
"name": "Linux",
"includePath": [
"${workspaceFolder}/**",
"/lib/modules/*/build/include"
],
"defines": ["__KERNEL__"],
"compilerPath": "/usr/bin/gcc"
}
]
}
Vim Setup
" ~/.vimrc for kernel development
set tabstop=8
set shiftwidth=8
set noexpandtab
syntax on
filetype plugin indent on
" Kernel style settings
autocmd FileType c setlocal noexpandtab shiftwidth=8 softtabstop=8
Kernel Source Setup
Download Kernel Source
# Option 1: Distribution kernel source
apt-get source linux
# Option 2: Mainline kernel
git clone https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
cd linux
# Option 3: Stable kernel
wget https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.6.tar.xz
tar xf linux-6.6.tar.xz
cd linux-6.6
Configure Kernel
# Use current config
cp /boot/config-$(uname -r) .config
# Or start from scratch
make menuconfig
# Enable debugging options
scripts/config --enable DEBUG_INFO
scripts/config --enable DEBUG_KERNEL
scripts/config --enable DEBUG_SPINLOCK
scripts/config --enable KGDB
scripts/config --enable KGDB_SERIAL_CONSOLE
Build Kernel (Optional)
# Build kernel
make -j$(nproc)
# Build modules
make modules
# Install (in VM only!)
sudo make modules_install
sudo make install
sudo update-grub
sudo reboot
Development Workflow
Project Structure
~/kernel-dev/
├── drivers/ # Your driver code
│ ├── mydriver/
│ │ ├── mydriver.c
│ │ ├── mydriver.h
│ │ └── Makefile
│ └── tests/
│ └── test_mydriver.c
├── linux/ # Kernel source (reference)
├── scripts/ # Helper scripts
│ ├── load.sh
│ ├── unload.sh
│ └── test.sh
└── notes/ # Documentation
Helper Scripts
scripts/load.sh:
#!/bin/bash
MODULE="mydriver"
echo "Loading $MODULE..."
sudo dmesg -C # Clear dmesg
sudo insmod ${MODULE}.ko "$@"
echo "Module loaded. dmesg output:"
dmesg | tail -20
scripts/unload.sh:
#!/bin/bash
MODULE="mydriver"
echo "Unloading $MODULE..."
sudo rmmod $MODULE
echo "Module unloaded. dmesg output:"
dmesg | tail -10
scripts/test.sh:
#!/bin/bash
set -e
make clean
make
./load.sh
# Run tests
echo "Running tests..."
./tests/test_mydriver
./unload.sh
Git Configuration
# Configure git for kernel development
git config user.name "Your Name"
git config user.email "you@example.com"
# Kernel-specific settings
git config format.signoff true
git config sendemail.smtpserver smtp.gmail.com
git config sendemail.smtpport 587
.gitignore:
*.o
*.ko
*.mod.c
*.mod
*.order
*.symvers
.tmp_versions/
modules.order
Module.symvers
.*.cmd
Testing Setup
Serial Console (For QEMU)
# Start QEMU with serial
qemu-system-x86_64 \
-kernel bzImage \
-append "console=ttyS0" \
-serial stdio \
-enable-kvm \
-m 2G
KGDB Setup
Target (VM) kernel parameters:
kgdboc=ttyS0,115200 kgdbwait
Host GDB:
gdb vmlinux
(gdb) target remote /dev/ttyS0
(gdb) break sys_init_module
(gdb) continue
Debugging Configuration
Enable Debug Options
# In kernel build
CONFIG_DEBUG_KERNEL=y
CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_INFO_DWARF4=y
CONFIG_GDB_SCRIPTS=y
CONFIG_FRAME_POINTER=y
CONFIG_KGDB=y
CONFIG_KGDB_SERIAL_CONSOLE=y
CONFIG_DEBUG_SPINLOCK=y
CONFIG_DEBUG_MUTEXES=y
CONFIG_PROVE_LOCKING=y
CONFIG_DEBUG_ATOMIC_SLEEP=y
CONFIG_KASAN=y # Address sanitizer
CONFIG_UBSAN=y # Undefined behavior sanitizer
Dynamic Debug
# Enable all debug messages for your module
echo 'module mydriver +p' > /sys/kernel/debug/dynamic_debug/control
# Enable debug for specific file
echo 'file mydriver.c +p' > /sys/kernel/debug/dynamic_debug/control
# Enable debug for specific function
echo 'func my_init +p' > /sys/kernel/debug/dynamic_debug/control
Performance Profiling
ftrace
# Enable function tracer
echo function > /sys/kernel/debug/tracing/current_tracer
# Trace specific module
echo ':mod:mydriver' > /sys/kernel/debug/tracing/set_ftrace_filter
# Start tracing
echo 1 > /sys/kernel/debug/tracing/tracing_on
# View trace
cat /sys/kernel/debug/tracing/trace
perf
# Record
perf record -g -a
# Report
perf report
# Live top
perf top
Safety Checklist
Before each test session:
- Code committed to git
- VM snapshot taken
- Backup of important files
- Serial console connected (if using QEMU)
- Emergency reboot method ready
- Not on production machine
- SysRq keys enabled:
echo 1 > /proc/sys/kernel/sysrq
Quick Recovery
# SysRq emergency reboot
echo b > /proc/sysrq-trigger
# Or keyboard
Alt + SysRq + R, E, I, S, U, B
Next Steps
- Clone this tutorial repository
- Set up VM or development environment
- Test with simple hello world module
- Work through examples progressively
- Start your own driver project
Remember: Always develop in a safe, isolated environment!