我对char驱动程序示例感到困惑。在一些示例中,示例集中于创建字符设备并将其与file_operations连接。然后我们必须insmod
驱动程序,使用mknod
创建一个节点,然后我们的小应用程序才能使用此驱动程序读取或写入。这样一个简单的init_function:
static int char_init(void)
{
alloc_chrdev_region(&mydev, 0, 1, "mydev");
cdev = cdev_alloc();
cdev->fops = &fops;
cdev_add(cdev, mydev, 1);
printk(KERN_ALERT "Major minor number available\n");
printk(KERN_ALERT "major number = %d minor number = %d\n",MAJOR(mydev), MINOR(mydev));//Macros that extract the major and minor numbers from a device number.
return 0;
}
在其他一些例子中,我们创建了一个类和一个设备。 Derek Molloy的char驱动程序的一个例子,
static int __init ebbchar_init(void){
printk(KERN_INFO "EBBChar: Initializing the EBBChar LKM\n");
// Try to dynamically allocate a major number for the device -- more difficult but worth it
majorNumber = register_chrdev(0, DEVICE_NAME, &fops);
if (majorNumber<0){
printk(KERN_ALERT "EBBChar failed to register a major number\n");
return majorNumber;
}
printk(KERN_INFO "EBBChar: registered correctly with major number %d\n", majorNumber);
// Register the device class
ebbcharClass = class_create(THIS_MODULE, CLASS_NAME);
if (IS_ERR(ebbcharClass)){ // Check for error and clean up if there is
unregister_chrdev(majorNumber, DEVICE_NAME);
printk(KERN_ALERT "Failed to register device class\n");
return PTR_ERR(ebbcharClass); // Correct way to return an error on a pointer
}
printk(KERN_INFO "EBBChar: device class registered correctly\n");
// Register the device driver
ebbcharDevice = device_create(ebbcharClass, NULL, MKDEV(majorNumber, 0), NULL, DEVICE_NAME);
if (IS_ERR(ebbcharDevice)){ // Clean up if there is an error
class_destroy(ebbcharClass); // Repeated code but the alternative is goto statements
unregister_chrdev(majorNumber, DEVICE_NAME);
printk(KERN_ALERT "Failed to create the device\n");
return PTR_ERR(ebbcharDevice);
}
printk(KERN_INFO "EBBChar: device class created correctly\n"); // Made it! device was initialized
return 0;
}
现在我可以用这两种策略得出什么结论?为什么不只使用第二个呢?
另外,当我们使用cdev_add
和cdev_init
创建设备时,如果我必须使用mknod
创建设备文件,该怎么办?