设备与模块

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

  • 设备类型:在所有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()。
导出的内核函数可以被模块调用,而来导出的函数模块则无陆被调用。

《Linux内核设计与分析》第十七章读书笔记的更多相关文章

  1. 《Linux内核设计与实现》第四周读书笔记——第五章

    <Linux内核设计与实现>第四周读书笔记--第五章 20135301张忻 估算学习时间:共1.5小时 读书:1.0 代码:0 作业:0 博客:0.5 实际学习时间:共2.0小时 读书:1 ...

  2. 《Linux内核设计与实现》Chapter 1 读书笔记

    <Linux内核设计与实现>Chapter 1 读书笔记 一.Unix的特点 Unix从Multics中产生,是一个强大.健壮和稳定的操作系统. 特点 1.很简洁 2.在Unix系统中,所 ...

  3. LINUX内核设计与实现第三周读书笔记

    LINUX内核设计与实现第三周读书笔记 第一章 LINUX内核简介 1.1 Unix的历史 1969年的夏天,贝尔实验室的程序员们在一台PDR-7型机上实现了Unix这个全新的操作系统. 1973年, ...

  4. 《Linux内核设计与实现》Chapter 3 读书笔记

    <Linux内核设计与实现>Chapter 3 读书笔记 进程管理是所有操作系统的心脏所在. 一.进程 1.进程就是处于执行期的程序以及它所包含的资源的总称. 2.线程是在进程中活动的对象 ...

  5. 《Linux内核设计与实现》Chapter 2 读书笔记

    <Linux内核设计与实现>Chapter 2 读书笔记 一.获取内核源码 1.使用Git 我们曾经在以前的学习中使用过Git方法 $ git clone git://git.kernel ...

  6. 《Linux内核设计与实现》Chapter 5 读书笔记

    <Linux内核设计与实现>Chapter 5 读书笔记 在现代操作系统中,内核提供了用户进程与内核进行交互的一组接口,这些接口的作用是: 使应用程序受限地访问硬件设备 提供创建新进程与已 ...

  7. 《Linux内核设计与实现》Chapter 18 读书笔记

    <Linux内核设计与实现>Chapter 18 读书笔记 一.准备开始 一个bug 一个藏匿bug的内核版本 知道这个bug最早出现在哪个内核版本中. 相关内核代码的知识和运气 想要成功 ...

  8. Linux内核设计与实现 第十七章

    1. 设备类型 linux中主要由3种类型的设备,分别是: 设备类型 代表设备 特点 访问方式 块设备 硬盘,光盘 随机访问设备中的内容 一般都是把设备挂载为文件系统后再访问 字符设备 键盘,打印机 ...

  9. Linux内核设计与实现第十周读书笔记

    第十七章 设备与模块 关于设备驱动与设备管理,我们讨论四种内核成分. 设备类型 模块 内核对象 sysfs 17.1设备类型 在Linux以及所有Unix系统中,设备被分为以下三种类型: 块设备,块设 ...

  10. Linux内核设计与实现第八周读书笔记

    第四章 进程调度 进程在操作系统看来是程序的运行态表现形式. 4.1多任务 多任务操作系统就是能同时并发地交互执行多个进程的操作系统. 多任务操作系统会使多个进程处于堵塞或者睡眠状态.这些任务尽管位于 ...

随机推荐

  1. 需求规格说明书——阿里八八“好记”APP

    工作流程 ① 组长查阅相关文档.示例文件等,根据本小组项目特点进行定制需求规格说明书目录. ② 根据选题报告工作进行任务分配,追求工作量最小化.效率最大化. ③ 分工编辑文档. ④ 组长搭建Githu ...

  2. one_code=soup.find('a',href=re.compile(r"ill")) NameError: name 're' is not defined

    啊啊啊啊我又来了,真的是万事开头难啊,一个问题刚解决,又来了一个问题..依旧跟着视频教学,说“re"这里按Ctrl+e导入正则表达式,可我弄了半天也没有反应..以至于最后的运行结果就是这样. ...

  3. Ajax进阶

    "POST":请求 POST请求:(一共三个方法)<!DOCTYPE html><html lang="en"><head> ...

  4. python 之 初识面向对象

    编程的两种范式 我们知道,程序 = 特定的语法+数据结构+算法 好像这个和我们熟知的小说有类似之处啊,小说 = 人物+背景+情节 写小说呢,都是有模板的,so,写程序也是一样,我们把这个“模板”叫做编 ...

  5. python五十六课——正则表达式(常用函数之match)

    函数:match(regex,string,[flags=0])参数:regex:就是正则表达式(定义了一套验证规则)string:需要被验证的字符串数据flags:模式/标志位,默认情况下(不定义) ...

  6. [NOI2005]瑰丽华尔兹

    嘟嘟嘟 这题大家应该都做过,就是暴力dp+单调队列优化. dp方程其实很好想,最初是这样的:dp[t][i][j]表示时刻\(t\)后,走到\((i, j)\)格子的最远路程,于是就有: \[dp[t ...

  7. 用PHP的curl实现并发请求远程文件(并发抓取远程网页)

    PHP的curl功能确实强大了.里面有个curl_multi_init功能,就是批量处理任务.可以利用此,实现多进程同步抓取多条记录,优化普通的网页抓取程序. 一个简单的抓取函数: function ...

  8. 【转】玩玩你的Windows防火墙——穿透与防御

    前言:在防火墙专区,我经常看见朋友们讨论,“某某防火墙的性能如何”,亦或是,“某某防火墙的防御能力如何”.实际上,一个防火墙所履行的基本职责便是“网络访问控制”,即放行我们允许的通信,阻止我们未允许的 ...

  9. MATLAB中的FOR循环问题

    做量化操作的时候经常需要使用到matlab编写策略或者计算多因子,for循环非常慢,自己找了一些matlab中for循环的优化方法,for的部分每处理一个大矩阵都要花费大量的时间,这是不可避免需要遇到 ...

  10. ros新建的包找不到

    cannot find the package 这个问题的解决办法一:每次打开命令窗都使用一次 source ~/ros_ws/devel/setup.bash 解决方法二:在住文件夹的图形界面使用快 ...