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. 洛谷P1077 摆花

    题目描述 小明的花店新开张,为了吸引顾客,他想在花店的门口摆上一排花,共m盆.通过调查顾客的喜好,小明列出了顾客最喜欢的n种花,从1到n标号.为了在门口展出更多种花,规定第i种花不能超过ai盆,摆花时 ...

  2. 【HDOJ6318】Swaps and Inversions(树状数组)

    题意: 给定一串数组,其中含有一个逆序对则需要花费x,交换相邻两个数需要花费y,输出最小花费. n<=1e5,-1e9<=a[i]<=1e9 思路: #include<cstd ...

  3. hdu2294:Pendant

    T<=10组数据问K<=30种珠子每种n<=1e9串成1~n长度的序列共有多少种,mod1234567891. 方程没想到.矩阵不会推.很好. f[i][j]--长度i,j种珠子方案 ...

  4. PHP获得真实客户端的真实IP REMOTE_ADDR,HTTP_CLIENT_IP,HTTP_X_FORWARDED_FOR[]转载

    REMOTE_ADDR 是你的客户端跟你的服务器“握手”时候的IP.如果使用了“匿名代理”,REMOTE_ADDR将显示代理服务器的IP. HTTP_CLIENT_IP 是代理服务器发送的HTTP头. ...

  5. OC-runtime 的温习

    -.runtime简介 runtime简称运行时,OC就是运行时机制,也就是运行时的一些机制,其中最主要的是消息机制: 对于C语言,函数的调用在编辑的时候,会决定调用哪个函数: 对于OC的函数,属于动 ...

  6. POJ 3013 【需要一点点思维...】【乘法分配率】

    题意: (这题明显感觉自己是英语渣) 给n个点从1到n标号,下面一行是每个点的权,另外给出m条边,下面是每条边的信息,两个端点+权值,边是无向边.你的任务是选出一些边,使这个图变成一棵树.这棵树的花费 ...

  7. 附加数据库时,提示“Microsoft SQL Server,错误: 5120”, 解决方案

    错误的提示内容为:

  8. mybatis <!-- useGeneratedKeys="true"把新增加的主键赋值到自己定义的keyProperty(id)中 -->

    <!-- useGeneratedKeys="true"把新增加的主键赋值到自己定义的keyProperty(id)中 -->

  9. Meteor软件包管理

    Meteor 提供数千种开发应用程序,您可以使用社区包. 添加软件包 您可以查看Meteor官方包服务器: 点击这里. 只搜索你需要的包,并在命令提示符窗口中添加它. 例如,想使用 http 包添加到 ...

  10. c++之虚基类初始化

    C++虚基类构造函数下面文章详细介绍C++虚基,所谓C++虚基类:是由最派生类的构造函数通过调用虚基类的构造函数进行初始化的,但前提是要深入理解到底什么是C++虚基类,及他是怎么运行的. 前面讲过,为 ...