设备和驱动匹配方式:
设备树匹配(现代使用)
id 匹配(老,淘汰)
name 匹配(远古,淘汰)
ACPI 匹配(x86 使用)
匹配优先级:设备树匹配 > id 匹配 > name 匹配
Linux 设备驱动模型
驱动和设备写在一起的缺点:
设备信息硬编码,硬件改动时需修改驱动代码并重新编译内核,移植性差。
不支持热插拔。由于设备和驱动是强绑定关系,系统启动时就确定了,无法在运行时动态加载或卸载设备。
不方便查看设备和驱动的信息,调试和维护困难。无法通过 /sys 接口查询设备与驱动的对应关系。
没有电源管理,驱动无法根据设备实际情况动态调整功耗,影响系统功耗。
Linux 设备驱动模型,就是为了解决这些问题。
在驱动模型中,设备这一角色专门用来描述设备的硬件信息,通常用设备树去描述设备;驱动还是之前的驱动。
电源管理
驱动自动加载
udev:Linux 内核提供的标准设备管理器,功能丰富,netlink机制。
mdev:Busybox 提供的设备管理器,功能精简,占用资源小,常用于嵌入式。
udev、mdev 工具,是用户空间的程序,当设备添加、删除、修改时,内核会向用户空间发送热插拔事件 uevent,这个工具捕获事件,自动完成加载驱动、创建设备节点等操作。
mdev 创建设备节点的两种方法:
(1)根文件系统挂载后调用:
mdev -s实现 Linux 启动后自动批量创建设备节点。
(2)热插拔时自动调用
在系统的初始化脚本文件 /etc/init.d/rcS 中:
echo /sbin/mdev > /proc/sys/kernel/hotplug告诉内核:以后有设备热插拔事件(hotplug 事件)时,调用 /sbin/mdev 来处理。
platform 平台设备驱动
为了满足 Linux 设备模型,必须有总线、设备和驱动。像 USB、SPI、I2C 等有物理的总线,但很多设备没有对应的物理总线,如 LED 灯、蜂鸣器等。
因此,内核专门开发的一种虚拟总线,用来连接没有物理总线的设备、不支持热插拔的设备。
现在一个驱动编写的流程是:
申请设备号
初始化 cdev
创建设备

当内核遍历设备树时,如果某个节点的 compatible属性与 my_driver_of_match表中的某一项匹配,就会调用该驱动的 probe函数,所以 probe 函数里应该做:
检查设备状态
获取私有数据指针
获取和映射硬件资源
初始化硬件
注册设备
读取整数
读取字符串
读取布尔值
处理内存映射
中断
GPIO
查找子节点
查找特定节点
查找设备是否可用