一、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. 2017 Benelux Algorithm Programming Contest (BAPC 17) Solution

    A - Amsterdam Distance 题意:极坐标系,给出两个点,求最短距离 思路:只有两种方式,取min  第一种,先走到0点,再走到终点 第二种,走到同一半径,再走过去 #include ...

  2. InFusion错误类型分析

    1       God Class 1.1     特征 上帝类通常过多的操纵其他类的数据,从而破坏了类的封装性.上帝类从其他类中获得功能,同时增加了自身的耦合性,通常会导致自己具有规模过大和较高的复 ...

  3. DB开发之oracle存储过程

    1. 存储过程格式 /* Formatted on 2011/1/17 13:20:44 (QP5 v5.115.810.9015) */ CREATE OR REPLACE procedure pr ...

  4. bzoj1613 / P1353 [USACO08JAN]跑步Running

    P1353 [USACO08JAN]跑步Running 显然的dp 设$f[i][j]$表示进行到第$i$分钟时,$j$疲劳度下的最远距离,$d[i]$为第$i$分钟下能跑的距离 分类讨论 1.运动: ...

  5. iptables命令、规则、参数详解

    表    (table)包含4个表:4个表的优先级由高到低:raw-->mangle-->nat-->filterraw---RAW表只使用在PREROUTING链和OUTPUT链上 ...

  6. 基于OpenCV进行图像拼接原理解析和编码实现(提纲 代码和具体内容在课件中)

    一.背景 1.1概念定义 我们这里想要实现的图像拼接,既不是如题图1和2这样的"图片艺术拼接",也不是如图3这样的"显示拼接",而是实现类似"BaiD ...

  7. linux及安全第六周总结——20135227黄晓妍

    总结部分: 操作系统内核三大功能: 进程管理,内存管理,文件系统 最核心的是进程管理 为了管理,首先要对每一个进程进行描述.进程描述符提供了所有内核需要了解的信息. 进程控制模块:task_struc ...

  8. 中通快递单api查询

    request POST https://hdgateway.zto.com/WayBill_GetDetail HTTP/1.1Host: hdgateway.zto.comConnection: ...

  9. 【查看内存】Linux查看内存使用情况(一)

    用 'top -i' 看看有多少进程处于 Running 状态,可能系统存在内存或 I/O 瓶颈,用 free 看看系统内存使用情况,swap 是否被占用很多,用 iostat 看看 I/O 负载情况 ...

  10. Yii框架(二)Model处理数据

    熟悉php的autoload机制,自己实现一个autoload函数 一.复习框架: basic/ 应用根目录 composer.json Composer 配置文件, 描述包信息 config/ 包含 ...