Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does actually cdev_add() do? in terms of registering a device to the kernel

What does cdev_add() actually do? I'm asking terms of registering a device with the kernel.

Does it add the pointer to cdev structure in some map which is indexed by major and minor number? How exactly does this happen when you say the device is added/registered with the kernel. I want to know what steps the cdev_add takes to register the device in the running kernel. We create a node for user-space using mknod command. Even this command is mapped using major and minor number. Does registration also do something similar?

like image 935
Anup Buchke Avatar asked Dec 08 '22 11:12

Anup Buchke


1 Answers

cdev_add registers a character device with the kernel. The kernel maintains a list of character devices under cdev_map

static struct kobj_map *cdev_map;

kobj_map is basically an array of probes, which in this case is the list of character devices:

struct kobj_map {
    struct probe {
        struct probe *next;
        dev_t dev;
        unsigned long range;
        struct module *owner;
        kobj_probe_t *get;
        int (*lock)(dev_t, void *);
        void *data;
    } *probes[255];
    struct mutex *lock;
};

You can see that each entry in the list has the major and minor number for the device (dev_t dev), and the device structure (in the form of kobj_probe_t, which is a kernel object, which represents a cdev in this case). cdev_add adds your character device to the probes list:

int cdev_add(struct cdev *p, dev_t dev, unsigned count)
{
    ...
    error = kobj_map(cdev_map, dev, count, NULL,
             exact_match, exact_lock, p);

When you do an open on a device from a process, the kernel finds the inode associated to the filename of your device (via namei function). The inode has the major a minor number for the device (dev_t i_rdev), and flags (imode) indicating that it is a special (character) device. With this it can access the cdev list I explained above, and get the cdev structure instantiated for your device. From there it can create a struct file with the file operations to your cdev, and install a file descriptor in the process's file descriptor table.

This is what actually 'registering' a character device means and why it needs to be done. Registering a block device is similar. The kernel maintains another list for registered gendisks.

like image 116
Jay Medina Avatar answered Dec 11 '22 11:12

Jay Medina