Q:字符设备驱动函数解析中有两处提到了kobject,字符设备驱动就符合了kobject 对应的 sysfs 架构了吗?
A:没有符合.
Q:为什么没有符合
A:虽然使用了kobject ,并把它注册到了内核,但是是注册到了cdev_map ,并没有注册到/sys/ 目录下. cdev_map不属于kobject 架构
Q:既然不注册到/sys 下面, 那字符设备驱动为什么要使用kobject
A: 在这里使用kobject ,是为了使用kobject 中的 reference count 和 release . 并不是为了注册到/sys
详情请查看 http://www.wowotech.net/bbs/116.html
Q: 那为什么不再 抽象一个 reference count 和 release
A: 没有必要,像字符设备需要这两个参数的设备太少了
Q: 那如果非要字符设备驱动和 sys系统建立联系呢?
A: 可以调用 class_create 和 device_create 函数 分别在 sys 目录下创建 class_name 目录 和 device_name 目录,并在 device_name 目录中创建属性文件
Q: 你好像混合了sys 和kobject
A: kobject 的底层就是利用了sysfs 实现的,所以你可以将他们看成是一样的.
Q: 如此看来, 字符设备在 sys 中并不是个设备,但是如果用其他框架(platform)创建字符设备会在 /sys 中创建设备文件,那么 字符设备对于 object 的意思是什么呢?
A: 类似一个接口. object 创建了设备文件,但并不会注册 ops 和 设备号.
恰恰, 这个字符设备框架(register_chrdev_region 和 cdev_init 和 cdev_add) 的作用就是 注册 设备号和 ops .所以 这个字符设备框架可以说是以 是 kobject 的 一种 接口存在.它不属于 kobject .
Q: class_create 和 device_create 是字符设备驱动的必备成分吗?
A : 不是,你可以在shell中手动 用 mknod 命令 在 /dev 目录 手动创建文件
Q : class_create 和 device_create 是怎么创建 /dev 目录下的文件的?
A : 通过 用户层的 udev 进程.udev 一直在监控 /sys/ ,class_create 和 device_create 在 /sys目录下创建了文件,然后 udev 就查到设备类型 和 名称 和 设备号 ,调用 mknod系统调用在 /dev 下面 创建了文件.
Q: 仅仅mknod 和 调用 class_create 和 device_create 有什么区别
A: 仅仅mknod 在 /dev 创建了设备文件,没有将设备注册到 /sys 系统中, /sys 目录下 没有对应的文件
调用 class_create 和 device_create 在 /dev 创建了设备文件,并将设备注册到 /sys 系统中, /sys 目录下 有对应的文件
Q: kobject 到底是什么
A: 可以说是 /sys 的上层实现.调用了 /sys 的底层实现(fs_create_file fs_mkdir)
也可以说是驱动设备总线模型的实现内核.
其实,他只是将内核中的东西,依据 struct object 创建树型结构
并将与 struct object 结构体相关的各种变量拿到了用户空间,形成目录架构展示给用户.
kobject 不仅用于驱动,还用于 模块,文件系统,具体可以看一下 /sys 中的文件夹
总结:
1.字符设备接口cdev_init /cdev_add只是将struct cdev这个对象注册到cdev_map,没有注册到/sys完成常用kobject和sys框架
2.可以调用 class_create 和 device_create 函数 分别在 sys 目录下创建 class_name 目录 和 device_name 目录,并在 device_name 目录中创建属性文件
3.字符设备框架类似一个接口. kobject 创建了设备文件,但并不会注册 ops 和 设备号.
恰恰, 这个字符设备框架(register_chrdev_region 和 cdev_init 和 cdev_add) 的作用就是 注册 设备号和 ops .所以 这个字符设备框架可以说是以 是 kobject 的 一种接口存在.它不属于 kobject .
扒完了字符设备的注册过程,不知各位看官有没有发现,全程没有一个初始化cdev.kobj的函数!
到此为止,我们都是通过cdev_map来管理系统里的字符设备的,
所以,我们并不能在sysfs找到我们此时注册的字符设备.
更深层的原因是内核中并不直接使用cdev作为一个设备,而是将其作为一个设备接口
使用这个接口我们可以派生出misc设备,输入设备,LCD等等
当初始化这些具体的字符设备的时候,相应的list_head对象才可能被打开挂接到相应的链表,并初始化kobj。
即如果希望sysfs中找到我们的字符设备,我们就必须对cdev.kobj进行初始化,挂接到合适的kset
这也就是导出设备信息到sysfs以便自动创建设备文件的原理。
--------------------------
导出设备信息到sysfs以便自动创建设备文件的原理
在注册设备之后.只需要导出相应的设备信息到"/sys"就可以按照我们的要求自动创建设备文件。内核给我们提供了相关的API
class_create(owner,name);
struct device *device_create_vargs(struct class *cls, struct device *parent,dev_t devt, void *drvdata,const char *fmt, va_list vargs);
void class_destroy(struct class *cls);
void device_destroy(struct class *cls, dev_t devt);
有了这几个函数,我们就可以在设备的xxx_init()和xxx_exit()中分别填写以下的代码就可以实现自动的创建删除设备文件
/* 在/sys中导出设备类信息 */
cls = class_create(THIS_MODULE,DEV_NAME);
/* 在cls指向的类中创建一组(个)设备文件 */
for(i= minor;i<(minor+cnt);i++){
devp = device_create(cls,NULL,MKDEV(major,i),NULL,"%s%d",DEV_NAME,i);
}
/* 在cls指向的类中删除一组(个)设备文件 */
for(i= minor;i<(minor+cnt);i++){
device_destroy(cls,MKDEV(major,i));
}
/* 在/sys中删除设备类信息 */
class_destroy(cls); //一定要先卸载device再卸载class
原文链接:https://blog.csdn.net/u011011827/article/details/82115378
版权声明:本文为weixin_42703045原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。