4

实际上是做什么的cdev_add()?我正在询问向内核注册设备的条款。

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

4

3 回答 3

11

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 结构。从那里它可以创建一个结构文件,其中包含对您的 cdev 的文件操作,并在进程的文件描述符表中安装一个文件描述符。

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

于 2016-05-12T21:28:45.537 回答
2

您可以阅读Linux 设备驱动程序。它有点旧,但主要思想是相同的。很难cdev_add()用几行来解释一个简单的操作和所有的东西。

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

于 2013-10-22T12:22:40.640 回答
1

请在此处查看代码注释:

cdev_add() - 向系统添加一个字符设备 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

于 2013-10-22T01:43:49.483 回答