sysfs文件系统学习--sysfs
一、sysfs简介
1.sysfs就是利用VFS的接口去读写kobject的层次结构,建立起来的文件系统。其更新与删除是那些xxx_register()/unregister()做的事
情。从sysfs中读写就相当于从kobject层提取数据。每当新增一个kobject结构时,就会在sysfs中增加一个目录。kobject对应的是文件
夹,attribute对应的是该文件夹下的文件。它是一个简单的文件系统,不涉及任何硬件驱动。sysfs来源于设备的层次结构,读sysfs文件就是动态地从设备树中寻找相关节点提取信息,然后返回给用户。sysfs是用户
与内核的接口,也是用户与设备的接口,通过读写sysfs文件来查看和改变内核的配置。
2.设备模型支持功能如下:
1)电源管理和系统关机。
2)与用户空间通信。将控制接口通过文件的形式暴露给用户空间
3)支持热插拔。
4)设备分类。比如找USB鼠标直接去/sys/class/input/里面去找即可,而不用关心它是接在哪个USB控制器的那个hub的哪个端口上。
5)对象的生命周期。比如U盘拔掉以后,全局设备树和sysfs里面得相应的去掉。
3.sysfs文件用户读show()被调用,用户写store()被调用。
4.sfsfs是一个虚拟的文件系统,没有存储介质,掉电丢失。
mount -t vfat /dev/sda2 /mnt :有存储介质
mount -t sysfs sysfs /sys :没有存储介质
5.fs/sysfs目录下bin.c file.c dir.c symlink.c 分别代表了在sysfs文件系统中当文件类型为二进制文件,普通文件,目录,符号链接时各自的file_operations的实现。
二、sysfs用户空间测试
/sys/bus/usb/drivers_autoprobe:
在bus_register() --> add_probe_files() --> bus_create_file()
属性:S_IWUSR|S_IRUGO
每次向总线注册设备/驱动时,都会通过klist_drivers/klist_devices去匹配驱动/设备,
但是也可以通过bus_register()中创建的这个文件在用户空间使能或禁止这种自动匹配!其实它改的就是:
直接只更改struct bus_type bus->p->drivers_autoprobe的值。
1./sys/bus/usb/drivers_probe:
在bus_register() --> add_probe_files() --> bus_create_file()
属性:S_IWUSR
store(): store_drivers_probe(),如果dev->driver为NULL,下面操作就会重新触发设备匹配驱动
# echo 2-1:1.0 > /sys/bus/usb/drivers_probe
# echo 2-2.1:1.0 > /sys/bus/usb/drivers_probe
插上U盘:
# echo 0 > /sys/bus/usb/drivers_autoprobe
# ls /sys/bus/usb/devices/ 对出 1-2
# echo 1-2 > /sys/bus/usb/drivers_probe 然后多出1-2:1.0
# echo 1-2:1.0 > /sys/bus/usb/drivers_probe 然后/dev/sdb1就产生了!
2./sys/bus/usb/uevent
在bus_register() --> bus_create_file()
属性:S_IWUSR
store(): bus_uevent_store(),
bus和drivers目录下有uevent文件,而devices目录下没有.
可以输入kobject_actions中的字符,由于向用户空间广播事件
# echo add > /sys/bus/usb/uevent
# echo bind > /sys/bus/usb/uevent
# echo online > /sys/bus/usb/uevent
/sys/bus/usb/drivers和devices目录:
在bus_register() --> kset_create_and_add("devices")/kset_create_and_add("drivers")
3.U盘设备文件操作为例:
1)设备和驱动的绑定
/sys/bus/usb/drivers/usb-storage/unbind
函数:unbind_store 属性S_IWUSR,找到设备,然后释放其驱动
echo 1-2:1.0 > /sys/bus/usb/drivers/usb-storage/unbind 然后U盘的设备文件/dev/sdb1就消失了
/sys/bus/usb/drivers/usb-storage/bind
函数:bind_store 属性S_IWUSR,找到设备,然后重新执行match操作
echo 1-2:1.0 > /sys/bus/usb/drivers/usb-storage/bind U盘的设备文件/dev/sdb1重新出现并且挂载了
2)使用动态id_table可以使id动态地增减,增加了灵活性
/sys/bus/usb/drivers/usb-storage/new_id
属性:S_IWUSR | S_IRUGO
函数:
new_id_show :仅仅是打印动态id的厂商设备接口类信息
new_id_store :命令行参数获取:sscanf(buf, "%x %x %x %x %x", &idVendor, &idProduct, &bInterfaceClass, &refVendor, &refProduct);
也可以只指定idVendor和idProduct,新创建的动态id挂载usb_driver.dynids链表上,然后调用driver_attach()匹配驱动
# echo 0951 01666 3 4 5 > /sys/bus/usb/drivers/usb-storage/new_id
# echo 0951 01666 > /sys/bus/usb/drivers/usb-storage/new_id
# cat /sys/bus/usb/drivers/usb-storage/new_id
/sys/bus/usb/drivers/usb-storage/remove_id
属性:S_IWUSR | S_IRUGO
函数:
remove_id_show :直接调用的是new_id_show,仅仅打印出可以remove的动态id
remove_id_store :就是直接将此id从usb_driver->dynids.list删除
# echo 0951 01666 > /sys/bus/usb/drivers/usb-storage/remove_id
# cat /sys/bus/usb/drivers/usb-storage/remove_id
三、设备的底层模型
1.kobject
- struct kobject {
- const char *name; /*恒指向设备名称的指针*/
- struct list_head entry; /*使用它挂接在kset中*/
- struct kobject *parent; /*指向父对象(可能是kset.kobj)*/
- struct kset *kset; /*所属的kset,device_init()中指向为全局devices_kset*/
- struct kobj_type *ktype; /*指向其对象类型描述符的指针*/
- struct kernfs_node *sd; /* sysfs directory entry */
- struct kref kref; /*对象的引用计数,通过kobject_get()/kobject_put()访问*/
- #ifdef CONFIG_DEBUG_KOBJECT_RELEASE
- struct delayed_work release;
- #endif
- unsigned int state_initialized:;
- unsigned int state_in_sysfs:;
- unsigned int state_add_uevent_sent:;
- unsigned int state_remove_uevent_sent:;
- unsigned int uevent_suppress:;
- };
entry, parent, kset用来构成树状的结构的指针。相关函数有kobj_add() kobj_put()等
2.kset
- struct kset {
- struct list_head list;
- spinlock_t list_lock;
- struct kobject kobj;
- const struct kset_uevent_ops *uevent_ops;
- } __randomize_layout;
一个kset里面的所有kobject组成一个双向循环链表,list是链表头。相同类型(kobj_type)的kobject集合在一起组成kset.
相关函数有kset_get() kset_put()等。
3.kobj_type
- struct kobj_type {
- void (*release)(struct kobject *kobj);
- const struct sysfs_ops *sysfs_ops; /*里面有show store*/
- struct attribute **default_attrs; /*属性以文件的形式存储在sysfs中,文件名就是.name,*/
- const struct kobj_ns_type_operations *(*child_ns_type)(struct kobject *kobj);
- const void *(*namespace)(struct kobject *kobj);
- };
attribute以文件的形式输出到sysfs的目录中,文件名就是name.kobject是连接attribute与sysfs的桥梁。文件读写对应于
kobj_type中的sysfs_ops,里面有show()和store()
kobject:
kobject_set_name(): 为kobj对象进行命名时里面的'/'将会被替换为'!'
kobject_del(): 会调用sysfs_remove_dir(kobj),删除一个目录也会先删除其所有的子目录或文件
kobject_add(): 会增加父目录各级kobject的引用计数,在其parent指向的目录下创建文件节点,并启动该类型内核对现的hotplug函数
kobject_add(): 会将kogj的引用计数减1,减为0后就会调用kobject_release()释放该对象。
kset:
kset_register(): 中调用了kobject_uevent(&k->kobj, KOBJ_ADD);
kset_unregister(): 只调用kobject_del(&k->kobj);kobject_put(&k->kobj);
struct device:
device_register()将一个device对象插入设备模型中,并在/sys/devices下创建一个对应的目录。
device_unregister()完成相反操作,注销设备。get_device()/put_device()分别增加减少引用计数。
它通常嵌入到其它结构体中使用
device_register() --> device_add() --> kobject_uevent(&dev->kobj, KOBJ_ADD);
四、设备模型的上层容器: bus、device、device_driver
1.总线bus是处理器与设备之间的通道。在设备模型中所有设备都是通过总线进行连接。即使设备没有在一根物理的总线上,也会设置
一个内部虚拟的平台总线来维持总线、设备、驱动的三角关系。
2.struct bus_type:每个bus_type对象都对应于/sys/bus目录下的一个子目录。使用bus_register()向系统中注册总线
3.device_register()将一个新的device对象插入设备模型中,并在/sys/devices/下创建对应的目录
五、代码阅读总结
1.file_operations dentry_operations inode_operations super_operations 实现一个文件系统需要实现这4个函数集合
file_operations:是对每一个具体的文件进行的读写操作
dentry_operations inode_operations 是对文件的属性进行更改,如更改名字,建立或删除操作。
2..对于不同的文件系统,open()系统调用调用到的是不同的file_operations.open()
3.进程通过目录项和索引节点描述文件
4.文件包含两方面的信息,存储的数据本身和有关该文件的组织和管理信息。每个文件都有一个dentry(目录项)和inode(索引节点,物理意义上的文件)。
dentry记录着文件名和上级目录信息等,形成树状结构。inode里面存放该文件的组织和管理信息。dentry和inode是一对多的关系,
因为可能一个文件有好几个文件名。
5.文件可分为:磁盘文件,设备文件,特殊文件
6.要打开/home/hello.c,先找到‘/’,读入其内容,找到名为'home'的文件的索引节点号,打开'/home'这个文件,找到名为‘hello.c’这个
文件的索引节点号,最后就得到‘/home/hello.c’了。
7.使用glibc进行读写的系统调用次数可能和读写调用的次数不一样!又封装了一下。
8.不管是bus还是设备添加到系统后都会调用kobject_uevent(&dev->kobj, KOBJ_ADD);
9.struct bus_type中有很多与struct driver重复的函数指针,这些函数在注册的时候只要bus的存在就使用bus的,bus的不存在才会使用
driver的,若两者都存在某些函数还会报警告!
10.module_add_driver(drv->owner, drv): usbstorge: /sys/bus/usb/drivers/usb-storage下创建到/sys/module的连接
11.创建sysfs文件:driver_create_file() --> sysfs_create_file(&drv->p->kobj, &attr->attr);
12.注册的bus和注册的驱动指向的bus可以是不是一个的,driver的bus用来为driver提供一些函数,好像driver并产生设备模型并没有涉及到bus
13.设备驱动绑定
bus_add_driver
如果 drv->probe_type == PROBE_PREFER_ASYNCHRONOUS, 则进行异步匹配
否则同步匹配,调用driver_attach()
bus_for_each_dev()
如果bus->match存在(usb_storage的是存在的),则调用bus的然后返回。如果不存在,调用really_probe
driver_bound()将设备加到驱动的链表中
kobject_uevent(&dev->kobj, KOBJ_BIND); 发送bind的事件,但是udevadm监听不到是因为没有在rules.d里面加吗?
sysfs文件系统学习--sysfs的更多相关文章
- proc文件系统、sysfs文件系统、kobject操作
Proc文件系统是提供一个接口给用户,让用户可以查看系统运行的一些状态信息,让用户修改内核的一些参数,比方说printk的打印级别就可以通过proc去修改 Sysfs文件系统, Sysfs is a ...
- Linux设备模型——设备驱动模型和sysfs文件系统解读
本文将对Linux系统中的sysfs进行简单的分析,要分析sysfs就必须分析内核的driver-model(驱动模型),两者是紧密联系的.在分析过程中,本文将以platform总线和spi主控制器的 ...
- sysfs文件系统的建立【转】
http://blog.csdn.net/dndxhej/article/details/7434615 对sysfs和设备模型有了解的都会知道sysfs实际是为了将设备模型导出到用户空间的一个内存文 ...
- [中英对照]The sysfs Filesystem | sysfs文件系统
The sysfs Filesystem | sysfs文件系统 Abstract | 摘要 sysfs is a feature of the Linux 2.6 kernel that allow ...
- 概述sysfs文件系统【转】
转自:http://blog.csdn.net/npy_lp/article/details/78933292 内核源码:linux-2.6.38.8.tar.bz2 目标平台:ARM体系结构 sys ...
- Sysfs文件系统与Linux设备模型
转:http://www.360doc.com/content/11/1218/16/1299815_173168170.shtml sysfs把连接在系统上的设备和总线组织成为一个分级的目录及文件, ...
- sysfs文件系统
3 sysfs文件系统 sysfs是一个基于内存的文件系统,它的作用是将内核信息以文件的方式提供给用户程序使用.该文件系统的目录层次结构严格按照内核的数据结构组织.除了二进制文件外(只有特殊场合才使用 ...
- Linux 内核sysfs 文件系统符号连接
sysfs 文件系统有通常的树结构, 反映它代表的 kobjects 的层次组织. 但是内核中对象 间的关系常常比那个更加复杂. 例如, 一个 sysfs 子树 (/sys/devices )代表所有 ...
- Documentation/filesystems/sysfs.txt 文档翻译--sysfs
sysfs - 用于导出内核对象的文件系统. 1.sysfs是一个基于ram的文件系统,最初基于ramfs. 它提供了一种方法,可以将内核数据结构,它们的属性以及它们之间的链接导出到用户空间.sysf ...
随机推荐
- python webdriver 测试框架-数据驱动txt文件驱动,带报告的例子
数据驱动txt文件驱动的方式,带报告 data.txt: gloryroad test||光荣之路 摔跤爸爸||阿米尔 超人||电影 data_driven_by_txt_file.py: #enco ...
- poj3071 Football(概率dp)
poj3071 Football 题意:有2^n支球队比赛,每次和相邻的球队踢,两两淘汰,给定任意两支球队相互踢赢的概率,求最后哪只球队最可能夺冠. 我们可以十分显然(大雾)地列出转移方程(设$f[ ...
- bzoj 4443: [Scoi2015]小凸玩矩阵
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 149 Solved: 81[Submit][Status][Discuss] Description ...
- Vim 的光标移动定位
一.光标移动以单个字符为单位: 在命令模式中 h向左 l 向右 j 向上 k 向下 二.光标移动以word 为单位: w 将光标向前移动一个word; b 将光标向后移动一个word: 以上2个命令光 ...
- Java加密代码 转换成Net版
java版本自己封装base64 package com.qhong; import java.io.UnsupportedEncodingException; import org.apache.c ...
- shell脚本监控Linux系统性能指标
2016-11-04 22:41 原作者不详 分类: Linux(7) 在服务器运维过程中,经常需要对服务器的各种资源进行监控, 例如:CPU的负载监控,磁盘的使用率监控,进程数目监控等等,以在系统出 ...
- Java Spring-传统AOP开发
2017-11-10 17:25:48 Spring中通知Advice类型(增强代码): 前置通知,org.springframework.aop.MethodBeforeAdvice:方法前 后置通 ...
- 使用触发器定义 WPF 控件的行为
Expression Studio 4.0 其他版本 Expression Studio 3.0 Expression Studio 2.0 此主题尚未评级 - 评价此主题 在应用程序的生 ...
- PHP--------解决网址URL编码问题
在PHP中有urlencode().urldecode().rawurlencode().rawurldecode()这些函数来解决网页URL编码解码问题. 理解urlencode: urlencod ...
- 返回值为 Record类型的函数 初始化 Result
function TMiTeC_Storage.GetPhysInfo(Index: integer): TDeviceInfo; begin Finalize(Result); FillChar(R ...