一、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的更多相关文章

  1. proc文件系统、sysfs文件系统、kobject操作

    Proc文件系统是提供一个接口给用户,让用户可以查看系统运行的一些状态信息,让用户修改内核的一些参数,比方说printk的打印级别就可以通过proc去修改 Sysfs文件系统, Sysfs is a ...

  2. Linux设备模型——设备驱动模型和sysfs文件系统解读

    本文将对Linux系统中的sysfs进行简单的分析,要分析sysfs就必须分析内核的driver-model(驱动模型),两者是紧密联系的.在分析过程中,本文将以platform总线和spi主控制器的 ...

  3. sysfs文件系统的建立【转】

    http://blog.csdn.net/dndxhej/article/details/7434615 对sysfs和设备模型有了解的都会知道sysfs实际是为了将设备模型导出到用户空间的一个内存文 ...

  4. [中英对照]The sysfs Filesystem | sysfs文件系统

    The sysfs Filesystem | sysfs文件系统 Abstract | 摘要 sysfs is a feature of the Linux 2.6 kernel that allow ...

  5. 概述sysfs文件系统【转】

    转自:http://blog.csdn.net/npy_lp/article/details/78933292 内核源码:linux-2.6.38.8.tar.bz2 目标平台:ARM体系结构 sys ...

  6. Sysfs文件系统与Linux设备模型

    转:http://www.360doc.com/content/11/1218/16/1299815_173168170.shtml sysfs把连接在系统上的设备和总线组织成为一个分级的目录及文件, ...

  7. sysfs文件系统

    3 sysfs文件系统 sysfs是一个基于内存的文件系统,它的作用是将内核信息以文件的方式提供给用户程序使用.该文件系统的目录层次结构严格按照内核的数据结构组织.除了二进制文件外(只有特殊场合才使用 ...

  8. Linux 内核sysfs 文件系统符号连接

    sysfs 文件系统有通常的树结构, 反映它代表的 kobjects 的层次组织. 但是内核中对象 间的关系常常比那个更加复杂. 例如, 一个 sysfs 子树 (/sys/devices )代表所有 ...

  9. Documentation/filesystems/sysfs.txt 文档翻译--sysfs

    sysfs - 用于导出内核对象的文件系统. 1.sysfs是一个基于ram的文件系统,最初基于ramfs. 它提供了一种方法,可以将内核数据结构,它们的属性以及它们之间的链接导出到用户空间.sysf ...

随机推荐

  1. uva1391 2-SAT 问题

    题意在大白书上. 有3 种工作 abc 大于等于平均年龄的可以去做a c 工作, 小于平均年龄的可以去做 bc , 同样转化为2 -sat 去做, 因为对于每个人也只有2 种情况可以作为选择 #inc ...

  2. Linux命令: grep命令

    基本用法                                                                                                 ...

  3. MySQL事务概述-1

    事务是数据库区别于文件系统最重要的特性之一.事务可由一条非常简单的SQL语句组成,也可以由一组复杂的SQL语句组成.事务是访问并更新数据库中各种数据项的一个程序执行单元.在事务操作中,要么都做修改,要 ...

  4. P2831 愤怒的小鸟(状压dp)

    P2831 愤怒的小鸟 我们先预处理出每个猪两两之间(设为$u,v$)和原点三点确定的抛物线(当两只猪横坐标相等时显然无解) 处理出$u,v$确定的抛物线一共可以经过多少点,记为$lines[u][v ...

  5. # 20145106 《Java程序设计》第3周学习总结

    教材学习内容总结 在本周的学习中,我看到了这样一句话:"使用java撰写程序几乎都是在使用对象(object),要产生对象必须先定义类(class),类是对象的设计图,对象是类的实例(ins ...

  6. c++生成算式并计算(《构建之法》第一章课后第一题)

    c++实现计算器(自动生成算式并计算) 要满足的需求有以下几个: 自动生成随机的四则运算算式,包含括号和小数. 对生成的算式计算出结果. 算式.结果分别存储到不同的文件. 一 生成算式 由上述需求可知 ...

  7. HBase优化相关

    1.HBase预分区 HBase在创建表时,默认会自动创建一个Region分区.在导入数据时,所有客户端都向这个Region写数据,直到这个Region足够大才进行切分.这样在大量数据并行写入时,容易 ...

  8. POJ 3422 Kaka's Matrix Travels(拆点+最大费用流)题解

    题意:小A从左上角走到右下角,每个格子都有一个价值,经过这个格子就把价值拿走,每次只能往下或往右走,问你走k次最多能拿多少价值的东西. 思路:这里有一个限制条件就是经过之后要把东西拿走,也就是每一格的 ...

  9. R中的路径设置

    软件的路径设置对于电脑的内存管理和自己的寻根究底十分重要.所以,合理的设置R中相关路径,能更加方便快捷的管理自己的相关文件,提高学习R语言的效率,建立自己的习惯体系. R中的路径设置主要有以下几个方面 ...

  10. python 判断字典是否为空

    my_dict = {} if not bool(my_dict): print("Dictionary is empty")