Linux Device Model
Relevant source files
The following files were used as context for generating this wiki page:
The Linux Kernel Device Model unifies disparate driver models into a single framework. It consolidates data and operations into globally accessible structures to describe buses and the devices appearing under them. This model enables features like power management, hot plugging, and seamless "plug and play" capabilities across different architectures.
Sources: Documentation/driver-api/driver-model/overview.rst:11-20
Architecture and Components
The device model uses a common interface to represent bridges and devices. It moves common data fields from individual bus layers into a shared data structure, struct device. Bus-specific structures, such as struct pci_dev, contain an instance of struct device to integrate with the global model.
Sources: Documentation/driver-api/driver-model/overview.rst:35-42
Component Relationships
The following diagram illustrates the relationship between generic device structures and bus-specific implementations.
The diagram shows how PCIDevice embeds the generic Device structure and how both link to a specific Bus. Sources: Documentation/driver-api/driver-model/overview.rst:43-55
Bus and Device Management
The model provides a uniform set of attributes and callbacks for all buses. These include device discovery during probing, bus shutdown procedures, and power management transitions. The bus layer typically handles the fields of struct device, while individual device drivers avoid touching generic fields unless necessary.
Sources: Documentation/driver-api/driver-model/overview.rst:21-25, Documentation/driver-api/driver-model/overview.rst:56-60
Discovery and Probing Flow
The probing process follows a standardized sequence when a device appears on a bus.
The flowchart describes the transition from hardware discovery to driver binding and sysfs population. Sources: Documentation/driver-api/driver-model/overview.rst:75-85
Sysfs User Interface
The device model exports a hierarchical view of the system to userspace via the sysfs virtual filesystem. When the kernel inserts a device into the tree, it creates a corresponding directory in /sys.
Sources: Documentation/driver-api/driver-model/overview.rst:64-74
| Layer | Exported Attributes | Description |
|---|---|---|
| Global | name | Reports the name of the device. |
| Global | power | Reports and sets the current power state. |
| Bus (e.g., PCI) | irq, resource | Bus-specific hardware parameters. |
| Device Driver | Custom attributes | Tunable interfaces or device-specific data. |
Sources: Documentation/driver-api/driver-model/overview.rst:80-92
ACPI and Hardware Abstraction
On architectures like Armv8/Armv9, the device model interacts with ACPI (Advanced Configuration and Power Interface). ACPI uses the _DSD (Device Specific Data) object to convey properties to drivers in a standardized format.
Sources: Documentation/arch/arm64/arm-acpi.rst:11-15, Documentation/arch/arm64/arm-acpi.rst:196-202
Power Control and Clocks
ACPI abstracts power control through Power Resource Objects and methods like _PS0 (Full On) and _PS3 (Full Off). The kernel assumes firmware initializes clocks to working values before handing control to the OS. Drivers invoke ACPI methods to change power states rather than manipulating hardware registers directly.
Sources: Documentation/arch/arm64/arm-acpi.rst:242-255, Documentation/arch/arm64/arm-acpi.rst:274-280
Programming Interfaces and Context
Drivers interact with the device model through specific kernel contexts.
- User Context: Occurs during system calls or module operations. The
currentpointer is valid, and code may sleep. - Interrupt Context: Hardware interrupts service hardware events. Code must be fast and cannot sleep.
- Software Interrupts: Includes softirqs and tasklets for deferred interrupt handling.
Sources: Documentation/kernel-hacking/hacking.rst:25-55
Common Management Routines
Drivers use several standard macros and functions for lifecycle management.
/* Example of structure initialization using designated initializers */
static struct block_device_operations opt_fops = {
.open = opt_open,
.release = opt_release,
.ioctl = opt_ioctl,
};
/* Module initialization and exit */
module_init(my_driver_init);
module_exit(my_driver_exit);
Sources: Documentation/kernel-hacking/hacking.rst:438-445, Documentation/kernel-hacking/hacking.rst:328-335
Summary
The Linux Device Model provides the essential infrastructure for hardware abstraction, power management, and userspace visibility. By centralizing bus and device logic, it reduces duplication across drivers and ensures consistent behavior for complex features like ACPI and hot-plugging. This unification is critical for maintaining the kernel's portability across diverse hardware architectures.
Sources: Documentation/driver-api/driver-model/overview.rst:11-30, Documentation/gpu/introduction.rst:10-15