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