Используя cp
, данные будут проходить через несколько буферов (на стороне пользователя и на стороне ядра), поэтому требуемая пропускная способность памяти может быть увеличена во много раз. Возможно, внутренние компоненты ramfs также добавят накладных расходов. Итак, cp
определенно не лучший инструмент для проверки пропускной способности памяти.
scull_fops
не присвоено дважды, оно используется дважды. Он определенв другом месте того же файла , затем его адрес передается в cdev_init
и назначается dev->cdev.ops
.
Как вы заметили, это явное присваивание dev->cdev.ops
не нужно, так как cdev_init
делает то же самое. Как Johan Myréenговорит , это неэффективность кода примера 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);
}
см. эту ссылку, чтобы подтвердить это сделать дважды:
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;
}