Linux设备模型 (2)》和《Linux设备模型 (3)》主要通过一些简单的实作介绍了kobject、kset、kobj_type、attribute等数据结构的用法,但这些实作并没有涉及到实际环境下的设备模型和sysfs。本文将以/sys下的module子目录为例,看看内核是如何构建sysfs这棵大树的。

(注:本文的分析基于2.6.36内核)

module的创建

当module被insmod到内核空间时,/sys/module目录下会相应创建一个和模块同名的目录。我们以usb_storage为例,在执行完sudo modprobe usb_storage之后,sysfs里会产生一个名为usb_storage的目录,其目录结构是:

在Linux 2.6内核里,module的插入是由用户程序insmod(modprobe最终也是调用insmod)发起的,但大部分工作还是由内核完成。我们可以用strace来观察一下insmod的流程。

stat64("/sys/module/usb_storage", 0xbfb9a654) = -1 ENOENT (No such file or directory)
open("/lib/modules/2.6.35-24-generic/kernel/drivers/usb/storage/usb-storage.ko", O_RDONLY) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=94776, ...}) = 0
mmap2(NULL, 94776, PROT_READ|PROT_WRITE, MAP_PRIVATE, 3, 0) = 0xb776f000
close(3)                                = 0
init_module(0xb776f000, 94776, "")      = 0
munmap(0xb776f000, 94776)               = 0
exit_group(0)                           = ?

从这个流程我们可以看到,insmod在执行时,首先会把module的内容映射到内存里,然后呼叫系统调用init_module来实现真正的工作。

如上图所示,这是系统调用init_module的执行路径。因为本文只是讨论设备模型和sysfs,流程图里只涉及到相关的内容。

1、mod_sysfs_init首先会查询当前模块(本例中是usb_storage)在sysfs中是否已经存在,如果没有,则调用kobject_init_and_add创建之;

2、调用kobject_create_and_add创建holders目录。holders目录用于存放指向其他module的链接,这里的其他module都是依赖于当前module的。以usb_storage为例,如果我们需要使用ums_XX模块(比如ums_karma或者ums_freecom等),可以调用sudo modprobe ums_XX来完成加载,因为ums_XX依赖于usb_storage,所以在usb_storage/holders目录下就会创建指向ums_XX的链接,同时refcnt也会加1;

3、module_param_sysfs_setup用来创建parameters目录,这个目录里的文件对应着当前module的所有参数。在Linux内核里,module的二进制ko文件中的__param section用来存储当前module的参数,load_module会把这些参数读取到内存结构里,module_param_sysfs_setup再根据相应的结构来创建paramters目录及其参数文件;

4、module_add_modinfo_attrs用来创建当前module目录下的4个文件:version、srcversion、refcnt和initstate,其中version和srcversion的信息存储在二进制ko文件的.modinfo section里。对于usb_storage模块来说,并没有指定version,所以不存在version这个文件。顺便罗嗦一句,在Linux内核里,可以用宏MODULE_VERSION定义版本号,比如MODULE_VERSION("v1.00")定义版本号为v1.00,这里的版本信息完全是字符串,并无特定格式。srcversion可以由MODULE_INFO(srcversion, xxx)来定义,但一般情况下由modpost默认生成就可以了。refcnt反映当前module的引用计数。initstate反映module的三种状态:live、coming和going;

5、add_usage_links和holders是密切相关的,但这个函数并不是操作当前module的holders目录。以ums_XX为例,在ums_XX的加载过程中,其add_usage_links会把自己作为链接加到usb_storage的holders目录下;

6、sections目录对应当前module的二进制ko文件里的section信息,这是通过add_sect_attrs实现的。需要提醒一下的是,section的命名通常以“.”开头,而以“.”开头的文件在Linux里被认为是隐藏文件,所以如果要察看的话要在ls命令后加"-a"参数,下面谈到的notes同样需要这样处理;

7、add_notes_attrs用来创建notes目录。ELF文件格式定义了一种名为note的元素,主要用于给二进制文件添加一些标示信息。通常,我们可以用readelf来察看ELF文件是否包含note section。比如usb_storage,我们可以使用命令“readelf usb-storage.ko -n”察看,其输出如下:

Notes at offset 0x00000034 with length 0x00000024:

Owner Data size Description

GNU 0x00000014 NT_GNU_BUILD_ID (unique build ID bitstring)

相应的,在/sys/module/usb_storage/notes目录下建立的notes文件就是.note.gnu.build-id。

上面的7条流程里,并无创建drivers的地方,那/sys/module/usb_storage下的drivers目录是如何建立的呢?答案在下图:

在usb_storage的module_init中,会调用usb_register来注册usb_driver结构,如图中所示,最终会调用module_add_driver来创建drivers目录。

module的撤销

module的撤销过程和前文中的创建过程一一对应,在这里就不详细叙述了,请看下图。

关于sysfs中的其他子目录的创建和撤销,大家也可以很容易的在Linux内核中找到对应的代码,本文不再一一赘述。

作者:wwang 
出处:http://www.cnblogs.com/wwang 
本文采用知识共享署名-非商业性使用-相同方式共享 2.5 中国大陆许可协议进行许可,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。

--------懒人评论(请勿重复点击)--------

Linux设备模型 (4)的更多相关文章

  1. linux设备模型_转

    建议原博文查看,效果更佳. 转自:http://www.cnblogs.com/wwang/category/269350.html Linux设备模型 (1) 随着计算机的周边外设越来越丰富,设备管 ...

  2. Linux设备模型(9)_device resource management ---devm申请空间【转】

    转自:http://www.wowotech.net/linux_kenrel/device_resource_management.html . 前言 蜗蜗建议,每一个Linux驱动工程师,都能瞄一 ...

  3. Linux设备模型(总线、设备、驱动程序和类)

    Linux设备驱动程序学习(13) -Linux设备模型(总线.设备.驱动程序和类)[转] 文章的例子和实验使用<LDD3>所配的lddbus模块(稍作修改). 提示:在学习这部分内容是一 ...

  4. Linux设备模型 学习总结

    看LDD3中设备模型一章,觉得思维有些混乱.这里从整体的角度来理理思路.本文从四个方面来总结一些内容: 1.底层数据结构:kobject,kset.2.linux设备模型层次关系:bus_type,d ...

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

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

  6. Linux 设备模型浅析之 uevent 篇(2)

    Linux 设备模型浅析之 uevent 篇 本文属本人原创,欢迎转载,转载请注明出处.由于个人的见识和能力有限,不可能面 面俱到,也可能存在谬误,敬请网友指出,本人的邮箱是 yzq.seen@gma ...

  7. linux设备模型:扩展篇

    Linux设备模型组件:总线  一.定义:总线是不同IC器件之间相互通讯的通道;在计算机中,一个总线就是处理器与一个或多个不同外设之间的通讯通道;为了设备模型的目的,所有的设备都通过总线相互连接,甚至 ...

  8. Linux设备模型:基础篇

    linux提供了新的设备模型:总线(bus).设备(device).驱动(driver).其中总线是处理器与设备之间通道,在设备模型中,所有的设备都通过总线相连:设备是对于一个设备的详细信息描述,驱动 ...

  9. Linux 设备模型之 (kobject、kset 和 Subsystem)(二)

    问题描写叙述:前文我们知道了/sys是包括内核和驱动的实施信息的,用户能够通过 /sys 这个接口.用户通过这个接口能够一览内核设备的全貌.本文将从Linux内核的角度来看一看这个设备模型是怎样构建的 ...

  10. Linux设备模型(总结)

    转:http://www.360doc.com/content/11/1219/16/1299815_173418267.shtml 看了一段时间的驱动编程,从LDD3的hello wrod到后来的字 ...

随机推荐

  1. LA 3890 半平面交

    二分查询答案,判断每一个新形成的向量合在一块能否形成半平面交 #include <iostream> #include <cstdio> #include <cstrin ...

  2. Codeforces225E - Unsolvable

    Portal Description 求所有对于方程\[z=\left \lfloor \frac{x}{2} \right \rfloor+y+xy\]不存在正整数解\((x,y)\)的\(z\)中 ...

  3. msp430项目编程21

    msp430中项目---直流电机控制系统 1.定时器工作原理 2.电路原理说明 3.代码(显示部分) 4.代码(功能实现) 5.项目总结 msp430项目编程 msp430入门学习

  4. spring boot + redis 实现session共享

    这次带来的是spring boot + redis 实现session共享的教程. 在spring boot的文档中,告诉我们添加@EnableRedisHttpSession来开启spring se ...

  5. Promise编程规范

    参考: http://www.cnblogs.com/dojo-lzz/p/4340897.html 闲话promise机制  http://www.cnblogs.com/lvdabao/p/es6 ...

  6. JVM原理及内存溢出

    JVM原理及内存溢出

  7. VS2015 android 设计器不能可视化问题解决。

    近期安装了VS2015,体验了一下android 的开发,按模板创建执行了个,试下效果非常不错.也能够可视化设计.但昨天再次打开或创建一个android程序后,设计界面直接不能显示,显示错误:(可能是 ...

  8. 自己定义Gradle插件之&quot;Hello World&quot;

    自己定义Gradle插件之"Hello World" 0.新建一个用于开发这个插件的目录 1.确定Plugin id Plugin id一般定义为java 包名. 由字母和数字及& ...

  9. 深度学习笔记之目标检测算法系列(包括RCNN、Fast RCNN、Faster RCNN和SSD)

    不多说,直接上干货! 本文一系列目标检测算法:RCNN, Fast RCNN, Faster RCNN代表当下目标检测的前沿水平,在github都给出了基于Caffe的源码. •   RCNN RCN ...

  10. Flask采用Virtualenv+Supervisor+Nginx部署应用

    Flask采用Virtualenv+Supervisor+Nginx部署应用 -- 首先是概念解释 WSGI服务器,负责我们的app与服务器的交互,常用的有Gunicorn Web服务器,是个HTTP ...