刚开始学习字符设备驱动,看到内核中有的代码使用cdev_alloc函数申请了内存后使用了cdev_init函数初始化,有的则是直接对结构体变量ops赋值。分别人如下
////////////////////////////////////////////我是分割线//////////////////////////////////////////////
为了了解为什么可以不使用cdev_init函数,找到源码,把cdev_alloc和cdev_alloc对比后发现cdev_alloc已经处理了cdev_init中的很多事情,所以可以在使用了cdev_alloc后,只初始化在cdev_init中没有处理的部分。
下面先看一下cdec_alloc函数原型和cdev_init函数原型
struct cdev *cdev_alloc(void) { struct cdev *p = kzalloc(sizeof(struct cdev), GFP_KERNEL); if (p) { INIT_LIST_HEAD(&p->list); kobject_init(&p->kobj, &ktype_cdev_dynamic); } return p; }
void cdev_init(struct cdev *cdev, const struct file_operations *fops) { memset(cdev, 0, sizeof *cdev); INIT_LIST_HEAD(&cdev->list); kobject_init(&cdev->kobj, &ktype_cdev_default); cdev->ops = fops; }
对比后可以发现,两者起始非常相似。
cdev_alloc函数使用里的kzalloc申请了内存并且内部把申请到的内存清零了。
经过对比可以发现,如果使用了cdev_alloc函数申请的内存,可以在下面直接对ops变量赋值,而不需要调用cdev_init再一次初始化,进而提高效率。