cdev_add()实际上做了什么?在将设备注册到内核方面

时间:2013-10-22 00:55:45

标签: linux-kernel kernel linux-device-driver

cdev_add()实际上做了什么?我问的是用内核注册设备的条款。

是否在某些地图中添加了指向cdev结构的指针,该指针由主要和次要编号索引?当您说设备已添加/注册到内核时,这究竟是怎么发生的。我想知道cdev_add在正在运行的内核中注册设备所需的步骤。我们使用mknod命令为用户空间创建节点。甚至此命令也使用主号和次号映射。注册也会做类似的事情吗?

3 个答案:

答案 0 :(得分:3)

cdev_add在内核中注册一个字符设备。内核在cdev_map

下维护一个字符设备列表
static struct kobj_map *cdev_map;

kobj_map基本上是一个探针数组,在这种情况下是字符设备列表:

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

您可以看到列表中的每个条目都有设备的主要和次要编号(dev_t dev),以及设备结构(以kobj_probe_t的形式,这是一个内核对象,在这种情况下代表一个cdev) )。 cdev_add将您的角色设备添加到探测列表中:

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

当您在进程中对设备执行打开时,内核会找到与设备文件名关联的inode(通过namei函数)。 inode具有设备的主要次要编号(dev_t i_rdev),以及表示它是特殊(字符)设备的标志(imode)。有了它,它可以访问我上面解释的cdev列表,并获得为您的设备实例化的cdev结构。从那里它可以创建一个struct文件,其中包含对cdev的文件操作,并在进程的文件描述符表中安装文件描述符。

这实际上是注册'角色设备意味着它需要完成的原因。注册块设备类似。内核为注册的gendisks维护另一个列表。

答案 1 :(得分:1)

请在此处查看代码注释:

  

cdev_add() - 将char设备添加到系统464 *   @p:设备的cdev结构465 * @dev:第一个设备   该设备负责的号码466 * @count:号码   对应于此467 *
的连续次要数字   device 468 * 469 * cdev_add()将@p表示的设备添加到   系统,使它立即生活470 *。负错误代码   失败时返回。 471 * /`

任何此类问题的直接答案都是阅读代码。那是莱纳斯所说的。

[编辑] cdev_add基本上将设备添加到系统中。它本质上意味着在cdev_add操作之后,您的新设备将通过/sys/文件系统获得可见性。该函数执行与此相关的所有必要的内务处理活动,特别是对设备的kobj引用将插入到对象层次结构中的位置。如果您想获得有关它的更多信息,我建议您阅读/sysfs/struct kboj

答案 2 :(得分:1)

您可以阅读Linux Device Driver。它有点旧,但主要的想法是一样的。很难解释像cdev_add()之类的简单操作以及几行中的所有内容。

我建议你阅读这本书和源代码。如果您无法浏览源代码,可以使用一些标记系统,如etags + emacs或eclipse索引器。