我正在为一个设备编写一个Linux设备驱动程序,从OOP的角度来看,它就像struct cdev
的子类(或扩展名)。此类设备必须包含struct cdev
,否则在打开/ dev文件时无法使用container_of()
检索设备数据:
struct mycdev {
struct cdev cdev; // We want to extend struct cdev
u32 data[10]; // Device data
};
...
static int mycdev_open(struct inode *ip, struct file *fp)
{
struct mycdev *dev = container_of(ip->i_cdev, struct mycdev, cdev);
...
}
什么是释放扩展struct mycdev
的安全方式?我能想到的是覆盖char设备的默认release()
:
...
struct mycdev *mycdev = kmalloc(sizeof(*mycdev), GFP_KERNEL);
cdev_init(&mycdev->cdev, &mycdev_fops);
mycdev->cdev.kobj.ktype->release = mycdev_release;
...
因为原始的release()
是静态的,所以我必须通过在我的方法中复制和粘贴代码来复制它的代码。或者,我可以在设备结构中的某处保存原始方法,然后记得从我的方法中调用它。有没有更好的方法来做到这一点?例如,在struct device
中,您的钩子方法可以覆盖release()
{/ 1}}。
在LDD3书籍示例中,它们似乎是疏忽,因为它们为扩展设备分配了一块内存,然后,当模块卸载时,它们cdev_del()
和kfree()
整个板块。如果系统中的某个人仍然持有指向cdev的指针(比如打开文件的struct inode
),那将是非常错误的。