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. [luoguP3606] [USACO17JAN]Building a Tall Barn建谷仓(贪心 + 线段树)

    传送门 把线段都读进来然后排序,先按右端点为第一关键字从小到大排序,后按左端点为第二关键字从小到大排序. 注意不能先按左端点后按右端点排序,否则会出现大包小的情况,如下: —————— ———  — ...

  2. hud 2073

    #include<stdio.h> #include<math.h> int main() { int i,j,k,n,m,t; double a]; a; for;i++) ...

  3. 【收藏】下载Chrome商店插件的方法,万恶的gwd

    以下是下载离线插件包的方法: 第一步: 每个Google Chrome扩展都有一个固定的ID,例如https://chrome.google.com/webstore/detail/bfbmjmiod ...

  4. msp430项目编程04

    msp430中项目---TFT彩屏显示 1.TFT彩屏工作原理 2.电路原理说明 3.代码(静态显示) 4.代码(动态显示) 5.项目总结 msp430项目编程 msp430入门学习

  5. Java 等额本金等额本息工具类

    原文:http://www.open-open.com/code/view/1449034309983 等额本息: /** * Description:等额本息工具类 * Copyright: Cop ...

  6. .NET作品集:基于svn 的.net 持续集成工具

    作品背景 这个.net 持续集成作品还是在2014年的时候从事.net 软件项目开发的时候做的,当时部门还用着vs2008用vb.net做项目(现在也是),项目代码极混乱,版本工具用的vss,而且用的 ...

  7. ECC数据结构

    在SM2 ECC算法中,有针对签名加密的数据结构,下面对这些结构进行分析 #define ECCref_MAX_BITS 512 #define ECCref_MAX_LEN ((ECCref_MAX ...

  8. linux中的线程局部存储(TLS)

    http://blog.csdn.net/cywosp/article/details/26469435

  9. 【python】super()

    转自: http://www.cnblogs.com/lovemo1314/archive/2011/05/03/2035005.html

  10. [转]JAVA对象容器

    要用Java实现记事本的功能.首先列出记事本所需功能: 可以添加记录(字符串): 可以获得记录条数: 可以删除其中某一条记录: 可以获得指定第几条的记录: 可以列出所有的记录. 如果这个记事本是某个大 ...