Skip to content

Drivers And Device Model

Imported from _research/manual-study-linux/drivers-device-model.md.

Drivers And Device Model

Status: implemented source-backed volume.

Source Surface

  • drivers/base/core.c: device registration and core driver-model lifecycle.
  • drivers/base/dd.c: driver/device binding and probe flow.
  • include/linux/device.h: struct device and public device APIs.

Entry Points

Device code enters the core through initialization and registration helpers such as device_initialize(), device_add(), device_register(), and removal helpers in drivers/base/core.c. include/linux/device.h declares device_register(), device_initialize(), and device_add() around lines 1159-1162.

Driver binding flows through drivers/base/dd.c: driver_probe_device() at line 892 attempts a bind, __driver_probe_device() at line 827 checks whether the device can be probed, and really_probe() at line 652 performs the actual binding sequence.

Core Data Model

struct device is the central object. include/linux/device.h documents it around lines 618-699 and defines it at line 701. It embeds a kobject, parent pointer, bus pointer, driver pointer, platform data, driver data, device links, power-management state, DMA metadata, firmware node, class, groups, and release callback.

The important design point: most subsystems do not use bare struct device. They embed it in a larger subsystem-specific object. That makes the generic device model a shared ownership and discovery substrate, not the whole driver.

Probe Flow

The probe sequence is a staged bind:

  1. Confirm the device is registered and not already bound.
  2. Check supplier links and defer if dependencies are missing.
  3. Set the driver pointer.
  4. Configure pinctrl/DMA/sysfs/power-domain state.
  5. Call the bus or driver probe function.
  6. Add driver groups and sync state.
  7. Mark the driver bound.
  8. On failure, unwind sysfs, DMA, links, and driver assignment.

This shape is visible in really_probe() at lines 652-775. call_driver_probe() at lines 621-650 chooses bus-level probe before driver-level probe and normalizes common probe return meanings such as -EPROBE_DEFER.

Concurrency And Lifetime

Device objects are reference-counted through the embedded kobject model and guarded by device locks during bind/unbind. The probe path also accounts for asynchronous probing and dependency deferral. A failed probe is not a partial success: Linux has explicit unwind labels for each initialized stage.

Rust Translation

A Rust driver API should preserve the staged lifecycle:

  • Device<T> embeds generic device metadata plus subsystem-specific state.
  • Driver trait exposes probe() and remove/shutdown methods.
  • Probe returns a typed BoundDevice only after all required resources are initialized.
  • Resource acquisition uses RAII guards so unwind is automatic.
  • Deferred probe is an explicit result, not a generic error string.

AI-Native Translation

For agent runtimes, the device model suggests a plugin lifecycle: discovered resources, dependency links, activation probes, sysfs-like introspection, and automatic cleanup if activation fails. Agents should not call plugin code until the runtime has completed dependency and capability binding.

  • file-notes/linux__drivers__base__core.c.md