Skip to main content

Understanding Peripheral Drivers Through the Linux Kernel Device Model

·725 words·4 mins
Linux Kernel Device Drivers Kobject Device Model Embedded Linux
Table of Contents

1. Introduction: Object-Oriented Thinking in the Kernel
#

Modern Linux treats devices, buses, and drivers using a highly object-oriented architecture. The kernel models system components using reusable abstractions that resemble class inheritance:

  • kobject → fundamental building block
  • kset → grouping mechanism
  • device / driver / bus → higher-level abstractions
  • subsystems → real-world peripherals such as PCI, USB, I2C

This design establishes a clean hierarchy that allows the kernel to manage the complexity of heterogeneous hardware in a consistent way.

2. The Foundation: kobject — The Core Kernel Object
#

At the base of Linux’s device model is kobject, a small but crucial structure embedded inside most driver-related data structures. A kobject provides:

  • Naming
  • Reference counting
  • Parent/child hierarchy
  • Sysfs linkage
  • Type information (kobj_type)

struct kobject
#

struct kobject {
    const char *name;
    struct list_head entry;
    struct kobject *parent;      // Parent in the object hierarchy
    struct kset *kset;
    struct kobj_type *ktype;     // Type definition and callbacks
    struct kernfs_node *sd;      // Sysfs directory entry
    struct kref kref;            // Reference counting
    unsigned int state_initialized:1;
    unsigned int state_in_sysfs:1;
    unsigned int state_add_uevent_sent:1;
    unsigned int state_remove_uevent_sent:1;
    unsigned int uevent_suppress:1;
};

struct kobj_type
#

This structure defines the behavior of a kobject, including sysfs operations and release logic.

struct kobj_type {
    void (*release)(struct kobject *kobj);
    const struct sysfs_ops *sysfs_ops;
    const struct attribute_group **default_groups;
    const struct kobj_ns_type_operations *(*child_ns_type)(struct kobject *);
    const void *(*namespace)(struct kobject *);
    void (*get_ownership)(struct kobject *, kuid_t *, kgid_t *);
};

Together, kobject + kobj_type implement the kernel’s base class pattern.

3. Building Up: Devices, Drivers, and Buses
#

From this foundation, Linux constructs the three central abstractions:

  • struct device — represents a hardware device
  • struct device_driver — represents a driver that manages devices
  • struct bus_type — represents a physical or logical bus that connects devices and drivers

3.1 struct device — The Universal Device Object
#

Every device in the kernel—from PCI devices to USB endpoints—eventually becomes a struct device.

struct device {
    struct device *parent;
    struct kobject kobj;           // Embedded kobject
    const char *init_name;
    const struct device_type *type;

    struct bus_type *bus;          // Bus this device is attached to
    struct device_driver *driver;  // Bound driver

    struct device_node *of_node;   // Device Tree node (if applicable)
    dev_t devt;                     // Char/block device number

    struct class *class;           // Functional grouping (input, net, etc.)
    struct klist_node knode_class;

    void (*release)(struct device *dev);
};

3.2 struct device_driver — The Driver Abstraction
#

A driver contains probe/remove callbacks and its own embedded kobject.

struct device_driver {
    const char *name;
    struct bus_type *bus;

    const struct of_device_id   *of_match_table;
    const struct acpi_device_id *acpi_match_table;

    int (*probe)(struct device *dev);
    int (*remove)(struct device *dev);
    void (*shutdown)(struct device *dev);
    int (*suspend)(struct device *dev, pm_message_t state);
    int (*resume)(struct device *dev);

    struct driver_private *p;
};

3.3 struct bus_type — Matching Devices and Drivers
#

The bus provides the matching logic and dispatches probe/remove to the driver.

struct bus_type {
    const char *name;
    int (*match)(struct device *dev, struct device_driver *drv);
    int (*uevent)(struct device *dev, struct kobj_uevent_env *env);
    int (*probe)(struct device *dev);
    int (*remove)(struct device *dev);

    struct subsys_private *p;
};

Examples of kernel buses:

  • PCI
  • USB
  • I2C
  • SPI
  • Platform bus

4. Extending the Model: Subsystems and Real Hardware
#

Every real hardware subsystem extends the generic device and driver structures by embedding them inside richer, bus-specific structures.

4.1 PCI — struct pci_dev
#

struct pci_dev {
    struct list_head bus_list;
    struct pci_bus *bus;
    struct pci_bus *subordinate;
    struct device dev;     // Generic device embedded here
};

The kernel uses container_of() macros such as to_pci_dev() to recover the extended structure.

4.2 USB — struct usb_device
#

USB follows the same pattern:

  • usb_device embeds a struct device
  • Matching happens via USB IDs
  • Drivers embed struct device_driver

4.3 I2C — struct i2c_client
#

I2C devices are represented as:

struct i2c_client {
    unsigned short addr;
    struct device dev;   // Embedded generic device
    ...
};

Each bus follows the same expansion structure:

  1. Base object (device)
  2. Bus-specific extended object (pci_dev, usb_device, i2c_client)
  3. Bus-specific driver (pci_driver, usb_driver, i2c_driver)
  4. Containment and inheritance via embedded kobject

5. Summary: A Unified, Object-Oriented Device Model
#

The Linux kernel’s device model provides:

  • A consistent framework for representing hardware
  • Reusable abstractions (kobject, kset)
  • Logical inheritance via embedded structures
  • Unified matching logic across PCI, USB, I2C, SPI, etc.
  • sysfs exposure of all device relationships

This object-oriented approach allows Linux to support a vast range of peripherals through the same set of abstractions, enabling maintainability, extensibility, and a clear hierarchical view of complex hardware systems.

Related

Wind River Linux: Pioneering Embedded Systems for the Edge Era
·681 words·4 mins
Embedded Linux WindRiver Linux Yocto Project
Wind River Leads Global Commercial Embedded Linux Development
·822 words·4 mins
Embedded Linux WindRiver Linux
Updating Embedded Linux System Images: Wind River Linux vs Ubuntu Core
·1027 words·5 mins
Embedded Linux Linux System Image Update Wind River Linux