为什么ldd3示例代码中文件操作分配了两次?

为什么ldd3示例代码中文件操作分配了两次?

https://github.com/martinezjavier/ldd3/blob/master/scull/main.c#L601

static void scull_setup_cdev(struct scull_dev *dev, int index)
{
    int err, devno = MKDEV(scull_major, scull_minor + index);

    cdev_init(&dev->cdev, &scull_fops); 
    dev->cdev.owner = THIS_MODULE;
    dev->cdev.ops = &scull_fops;

我们可以看到和scull_fops被分配了两次,为什么呢?cdev_init()cdev.ops

答案1

scull_fops不是分配的两次,就是用过的两次。它是定义的 同一文件中的其他地方,然后它的地址被传递到cdev_init,并分配给dev->cdev.ops

正如您所提到的,这种显式分配 todev->cdev.ops是不必要的,因为cdev_init它也是如此。作为约翰·迈林 ,这是 LDD3 示例代码中的一个低效率问题——示例代码比 中的相应行更新cdev_init,因此在编写时就已经没有必要了。 (看看是否在其他地方重现了同样的错误,看看有多少“真正的”驱动程序代码是基于 LDD3 示例编写的,这将是很有趣的!)

该函数可以简化为

static void scull_setup_cdev(struct scull_dev *dev, int index)
{
    int err, devno = MKDEV(scull_major, scull_minor + index);

    cdev_init(&dev->cdev, &scull_fops);
    dev->cdev.owner = THIS_MODULE;
    err = cdev_add (&dev->cdev, devno, 1);
    /* Fail gracefully if need be */
    if (err)
        printk(KERN_NOTICE "Error %d adding scull%d", err, index);
}

答案2

请参阅此链接以确认它执行两次:

https://github.com/torvalds/linux/blob/6f0d349d922ba44e4348a17a78ea51b7135965b1/fs/char_dev.c#L656

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;
}

相关内容