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:
随后 bus 开始尝试匹配 driver,当设备移除时:
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 或 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 提供:
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:
如果匹配成功,则建立: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 如何在大规模硬件系统中维持统一对象关系与生命周期管理。