driver-know-hows

device driver related stuff

View on GitHub

Kernel Development Environment Setup

Complete guide for setting up a safe kernel development environment.

Option 1: Virtual Machine (Safest)

Using VirtualBox

  1. Download and Install VirtualBox
    # Ubuntu/Debian
    sudo apt-get install virtualbox
       
    # Or download from: https://www.virtualbox.org/
    
  2. Create VM
    • OS: Linux
    • Version: Ubuntu 22.04 LTS (or preferred distro)
    • RAM: 2GB minimum (4GB recommended)
    • Disk: 20GB minimum (40GB recommended)
  3. 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
    
  4. 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
      
  5. 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:

Quick Recovery

# SysRq emergency reboot
echo b > /proc/sysrq-trigger

# Or keyboard
Alt + SysRq + R, E, I, S, U, B

Next Steps

  1. Clone this tutorial repository
  2. Set up VM or development environment
  3. Test with simple hello world module
  4. Work through examples progressively
  5. Start your own driver project

Remember: Always develop in a safe, isolated environment!