字符设备驱动 与 kobject

版权声明:本文为博主原创文章,任何组织或者个人可以在任何媒介上发表或转载我的文章、图片等.且转载后必须注明出处和邮箱,博客地址(https://blog.csdn.net/u011011827),本人邮箱([email protected]) https://blog.csdn.net/u011011827/article/details/82115378
前言
本文大量引用了 Linux设备管理(二)_从cdev_add说起kobject在字符设备中的使用

本文讨论的是字符设备驱动与 kobject 的关系

且在这个驱动中

设备文件是通过mknod工具建立的,不是通过 class_create 和 device_create 建立的

此为讨论的基础

Q&A


Q:字符设备驱动函数解析 中有两处提到了 object,字符设备驱动就 符合  了 object 对应的 sysfs 架构了吗?

A:没有符合.

Q:为什么没有符合

A:虽然使用了 kobject ,并把它注册到了内核,但是是注册到了 cdev_map ,并没有注册到  /sys/ 目录下. cdev_map 不属于 object 架构

Q:既然不注册到 sys 下面, 那字符设备驱动为什么要使用  object

A: 在这里使用 object ,是为了使用 object 中的 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 和 object

A: object 的底层就是利用了 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 中的文件夹



kobject在字符设备中的使用 文章中的重点



前面你和wowo已经论证过cdev与设备模型无关,那么你是怎么理解cdev中出现的kobject? 没看出来它在这里的作用。

设备模型中大量使用了kobject,但是kobject并不是仅仅for设备模型的。 
对于cdev这个场景,kobject主要是应用两点: 
1、reference count。 
2、ktype中的release函数 

基本上可以这么认为,cdev中的kobject没有完全发挥其功能,假设其全部功能有10条,实际只用了2条。是不是很浪费?当然是很浪费了,如果有可能,最好定义一个基类,只包括上面的那两点功能,kobject派生于此基类,cdev也是派生于此基类。当然,是否定义这样的基类应该是内核中的应用场景相关,如果有大量类似cdev这样的场景,我们相信内核人员有可能定义这样的基类


这两点功能,其中一点(reference count),kernel中已经有一个基类了,即struct kref,kobject也正是派生于kref。 
至于第二点,应该就是kobject诞生的初衷。

Linux设备管理(二)_从cdev_add说起 文章中的重点


扒完了字符设备的注册过程,不知各位看官有没有发现,全程没有一个初始化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



Linux中几乎所有的"设备"都是"device"的子类,无论是平台设备还是i2c设备还是网络设备,但唯独字符设备不是,
从"Linux字符设备驱动框架"一文中我们可以看出cdev并不是继承自device,从"Linux设备管理(二)_从cdev_add说起"一文中我们可以看出注册一个cdev对象到内核其实只是将它放到cdev_map中

直到"Linux设备管理(四)_从sysfs回到ktype"一文中对device_create的分析才知道此时才创建device结构并将kobj挂接到相应的链表.

基于历史原因,当下cdev更合适的一种理解是一种接口(使用mknod时可以当作设备),而不是而一个具体的设备,和platform_device,i2c_device有着本质的区别

猜你喜欢

转载自blog.csdn.net/u011011827/article/details/82115378