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

Anu*_*hke 3 kernel linux-device-driver linux-kernel

什么是cdev_add()真正做到?我在问向内核注册设备的条款。

是否在某些映射中添加了指向cdev结构的指针,该映射由主数和次数索引?当您说设备已在内核中添加/注册时,这是如何发生的。我想知道cdev_add采取什么步骤在运行的内核中注册设备。我们使用mknod命令为用户空间创建一个节点。即使此命令也使用主号和副号映射。注册也做类似的事情吗?

小智 5

cdev_add向内核注册一个字符设备。内核在cdev_map下维护一个字符设备列表

static struct kobj_map *cdev_map;
Run Code Online (Sandbox Code Playgroud)

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;
};
Run Code Online (Sandbox Code Playgroud)

您可以看到列表中的每个条目都有设备的主设备号和次设备号(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);
Run Code Online (Sandbox Code Playgroud)

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

这就是“注册”字符设备的实际含义,以及为什么需要这样做。注册块设备类似。内核为已注册的gendisk维护另一个列表。


Fed*_*ico 2

您可以阅读Linux 设备驱动程序。虽然有点老了,但主要思想是一样的。很难用cdev_add()几行内容来解释像这样的简单操作以及周围的所有内容。

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