Linux驱动开发:如何用platform_driver实现资源零泄漏的模块卸载
在嵌入式Linux开发中,驱动模块的动态加载和卸载是开发者必须掌握的技能。但许多人在兴奋地完成probe函数中的设备初始化后,往往忽视了remove函数中的资源清理工作。这种疏忽可能导致内存泄漏、设备状态混乱甚至系统崩溃。本文将深入探讨如何利用platform_driver机制,构建一个资源管理完美的Linux驱动模块。
1. 理解platform_driver的生命周期管理
Linux内核的platform_driver机制不仅仅是一个简单的驱动注册接口,它实际上提供了一套完整的设备生命周期管理方案。与直接注册字符设备或misc设备不同,platform_driver通过probe/remove函数对,为开发者提供了天然的"创建-销毁"对称结构。
当驱动模块被加载时,内核会依次执行:
- 模块初始化函数(通常标记为
__init) - platform_driver_register()
- 设备树匹配过程
- 匹配成功后的probe函数调用
而卸载时则完全相反:
- 模块退出函数(通常标记为
__exit) - platform_driver_unregister()
- 已匹配设备的remove函数调用
这种对称性设计使得资源管理变得直观。一个良好的实践是:在probe函数中分配/获取的所有资源,都应该在remove函数中有对应的释放操作。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 典型资源泄漏场景与防范
在驱动开发中,常见的需要清理的资源包括:
- 内存分配(kmalloc, devm_kzalloc等)
- 设备注册(misc_register, class_create等)
- 中断请求(request_irq)
- 工作队列(create_workqueue)
- 定时器(setup_timer)
- 各种内核对象(如sysfs节点)
下面是一个典型的资源泄漏示例:
c复制static int sample_probe(struct platform_device *pdev)
{
struct my_device *dev;
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
