Linux kernel 容器(inode->;i\u cdev、结构-工艺开发、cdev)说明
我正在阅读关于macro的Linux kernel 容器(inode->;i\u cdev、结构-工艺开发、cdev)说明,linux-kernel,linux-device-driver,kernel-module,Linux Kernel,Linux Device Driver,Kernel Module,我正在阅读关于macro的container\u的解释,除了一件事之外,我得到了大部分。inode->I_cdev如何指向cdev? 为了确保cdev这里是我们在cdev_init调用中初始化的字符设备 还有一件事要补充 “struct cdev”中的dev是DD视图,“struct inode”中的dev是Fs(文件系统)视图 还有Struct inode(fs.h的一部分)-->Struct cdev(cdev.h的一部分&Struct inode的成员对象)-->(大调、小调) &结构开发
container\u的解释,除了一件事之外,我得到了大部分。inode->I_cdev
如何指向cdev
?
为了确保cdev
这里是我们在cdev_init
调用中初始化的字符设备 还有一件事要补充
“struct cdev”中的dev是DD视图,“struct inode”中的dev是Fs(文件系统)视图
还有Struct inode(fs.h的一部分)-->Struct cdev(cdev.h的一部分&Struct inode的成员对象)-->(大调、小调)
&结构开发(用户定义)--->结构cdev-->(主要、次要)
两者都达到了同一点 还有一件事要补充
“struct cdev”中的dev是DD视图,“struct inode”中的dev是Fs(文件系统)视图
还有Struct inode(fs.h的一部分)-->Struct cdev(cdev.h的一部分&Struct inode的成员对象)-->(大调、小调)
&结构开发(用户定义)--->结构cdev-->(主要、次要)
两者都达到了同一点 如果查看fs/char_dev.c文件下的chrdev_open函数,您将看到在打开任何字符设备之前,其各自的i_cdev结构都填充在inode的结构中
p = inode->i_cdev;
if (!p) {
struct kobject *kobj;
int idx;
spin_unlock(&cdev_lock);
kobj = kobj_lookup(cdev_map, inode->i_rdev, &idx);
if (!kobj)
return -ENXIO;
new = container_of(kobj, struct cdev, kobj);
spin_lock(&cdev_lock);
/* Check i_cdev again in case somebody beat us to it while
we dropped the lock. */
p = inode->i_cdev;
if (!p) {
inode->i_cdev = p = new;
list_add(&inode->i_devices, &p->list);
new = NULL;
} else if (!cdev_get(p))
ret = -ENXIO;
} else if (!cdev_get(p))
ret = -ENXIO;
对于inode本身,它必须在创建设备节点时创建。
我不太了解kobjects,但它是如何使用kobj获得cdev的,以及我们在哪里将kobject与这个特定设备关联起来的?答案在于cdev_add
int cdev_add(struct cdev *p, dev_t dev, unsigned count)
{
int error;
p->dev = dev;
p->count = count;
error = kobj_map(cdev_map, dev, count, NULL,
exact_match, exact_lock, p);
if (error)
return error;
kobject_get(p->kobj.parent);
return 0;
}
如果查看fs/char_dev.c文件下的chrdev_open函数,您将看到在打开任何字符设备之前,其各自的i_cdev结构填充在inode的结构中
p = inode->i_cdev;
if (!p) {
struct kobject *kobj;
int idx;
spin_unlock(&cdev_lock);
kobj = kobj_lookup(cdev_map, inode->i_rdev, &idx);
if (!kobj)
return -ENXIO;
new = container_of(kobj, struct cdev, kobj);
spin_lock(&cdev_lock);
/* Check i_cdev again in case somebody beat us to it while
we dropped the lock. */
p = inode->i_cdev;
if (!p) {
inode->i_cdev = p = new;
list_add(&inode->i_devices, &p->list);
new = NULL;
} else if (!cdev_get(p))
ret = -ENXIO;
} else if (!cdev_get(p))
ret = -ENXIO;
对于inode本身,它必须在创建设备节点时创建。
我不太了解kobjects,但它是如何使用kobj获得cdev的,以及我们在哪里将kobject与这个特定设备关联起来的?答案在于cdev_add
int cdev_add(struct cdev *p, dev_t dev, unsigned count)
{
int error;
p->dev = dev;
p->count = count;
error = kobj_map(cdev_map, dev, count, NULL,
exact_match, exact_lock, p);
if (error)
return error;
kobject_get(p->kobj.parent);
return 0;
}
cdev\u添加(cdev,dev,count)
将字符设备添加到系统中,将设备编号dev
与给定的cdev
对象相关联。当为给定的设备编号创建inode时,它将关联的cdev
对象存储在i\u cdev
字段中。cdev\u添加(cdev,dev,count)
向系统添加字符设备,将设备编号dev
与给定的cdev
对象关联。当为给定的设备编号创建inode时,它将相关的cdev
对象存储在i_cdev
字段中。