Linux Device Model Explained: How Buses, Devices and Drivers Work Together-Free Linux Device Drivers Course

Linux Device Model Explained: How Buses, Devices and Drivers Work Together
Free Linux Kernel Development Course — Kernel 6.12+ Edition
📘 Beginner Friendly
🐧 Kernel 6.12+ Updated
🆓 100% Free

If you are starting a free Linux kernel development course or working through a free Linux device drivers course, the very first mental model you need is the Linux Device Model (LDM). Every character driver, block driver, network driver, and platform driver you will ever write sits on top of this model. Once you understand how buses, devices, and drivers cooperate inside the kernel, writing your own drivers becomes far less mysterious.

In this lecture of our free embedded systems course, we rebuild the Linux Device Model from first principles, using the current kernel source tree (6.12 and later) instead of outdated references, and we visualize every relationship using clean inline diagrams — no screenshots, no external images, just concepts you can actually study and remember.

Topics covered in this free Linux kernel development course lecture:
Linux Device Model Bus Drivers sysfs probe() / remove() Platform Bus Kernel Frameworks

What You Will Learn

  • What the Linux Device Model actually is, and why the kernel is organized around it
  • Why “every device must live on a bus,” including logical and pseudo-buses
  • How /sys/bus, /sys/devices, and /sys/class relate to each other
  • How device discovery triggers probe() and remove() in a driver
  • The difference between registering with a bus and registering with a kernel framework
  • What changed in the Linux Device Model on modern 6.x kernels
  • Common mistakes beginners make when reasoning about bus/device/driver binding

Prerequisites

This lecture assumes basic familiarity with:

  • C programming fundamentals (structs, function pointers)
  • Basic Linux command-line usage
  • A general idea of what a kernel module is (covered in our earlier free Linux kernel development course lectures on loadable kernel modules)

You do not need any prior driver-writing experience — this is where that journey begins.

What Is the Linux Device Model?

The Linux Device Model is the internal bookkeeping system the kernel uses to track every piece of hardware (and some purely logical devices) present on a running system, along with the drivers responsible for them. Instead of every subsystem inventing its own way to represent hardware, the kernel provides one unified core — commonly called the driver core — that all bus types plug into.

This unification is what makes /sys possible. Whether you plug in a USB webcam, a PCIe network card, or an I2C temperature sensor, the resulting device object ends up represented the same structural way internally, even though the underlying hardware protocols are completely different.

Why Every Device Must Live on a Bus

A foundational rule of the Linux Device Model is simple to state: every device must be attached to a bus. This is intuitive for physical buses — a USB mouse obviously sits on the USB bus, an NVMe SSD sits on the PCIe bus. But the rule also covers hardware that has no real electrical bus at all.

For SoC-integrated peripherals that are wired directly into the processor with no discoverable bus protocol, the kernel uses a pseudo-bus called the platform bus. This lets even “busless” hardware follow the same registration pattern as everything else, which keeps the driver model consistent across the entire kernel.

How /sys/bus Organizes Hardware
/sys/bus/
usb/
i2c/
pci/
spi/
platform/ (pseudo-bus)
devices/ (what is plugged in)
drivers/ (what can drive it)

Each bus folder under /sys/bus/ is maintained by a bus driver, which is either compiled into the kernel image or auto-loaded during boot. The bus driver’s job is to enumerate hardware that appears on it and match each device to a compatible driver.

The Bus, Device, and Driver Triad

The Linux Device Model revolves around three cooperating entities. Understanding their separate responsibilities removes most of the early confusion beginners face in this free Linux device drivers course.

Entity Responsibility Example
Bus Discovers hardware and matches it with a registered driver USB, I2C, PCI, Platform
Device Represents one physical or logical hardware instance An I2C RTC chip at address 0x68
Driver Provides the code that operates a specific class of device An RTC driver implementing read/set-time

How Device Discovery Works: probe() and remove()

When a bus driver detects a new device and successfully pairs it with a registered driver, the kernel invokes that driver’s probe() callback. This is where the driver allocates resources, requests interrupts, maps memory, and initializes the hardware. When the device is removed, or the module is unloaded, the matching remove() (sometimes disconnect()) callback runs to release everything cleanly.

Device Binding Lifecycle
1. Hardware appears
→
2. Bus enumerates it
→
3. Matched with driver
→
4. probe() runs
→
5. Device in use
→
6. remove() runs

Registering with a Kernel Framework vs Registering with a Bus

A well-designed modern driver typically does two separate registrations, and mixing these up is one of the most common sources of confusion in any free Linux device drivers course:

Registration Type Purpose Example API
Kernel framework Plugs your driver into a subsystem-specific API (RTC, network, misc, input, etc.) so you get ready-made helper routines rtc_register_device(), register_netdev()
Bus registration Tells the kernel which bus your driver should be matched against for device discovery i2c_register_driver(), pci_register_driver()

Some of the simplest drivers — like the misc character device driver we build in the next lecture — only need the framework registration and skip bus registration entirely, because they operate on logical resources rather than real bus-attached hardware.

What’s New in the Linux Device Model on Kernel 6.12+

Older driver books and tutorials often reference APIs whose signatures have since changed. If you are following this free Linux kernel development course to write real, buildable drivers on a current kernel, keep these updates in mind:

  • class_create() no longer takes an owner module pointer as of kernel 6.4 — it now takes only the class name.
  • Device tree overlays are now the standard way most platform devices are described on ARM SoCs, rather than hand-written platform device registration in board files.
  • devm_* managed resource APIs (devm_kzalloc(), devm_request_irq(), and similar) are now the preferred way to allocate resources inside probe(), since they are automatically released when the device is unbound.
  • Many bus subsystems increasingly rely on fwnode abstractions so the same driver logic can work whether the platform description comes from device tree or ACPI.

Real-World Use Cases

Almost every embedded Linux product you interact with relies on this model:

  • A Wi-Fi module on an SDIO bus, bound automatically when the SoC boots
  • A touchscreen controller on I2C, probed the moment its device tree node is parsed
  • An SoC’s built-in UART or timer block, registered on the platform bus
  • A USB-to-serial adapter, bound the instant it is plugged in

Common Mistakes and Troubleshooting

Mistake Why It Breaks Things
Assuming every device needs bus registration Logical drivers like misc devices don’t sit on a real bus at all
Doing hardware setup outside probe() Resources may not be ready yet, or you break hot-plug support
Forgetting remove() cleanup Leaks memory/IRQs and can crash the kernel on module unload

Best Practices

  • Always check /sys/bus/<bus>/devices/ and /sys/bus/<bus>/drivers/ while debugging binding issues
  • Prefer devm_* managed APIs over manual allocation/free pairs in probe()/remove()
  • Keep probe() fast — defer heavy initialization with workqueues if needed
  • Log meaningful context using pr_fmt() so dmesg output is traceable

Performance and Security Considerations

Performance: Because probe() can run during boot for many devices in parallel (asynchronous probing), keep it non-blocking wherever possible to avoid extending boot time.

Security: Device nodes created through this model often end up world-accessible under /dev. Always set correct permissions and validate any user-supplied data your driver later accepts through its file operations.

Summary / Key Takeaways

  • The Linux Device Model unifies how the kernel represents buses, devices, and drivers
  • Every device, even logical ones, is conceptually attached to a bus — real or pseudo (platform)
  • probe() and remove() drive the device lifecycle
  • Modern drivers often register with both a specialized kernel framework and a bus
  • Simple logical drivers, like the misc driver in the next lecture, can skip bus registration entirely

Conclusion

The Linux Device Model can look intimidating from the outside, but it boils down to a small number of consistent rules repeated across every subsystem in the kernel. Once this mental model clicks, reading unfamiliar driver source code becomes dramatically easier, because you already know what probe(), remove(), and bus registration are trying to accomplish. In the next lecture of this free Linux device drivers course, we put this theory into practice by writing a real, working misc character device driver from scratch.

Frequently Asked Questions

Q1. What is the Linux Device Model in simple terms?
It is the kernel’s unified system for tracking hardware buses, the devices on them, and the drivers that operate those devices.

Q2. Why does every device need to be on a bus?
It keeps device discovery and driver matching consistent, even for hardware without a real physical bus, via the platform pseudo-bus.

Q3. What is the platform bus?
A pseudo-bus used for SoC-integrated peripherals that have no discoverable physical bus of their own.

Q4. What triggers a driver’s probe() function?
The bus driver invokes it once a device is successfully matched to a registered driver.

Q5. Do all drivers need to register with a bus?
No. Simple logical drivers, such as misc character device drivers, often only register with a kernel framework.

Q6. Where can I inspect bus and device relationships on a running system?
Under /sys/bus/, /sys/devices/, and /sys/class/.

Q7. What changed with class_create() in recent kernels?
From kernel 6.4 onward, class_create() takes only the class name, dropping the older owner-module argument.

Continue This Free Linux Kernel Development Course

Next up: writing your first real driver using the misc framework.

Next Lecture » Back to Course Index

2 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *