cdev is the char device representation of the kernel and is to associate cdev with a set of file_operations. These file_operations are performed on a device node, typically present under /dev or depending on you where you create a device node.
cdev_init() is used to associate a cdev with a set of file_operations. Finally cdev_add() is called on the device to make it live, such that, the user could access them.
Now, while this is done, it doesn't mean that the device node is created for you.
This is done manually either by using mknod utility or using device_create() function. Device nodes are generally associated with a class. Thus, we need to create a class first(using class_create()) and then create device nodes using that class.
This is an example how to get device node.
struct class *my_class;
struct cdev my_cdev[N_MINORS];
dev_t dev_num;
static int __init my_init(void)
{
int i;
dev_t curr_dev;
/* Request the kernel for N_MINOR devices */
alloc_chrdev_region(&dev_num, 0, N_MINORS, "my_driver");
/* Create a class : appears at /sys/class */
my_class = class_create(THIS_MODULE, "my_driver_class");
/* Initialize and create each of the device(cdev) */
for (i = 0; i < N_MINORS; i++) {
/* Associate the cdev with a set of file_operations */
cdev_init(&my_cdev[i], &fops);
/* Build up the current device number. To be used further */
curr_dev = MKDEV(MAJOR(dev_num), MINOR(dev_num) + i);
/* Create a device node for this device. Look, the class is
* being used here. The same class is associated with N_MINOR
* devices. Once the function returns, device nodes will be
* created as /dev/my_dev0, /dev/my_dev1,... You can also view
* the devices under /sys/class/my_driver_class.
*/
device_create(my_class, NULL, curr_dev, NULL, "my_dev%d", i);
/* Now make the device live for the users to access */
cdev_add(&my_cdev[i], curr_dev, 1);
}
return 0;
}
register_chrdev is not going to be use in the latest kernel, where we
give NAME?
register_chrdev() is the older way which was using in kernel 2.4, but in kernel 2.6 is replaced with register_chrdev_region() and alloc_chardev_region().
- register_chrdev_region() if you know ahead of time exactly which device numbers you want.
- alloc_chrdev_region() for dynamically allocated a device number, done by kernel.