Device Drivers
What a device driver is
A device driver is kernel code that mediates between the generic OS I/O interface and the specific hardware registers of a particular device. It translates high-level commands (read_block(device, block_number, buffer)) into device-specific operations (write command to control register, wait for interrupt, read status, copy data from DMA region).
Drivers are the largest body of code in a modern kernel. The Linux source tree is approximately 70% drivers.
Driver structure
A typical block-device driver implements:
| Function | Purpose |
|---|---|
probe() | Detect and initialise the device |
open() | Prepare the device for I/O; allocate per-open state |
strategy() or request() | Queue a read/write request |
interrupt_handler() | Handle completion interrupts |
ioctl() | Device-specific control operations (eject, format, query geometry) |
close() | Clean up per-open state |
remove() | Shut down and unregister |
Character-device drivers are similar but operate on byte streams rather than blocks.
Driver binding
How does the kernel know which driver to load for a device?
- PCI/USB enumeration: the device reports a vendor ID and device ID. The kernel’s device table maps these to drivers.
- Device Tree (ARM, embedded): the hardware description lists devices and their memory-mapped addresses; compatible strings map to drivers.
- ACPI (x86): the firmware describes devices; the kernel matches them by hardware ID.
Kernel vs user-space drivers
Most drivers run in kernel mode for performance (low latency, direct hardware access) and because the interface between drivers and the kernel’s I/O subsystems (block layer, network stack) is a kernel-internal API.
Some drivers run in user space (e.g., FUSE file systems, USB drivers via libusb, GPU drivers partially via DRM). User-space drivers are safer (a crash does not take down the kernel) but slower (every hardware access requires a system call or memory-map setup).
DMA and drivers
Device drivers for DMA-capable devices must manage DMA mappings: translating between CPU virtual addresses and device bus addresses. On systems with an IOMMU (Intel VT-d, AMD-Vi), DMA addresses are translated through a separate page table that restricts which physical memory each device can access — preventing malicious or buggy devices from reading arbitrary kernel memory.
Summary
- Device drivers translate generic OS I/O requests into device-specific hardware operations.
- They follow a standard structure: probe, open, strategy/request, interrupt handler, ioctl, close.
- Device enumeration (PCI IDs, ACPI, Device Tree) matches drivers to hardware.
- User-space drivers are safer but slower; kernel drivers are faster but can crash the system.
- IOMMU provides DMA protection analogous to MMU-provided memory protection for CPUs.