Linux 内核设备模型与驱动框架深度实战:从设备树到字符设备驱动的完全工程指南
Linux 内核的设备模型是驱动框架的基石。本文从 kobject 和 kset 开始,深入 Platform 驱动、设备树解析、字符设备注册,到生产级驱动调试与性能优化。
1. 设备模型核心架构
Linux 设备模型基于三个核心数据结构:
- kobject:提供引用计数、sysfs 表示和层次关系管理
- kset:kobject 的集合,管理一组相同类型的 kobject
- ktype:定义 kobject 的释放函数和 sysfs 操作
struct kobject {
const char *name;
struct list_head entry;
struct kobject *parent;
struct kset *kset;
struct kobj_type *ktype;
struct kref kref;
};
2. 总线-设备-驱动模型
Linux 使用总线(Bus)将设备(Device)和驱动(Driver)匹配起来。当总线检测到新的设备或驱动时调用 match() 函数,匹配成功则调用 probe()。
3. 设备树(Device Tree)
ARM 架构使用设备树描述硬件拓扑。设备树源文件(.dts)编译为 DTB 后由 bootloader 传递给内核。
/ {
compatible = "vendor,board";
mydevice@10000000 {
compatible = "vendor,mydevice";
reg = <0x10000000>;
interrupts = ;
status = "okay";
};
};
内核使用 of_platform_populate() 自动遍历设备树并注册 platform_device。驱动的 of_device_id 表用于设备树匹配。
4. Platform Bus 驱动
Platform 总线用于 SoC 内集成的没有物理总线的设备:
static int mydev_probe(struct platform_device *pdev) {
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
void __iomem *base = devm_ioremap_resource(&pdev->dev, res);
int irq = platform_get_irq(pdev, 0);
devm_request_irq(&pdev->dev, irq, mydev_irq, 0, "mydev", priv);
sysfs_create_group(&priv->kobj, &attr_group);
return 0;
}
static const struct of_device_id mydev_of_match[] = {
{ .compatible = "vendor,mydev" },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, mydev_of_match);
static struct platform_driver mydev_driver = {
.probe = mydev_probe,
.remove = mydev_remove,
.driver = { .name = "mydev", .of_match_table = mydev_of_match },
};
module_platform_driver(mydev_driver);
5. 字符设备
字符设备提供无缓冲的流式读写接口。推荐注册流程:alloc_chrdev_region() → cdev_init() → cdev_add() → class_create() → device_create()。实现 file_operations 中的 open/read/write/ioctl/release。
6. 中断与 DMA
中断处理框架:
| 机制 | 上下文 | 特点 |
|---|---|---|
| tasklet | 中断上下文 | 不允许睡眠,轻量延迟 |
| workqueue | 进程上下文 | 允许睡眠,耗时操作 |
| threaded IRQ | 独立线程 | 整个 handler 在单独线程 |
| tasklet_hi | 中断上下文 | 高优先级 tasklet |
7. 驱动调试与优化
7.1 DebugFS 与动态打印
pr_debug("val=%d
", val);
dynamic_pr_debug("reg=%x
", reg);
debugfs_create_file("regs", 0444, dir, priv, ®s_fops);
7.2 ftrace
使用 function tracer 追踪驱动调用链,perf 分析性能,bpftrace 动态 trace 内核路径。
8. 内核模块与热插拔
驱动通过 modprobe/insmod 加载,rmmod 卸载。热插拔结合 uevent 和 udev 实现自动驱动加载。DRM 和 USB 子系统提供了成熟的驱动模型实现。
9. 总结
Linux 设备模型将硬件抽象为统一的设备-总线-驱动框架,配合设备树实现跨平台。Platform 驱动、字符设备、中断和 DMA 是所有驱动开发的基础。

发表评论 取消回复