当前位置:首页>Linux>Linux 设备驱动模型解析:device、driver 与 bus 的关系

Linux 设备驱动模型解析:device、driver 与 bus 的关系

  • 2026-10-11 07:28:39
Linux 设备驱动模型解析:device、driver 与 bus 的关系
看一个框架图,有疑问我们可以评论区或者加群讨论
第一章 Linux 为什么需要设备驱动模型

1.1 早期 Linux 驱动的问题

早期 Linux 内核中,很多驱动并没有统一模型。驱动初始化时直接操作硬件、申请设备号、创建接口,不同驱动之间几乎没有统一管理方式。随着 PCI、USB、Platform、I2C 等总线出现,设备数量迅速增长,Linux 开始面临设备发现、驱动匹配、热插拔、电源管理等复杂问题。

Linux 设备驱动模型(Driver Model)本质上是一个统一对象管理框架,其核心目标是将“硬件设备”“驱动程序”“总线管理”解耦。device 表示硬件实体,driver 表示功能实现,bus 负责组织匹配关系。现代 Linux 几乎所有子系统都建立在这套模型之上,包括 platform、PCI、USB、I2C、SPI、input、net、block 等。

1.2 Linux Driver Model 核心思想

Linux Driver Model 的核心思想其实非常简单:

device 描述硬件driver 提供操作方法bus 负责匹配二者

内核启动后,bus 会维护 device 链表与 driver 链表,并不断尝试 match。一旦匹配成功,bus 调用 driver->probe,驱动开始接管设备。

这种架构最大的优势是统一生命周期管理。无论是 PCI 热插拔还是 Device Tree 静态设备,最终都能够抽象为同一种 device-driver 关系。Linux 内核大量复杂功能,例如 runtime PM、sysfs、udev、deferred probe,本质上都建立在 Driver Model 基础之上。

第二章 device 对象解析

2.1 struct device 的本质

Linux 中最核心的对象之一是:struct device它并不代表某一种具体硬件,而是 Linux 对“设备”的统一抽象。无论 UART、网卡、USB 鼠标还是 SPI Flash,最终都必须嵌入 struct device,其内部最关键成员包括:

struct device {    struct kobject kobj;    struct bus_type *bus;    struct device_driver *driver;    struct device *parent;};

其中 kobj 用于接入 sysfs,bus 表示所属总线,driver 表示当前绑定驱动。Linux 通过 struct device 将所有硬件统一纳入对象模型管理体系。

2.2 device 的生命周期

device 创建后通常会执行:

device_initialize()device_add()

device_add 会将设备挂接到 bus 与 sysfs:

/sys/devices//sys/bus/

随后 bus 开始尝试匹配 driver,当设备移除时:

device_del()put_device()

Linux 使用 kobject 引用计数管理 device 生命周期。只有所有引用释放后,device 才真正销毁。这种机制能够避免热插拔场景中出现 dangling pointer。

第三章 driver 对象解析

3.1 struct device_driver 架构

Linux 驱动核心对象:struct device_driver其关键成员:

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

真正的平台相关逻辑通常封装在更高层对象中,例如:

platform_driverpci_driverusb_driveri2c_driver

这些结构最终都会内嵌 device_driver。

Linux driver 本质上不是“代码集合”,而是一个注册进内核对象系统的运行时对象。注册后 bus 才能发现它,并尝试与 device 匹配。

3.2 probe 与 remove 的意义

driver 最核心的函数:probe remove,probe 表示驱动接管设备:

申请资源ioremap申请 IRQ初始化硬件注册子系统

remove 则负责反向释放资源,Linux 强调驱动必须支持 remove,原因在于现代系统存在:

USB 热插拔模块卸载runtime PM设备重绑定

如果驱动只考虑“启动”,不考虑“退出”,系统资源模型会迅速失控。

第四章 bus 总线模型解析

4.1 bus_type 的作用

bus 是 Linux Driver Model 中最关键的一层:struct bus_type核心作用:

管理 device管理 driver负责 match

bus 内部同时维护:

device listdriver list

每次新 device 或 driver 注册时,bus 都会尝试重新匹配。

Linux 所谓“总线”很多时候并不是真实硬件总线,例如:platform bus,本质只是 Linux 虚拟管理框架,它并不传输数据。

4.2 match 机制

bus 最关键函数:match()例如 platform bus:platform_match()

PCI bus:pci_bus_match()

match 成功后:driver ↔ device bind,随后执行 probe。

现代 ARM Linux 大量依赖:Device Tree compatible

进行匹配。例如:compatible = "rockchip,rk3568-uart";

驱动:.of_match_table = uart_ids,bus 会比较 compatible 字符串完成匹配。

第五章 sysfs 与 kobject 关系

5.1 kobject 为什么重要

Linux Driver Model 实际建立在:kobject之上,device、driver、bus 内部都包含:struct kobject,kobject 提供:

引用计数sysfs 导出对象层级uevent

Linux 内核实际上通过 kobject 构建了一套“对象文件系统”。

5.2 sysfs 如何反映设备模型

注册 device 后:/sys/devices/会生成对应目录。

注册 driver 后:/sys/bus/platform/drivers/也会生成目录。

Linux sysfs 本质上就是 Driver Model 的用户空间映射。用户看到的:

/sys/bus/sys/class/sys/devices

实际上对应 Linux 内核对象树,udev 正是监听:uevent自动创建设备节点。

第六章 device-driver 绑定过程

6.1 驱动注册流程

以 platform_driver 为例:platform_driver_register()最终执行:

driver_register    ↓bus_add_driver    ↓driver_attach

bus 开始遍历所有 device:

match    ↓probe

如果匹配成功,则建立:dev->driver = drv绑定关系。

6.2 设备注册流程

platform_device 注册:platform_device_register()最终执行:

device_add    ↓bus_add_device    ↓bus_probe_device

随后 bus 遍历所有 driver,因此 Linux Driver Model 本质上属于“双向匹配模型”:

device 来找 driverdriver 也会找 device

无论谁先注册,最终都能完成绑定。

第七章 Linux Driver Model 工程意义

7.1 为什么 Linux 一定要分层

很多初学者会觉得:

devicedriverbuskobjectsysfs

层次太复杂,但 Linux 必须这样设计,因为它需要支持:

热插拔模块动态加载电源管理设备树sysfs用户空间管理

如果没有统一对象模型,不同驱动会完全失控,Linux Driver Model 本质上是“设备生命周期管理系统”,而不仅仅是驱动框架。

7.2 现代 Linux 内核中的 Driver Model

现代 Linux 几乎所有 subsystem 都依赖 Driver Model:

PCIUSBPlatformI2CSPIDRMTTYInputNetdev

其核心架构始终一致:

bus 管理device 描述硬件driver 提供行为

理解 Driver Model 后,再分析 platform、I2C、PCI、USB 等子系统,会发现 Linux 内核虽然代码庞大,但底层设计思想高度统一。真正复杂的并不是“设备操作”,主要是 Linux 如何在大规模硬件系统中维持统一对象关系与生命周期管理。

最新文章

随机文章