A device driver is a kernel component that manages the communication between the operating system and a specific piece of hardware. Drivers abstract hardware details so that user-space applications and other kernel subsystems can interact with devices through a uniform interface. In Linux, all drivers participate in a unified driver model that governs how devices are discovered, bound to a driver, and removed from the system.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/deelerdev/linux/llms.txt
Use this file to discover all available pages before exploring further.
Driver types
Linux supports several categories of drivers, each suited to a different bus topology or device class.Platform drivers
Platform drivers
Platform drivers manage devices that are directly addressable from the CPU bus and are not discoverable at runtime — typically peripherals integrated into a system-on-chip (SoC). The kernel learns about these devices from the Device Tree or ACPI tables. A platform driver registers with
platform_driver_register() and handles a struct platform_device.PCI drivers
PCI drivers
PCI drivers bind to devices enumerated on the PCI bus. The kernel automatically discovers PCI devices at boot and matches them against registered drivers using the vendor ID and device ID in a
struct pci_device_id table. PCI drivers register using pci_register_driver().USB drivers
USB drivers
USB drivers bind to interfaces on USB devices. The USB core enumerates connected devices and matches them by vendor ID, product ID, class, or subclass. USB drivers register with
usb_register().I2C drivers
I2C drivers
I2C drivers control devices on the I2C bus. The I2C core matches drivers to devices by name or by a
struct i2c_device_id table. Drivers register with i2c_add_driver().Character device drivers
Character device drivers
Character device drivers expose a device to user space as a file under
/dev. User-space programs call open(), read(), write(), and ioctl() on the device file. The driver implements these operations through a struct file_operations.Block device drivers
Block device drivers
Block device drivers manage storage devices that transfer data in fixed-size blocks. They expose a request queue to the block layer, which handles I/O scheduling before dispatching requests to the driver.
Buses, devices, and drivers
The Linux driver model is built on three objects: buses, devices, and drivers.- A bus (
struct bus_type) is a communication channel between the processor and one or more devices. Every device is attached to a bus — even devices with no physical bus use the virtual platform bus. - A device (
struct device) represents a hardware or virtual device in the system. Each device belongs to exactly one bus and holds a reference to the driver currently managing it. - A driver (
struct device_driver) represents a driver as a whole, not a particular device instance. A single driver can manage multiple devices simultaneously.
match() callback for each one. When a device is registered, the bus iterates over all registered drivers and calls match() for each. A positive return from match() triggers a probe() call.
Device discovery and probe()
Theprobe() callback is the driver’s entry point for a specific device. The kernel calls it in task context after match() succeeds. Inside probe() the driver must:
- Verify that the hardware is present and behaves as expected.
- Allocate and initialize any data structures needed to manage the device.
- Claim hardware resources such as memory regions, I/O ports, and interrupt lines.
- Register any sub-devices or interfaces that higher-level subsystems will use.
probe() returns 0, the driver core considers the driver successfully bound to the device. If it returns a negative error code, all claimed resources must already have been released. Return -EPROBE_DEFER if a resource the driver depends on — such as a clock, regulator, or GPIO — is not yet available; the core will retry probe() later.
The driver lifecycle
Every driver follows the same lifecycle from the moment the kernel matches it to a device until the device is removed.Match
The bus
match() callback compares the device’s identity (vendor/device ID, Device Tree compatible string, or name) against the driver’s supported-device table.Probe
The driver’s
probe() callback runs. The driver acquires resources, initializes hardware, and signals success by returning 0.Operate
The device is live. User space, other kernel subsystems, or interrupt handlers communicate with the hardware through the driver’s registered interfaces.
Suspend / resume (optional)
If the system enters a sleep state, the driver’s
suspend() and resume() callbacks (or dev_pm_ops) quiesce and restore the device.Key header files
Every driver includes a small set of core headers. The exact set depends on the bus type and features used.| Header | Purpose |
|---|---|
<linux/module.h> | module_init(), module_exit(), MODULE_LICENSE(), and related macros |
<linux/device.h> | struct device, struct device_driver, device attributes |
<linux/device/bus.h> | struct bus_type, bus_register(), bus_for_each_dev() |
<linux/platform_device.h> | struct platform_device, struct platform_driver, platform_driver_register() |
<linux/interrupt.h> | request_irq(), free_irq(), IRQ flags |
<linux/fs.h> | struct file_operations for character devices |
<linux/cdev.h> | struct cdev, cdev_init(), cdev_add() |
<linux/pm.h> | struct dev_pm_ops for power management callbacks |
Linux device model
Dive into struct device, struct bus_type, sysfs layout, and power management integration.
Write your first driver
Step-by-step walkthrough of a minimal character device driver and a platform driver.
