zoukankan      html  css  js  c++  java
  • 《Linux内核设计与分析》第十七章读书笔记

     设备与模块

    关于设备驱动和设备管理,四种内核成分。

    • 设备类型:在所有Unix 系统中为了统一普通设备的操作所采用的分类.
    • 模块: Linux 内核中用于按需加载和卸载目标码的机制.
    • 内核对象:内核数据结构中支持面向对象的简单操作,还支持维护对象之间的父子关系。
    • sysfs :表示系统中设备树的一个文件系统。

    17 .1 设备类型

    在Linux 以及所有Unix 系统中,设备被分为以下三种类型

    • 块设备
    • 字符设备
    • 网络设备
    块设备通常缩写为blkdev,它是可寻址的,寻址以块为单位,块大小随设备不同而不同;
    
    块设备通常支持重定位( seeking )操作,也就是对数据的随机访问。
    
    块设备是通过称为“块设备节点”的特殊文件来访问的,井且通常被挂载为文件系统。
    

      

    字符设备通常缩写为cdev,它是不可寻址的,仅提供数据的流式访问,就是一个个字符,或者一个个字节。
    
    字符设备是通过称为“字符设备节点”的特殊文件来访问的。
    
    与块设备不同,应用程序通过直接访问设备节点与字符设备交互。
    

      

    网络设备最常见的类型:以太网设备(ethemet devices)
    它提供了对网络的访问,
    
    通过-个物理适配器和一种特定的协议(如IP 协议)进行的。
    
    网络设备打破了Unix 的“所有东西都是文件”的设计原则,
    它不是通过设备节点来访问,
    而是通过套接字API 这样的特殊接口来访问。
    

      

    有些设备驱动是虚拟的,仅提供访问内核功能而已.我们称为“伪设备”(pseudo device )
    

      

    17.2 模块

    尽管Linux 是“单块内核”( monolithic )的操作系统
    整个系统内核都运行于一个单独的保护域中,
    但是Linux 内核是模块化组成的,
    它允许内核在运行时动态地向其中插入或从中删除代码。
    这些代码(包括相关的子例程、数据、函数人口和函数出口〉被一并组合在一个单独的二进制镜像中,
    即所谓的可装载内核模块中,或简称为模块。
    
    支持模块的好处是基本内核镜像可以尽可能地小,
    因为可选的功能和驱动程序可以利用模块形式再提供。
    
    模块允许我们方便地删除和重新载入内核代码,也方便了调试工作。
    
    而且当热插拔新设备时,可通过命令载入新的驱动程序。
    

      

     17.2.1 Hello, World

    hel lo_init -初始化函散, 当模块装载时被调用,如果成功装载返回零,否则返回非零值

    hello_exit -退出函数,当模块卸载时披调用 

    module init(hello init);
    module exit(hello exit);
    
    hello_init的函数是模块的入口点,
    它通过module_ init()例程注册到系统中,在内核装载时被调用。
    
    调用module_initO 实际上不是真正的函数调用,而是一个宏调用,它唯一的参数便是模块的初始化函数。
    
    模块的所有初始化函数必须符合下面的形式:
    int my _ init (void) ;
    
    因为init 函数通常不会被外部函数直接调用,所以你不必导出该函数,故它可标记为static
    类型.
    

      

    hello_ exit()函数是模块的出口函数,
    它由module_exit()例程应册到系统.在模块从内存卸载时,内核便会调用hello_exit。
    
    退出函数可能会在返回前负责清理资源,以保证硬件处于一致状态:或者做其他的一些操作。
     
    exit 函数负责对init 函数以及在模块生命周期过程中所做的一切事情进行撤销工作,
    在退出函数返回后, 模块就被卸载了。
    退出函数必须符合以下形式:
    void my_exit (void);
    与init 函数一样,你也可以标记其为static.
    

      

    如果上述文件被静态地编译到内核映像中,那么退出函数将不被包含,而且永远都不会被调
    
    MODULE_LICENSE()宏用于指定模块的版权。
     
    MODULE_AUTHOR()宏和MODULE_DESCRIPTION()宏指定了代码作者
    和模块的简要描述,它们完全是用作信息记录目的。
    

      


    17.2.2 构建模块

    1. 放在内核派代码树中

    当你决定了把你的模块放入内核源代码树中,下一步要清楚你的模块应在内核源代码树中
    处于何处。

    设备驱动程序存放在内核源码树根目录下/drivers 的子目录下,在其内部,设备驱动
    文件被进一步按照类别、类型或特殊驱动程序等更有序地组织起来。

    2. 放在内核代码外

    17.2.3 安装模块

    编译后的模块将被装入到目录/li~/modules/version/kemel/ 下,

    在kernel/ 目录下的每一个目录都对应着内核源码树中的模块位置。

    如果使用的是2 .6.34 内核,而且将你的模块源代码直接
    放在drivers/char/下,那么编译后的钓鱼竿驱动程序的存放路径将是:

    /lib/modules/2.6.34/kemel/drivers/chai/fisbing.ko.

    下面的构建命令用来安装编译的模块到合适的目录下
    make modules install
    通常需要以root 权限运行。


    17.2.4 产生模块依赖性
    Linux 模块之间存在依赖性

    • 若想产生内核依赖关系的信息, root 用户可运行

            depmod

    • 为了执行更快的更新操作,那么可以只为新模块生成依赖信息,而不是生成所有的依赖关

           系,这时root 用户可运行命令
           depmod -A

      模块依赖关系信息存放在/lib/modules/version/modules.dep 文件中.


    17.2.5 戴入模块

    载入模块最简单的方法是通过insmod 命令,请求内核载入指定的模块。
    
    insmod 程序不执行任何依赖性分析或进一步的错误检查。
    
    以root 身份运行命令:
    insmod module .ko
    这里, module.ko 是要载入的模块名称。
    
    执行命令
    insmod fishing.ko
    
    卸载一个模块,你可使用rmmod 命令,它同样需要以root 身份运行
    rmmod module
    
    先进工具modprobe 提供了模块依赖性分析、错误智能检查、错误报告以及许多其他功能和选项。
    为了在内核via modprobe 中插入模块,需要以root 身份运行
    modprobe module [ module parameters ]
    其中,参数module 指定了需要载入的模块各称,后面的参数将在模块加载时传入内核。
    

      

    modprobe 命令不但会加载指定的模块,而且会自动加载任何它所依赖的有关模块.所以说
    它是加载模块的最佳机制。
    modprobe 命令也可用来从内核中卸载模块,当然这也需要以root 身份运行:
    modprobe -r modules
    参数modules 指定一个或多个需要卸载的模块.与rmmod 命令不同, modprobe 也会装载给
    定模块所依赖的相关模块,但其前提是这些相关模块没有被使用. 
    

      



    17.2.6 管理配置选项


    17.2. 7 模块参数

    17.2.8 导出符号表

    模块被载入后,就会被动态地连接到内核。注意,它与用户空间中的动态链接库类似,只有
    当被显式导出后的外部函数,才可以被动态库调用。在内核中,导出内核函数需要使用特殊的指
    令: EXPORT_ SYMBOL()和EXPORT_SYMBOL_GPL()。
    导出的内核函数可以被模块调用,而来导出的函数模块则无陆被调用。

  • 相关阅读:
    __getitem__ 方法的使用
    python加载测试用例时,修改用例不必须以“test”开头
    python 反射
    python 类中__getattr__的使用
    python 中 __dict__函数的使用
    python 类中__int__和__str__的使用
    ubuntu16.04Nvidia驱动、CUDA、cuDNN安装与卸载
    C++中的各种可调用对象
    ubuntu16.04安装QGIS工具
    C/C++中extern关键字详解
  • 原文地址:https://www.cnblogs.com/zhengwei0712/p/5456305.html
Copyright © 2011-2022 走看看