设为首页 加入收藏

TOP

Linux设备管理(四)_从sysfs回到ktype(一)
2016-12-28 08:16:08 】 浏览:405
Tags:Linux 设备管理 sysfs 回到 ktype

sysfs的布局体现内核的数据结构,顶层的目录有


每一个目录都对应内核中的一个kset,每一个kset还会包含一些kobject或其他kset。下面针对常用目录做一个简单的介绍


块设备的存放目录,这是一个过时的接口,按照sysfs的设计理念,所有的设备都存放在"sys/devices/"同时在"sys/bus/"或(和)"sys/class/"存放相应的符号链接,所以现在这个目录只是为了提高兼容性的设计,里面的文件已经被全部替换成了符号链接,只有在编译内核的时候勾选CONFIG_SYSFS_DEPRECATED才会有这个目录,


bus包含了系统中所有的总线,比如我的系统当前提供的总线有:


每一种总线通常还有两个子目录:device和driver,这两个字目录分别对应内核中的两个kset,同时bus本身也对应一个kset,也有自己的kobject和以及(可能)有相应的ktype。我们可以查看相应的kset属性。


我们可以扒一下3.19的源码,找到这个属性


同时,根据kset的组织形式,平台总线的设备kset链接了挂接在平台总线上的所有设备,所以"platform/devices"下应该可以查看到,要注意的事,为了使一个设备在sysfs中只有一个实例,很多目录都是使用符号链接的形式,下面显示的结果也验证了这种设计。


按照设备功能对系统设备进行分类的结果放在这个目录,如系统所有输入设备都会出现在 "/sys/class/input"之下。和sys/bus一样,sys/class最终的文件都是符号链接,这种设备可以保证整个系统中每一个设备都只有一个实例。


按照设备号对字符设备和块设备进行分类的结果放在这个目录,同样,文件依然是使用符号链接的形式链接到"sys/devices/"中的相应文件


如前所述,所有的设备文件实例都在"sys/devices/"目录下,


"sys/class/","sys/bus/","sys/devices"是设备开发中最重要的几个目录。他们之间的关系可以用下图表示。


这里按照设计是用于描述系统中所有文件系统,包括文件系统本身和按文件系统分类存放的已挂载点,但目前只有 fuse,gfs2 等少数文件系统支持 sysfs 接口,一些传统的虚拟文件系统(VFS)层次控制参数仍然在 sysctl (/proc/sys/fs) 接口中中;


这里是内核所有可调整参数的位置,目前只有 uevent_helper, kexec_loaded, mm, 和新式的 slab 分配器等几项较新的设计在使用它,其它内核可调整参数仍然位于 sysctl (/proc/sys/kernel) 接口中 ;


这里有系统中所有模块的信息,不论这些模块是以内联(inlined)方式编译到内核映像文件(vmlinuz)中还是编译为外部模块(ko文件),都可能会出现在 /sys/module 中:编译为外部模块(ko文件)在加载后会出现对应的/sys/module/


这里是系统中电源选项,这个目录下有几个属性文件可以用于控制整个机器的电源状态,如可以向其中写入控制命令让机器关机、重启等。


(对应 2.6.23 内核,在 2.6.24 以后移至/sys/kernel/slab) 从2.6.23 开始可以选择 SLAB 内存分配器的实现,并且新的 SLUB(Unqueued Slab Allocator)被设置为缺省值;如果编译了此选项,在 /sys 下就会出现 /sys/slab ,里面有每一个 kmem_cache 结构体的可调整参数。对应于旧的 SLAB 内存分配器下的/proc/slabinfo 动态调整接口, 新式的 /sys/kernel/slab/


对于每一个注册到内核的kobject,都会在sysfs中创建一个目录!!!一个目录!!!一个目录!!!,目录名就是kobject.name,这个目录会从属于kobject.parent对应的目录,我们就可以实现在sysfs中用树状结构来呈现内核中的kobject。最初的sysfs下顶层目录下的目录使用subsystem的结构,在某些书中还会见到这个概念,不过现在已经被kset替代了。在 kobject 下还有一些符号链接文件,指向其它的 kobject,这些符号链接文件用于组织上面所说的 device, driver, bus_type, class, module 之间的关系。我们再来看看kobject结构:


这其中的symlink就组成了下面的符号链接,许许多多这样的符号链接就构成了整个sysfs的符号链接体系


在sysfs中,kobject的属性(kobject.ktype.attribute)可以以普通文件的形式导出,sysfs还提供了使用文件I/O直接修改内核属性的机制,这些属性一般都是ASCII格式的文本文件(ktype.attribute.name)或二进制文件(通常只用在sys/firmware中),为了提高效率,可以将具有同一类型的属性放置在一个文件中,这样就可以使用数组进行批量修改,不要在一个文件中使用混合类型,也不要使用多行数据,这些做法会大大降低代码的可读性,下面就是一个属性的定义,可以看到,属性中并没有包含读写属性的函数,但是从面向对象的思想看,内核提供了两个用于读写attribute结构的函数。


由于一个ktype往往包含很多属性(default_attr是一个二级指针),当用户通过sysfs读写一个kobject的属性的时候,会自动回调ktype中的sysfs_ops->show()sysfops->remove(),所以一个典型的做法是,当我们创建了一个继承自kobject的子类child后,同时还会创建两个调用了sysfs_create_file()sys_remove_file()的读写函数,并将它们注册到struct sysfs_ops中。比如内核使用的struct device就将相应的方法和属性都封装在了一起。


此外,内核甚至还提供了辅助定义这个属性的宏


有了这个宏,我们就可以直接通过这个接口创建我们自己的对象


我们可以追一下源码,可以发现,我们使用的自动创建设备文件device_create()就会调用device_create_file()并最终调用sysfs_create_file()


当一个子系统定义了一个新的属性,它必须执行一组针对的sysfs操作以便对实现对属性的读写,这些读写操作通过回调ktype.sysfs_ops.show()和store()


当进行读写的时候,sysfs会分配一个PAGE_SIZE大小的buf并把它作为参数传入这两个函数,同时,对于每一次对属性的读写操作,sysfs都会调用这两个函数,所以,调用read系统调用的时候,show()方法应该填满整个buf,注一个属性应该是一个或一组相似的值,所以这种机制并不会浪费很多系统资源。这种机制允许用户读取一部分内容并且可以任意的移动文件位置指针,如果用户空间将文件指针置为0或以0为偏移量调用了pread()show()会被重新调用并且再填满一个buf。类似地,调用write()系统调用的时候,sysfs希望第一次传入的buf是被填满的,sysfs会在传入的数据最后自动加NUL,这可以让诸如sysfs_strqe()一类的函数用起来更安全。当对sysfs执行写操作时,用户空间

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Android中Activity的四大启动模式.. 下一篇Android中AlarmManager使用示例

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目