第17章 设备与模块

四种内核成分

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

17.1 设备类型

Linux系统中,设备被分为以下三种类型

块设备

  • 通常缩写为 blkdev ,它是可寻址的,寻址以块为单位,块大小随设备不同而不同;
  • 支持重定位(seeking )操作,也就是对数据的随机访问 块设备的例子有硬盘、蓝光光牒,还有如 Flash 这样的存储设备;
  • 通过称为“块设备节点”的特殊文件来访问的.

字符设备

  • 字符设备通常缩写为 cdev,它是不可寻址的,仅提供数据的流式访问;
  • 例子有键盘、鼠标、打印机,还有大部分伪设备。
  • 通过称为“字符设备节点”的特殊文件来访问的。
  • 与块设备不同,应用程序通过直接访问设备节点与字符设备交互。

网络设备

  • 网络设备打破了 Unix 的“所有东西都是文件”的设计原则,它不 是通过设备节点来访问,而是通过套接字 API 这样的特殊接口来访问。 其他设备
  • “杂项设备”,是个简化的字符设备。杂项设备使驱动程序开发者能够很容易地表示一个简单设备。
  • “伪设备”的设备驱动是虚拟的,仅提供访问内核功能而 已。最常见的如内核随机数发生器(通过/dev/random和/dev/urandom 访问)、空设备(通过/dev/null 访问)、零设备(通过/dev/zero访问)等。

17.2 模块

17.2.1 Hello,World

1、Linux 内核是模块化组成的,它允许内核在运行时动态地向其中插入或从中删除代码。

  • 这些代码(包括相关的子例程、数据、函数人口和函数出口〉被一并组合在 个单独的二进制镜像中,即所谓的可装载内核模块中,或简称为模块。

2、支持模块的好处:

  • 基本内核镜像可以尽可能地小,因为可选的功能和驱动程序可以利用模块形式再提供。
  • 模块允许我们方便地删除和重新载入内核代码,也方便了调试工作。而且当热插拔新设备时,可通过命令载入新的驱动程序。

3、调用 module_init()实际上不是真正的函数调用,而是一个宏调用,它唯一的参数便是模块的初始化函数。模块的所有初始化函数必须符合下面的形式:

int my _ init (void) ;

17.2.2 构建模块

构建过程的第一步是决定在哪里管理模块源码。 
构建方式:

(1)放在内核派代码树中.

  • 把模块源码加入到内核源代码树中
  • 作为一个补丁或者是最终把你的代码合并到正式的内核代码树中.

(2)放在内核代码外.

17.2.3 安装模块

用来安装编译的模块到合适的目录下

make modules install

通常需要以 root 权限运行。

17.2.4 产生模块依赖性

产生内核依赖关系的信息, root用户可运行命令

depmod

17.2.5 载入模块

1、载入模块最简单的方法是通过 insmod 命令。

insmod module.ko

2、卸载模块使用 rmmod 命令,以 root 身份运:

rmmod module

3、via modprobe中插入模块,需要以 root 身份运行:

modprobe module [ module parameters ]

其中,参数 module 指定了需要载入的模块各称,后面的参数将在模块加载时传入内核。

17.2.6 管理配置选项

Kconfig 文件:

config FISHING_POLE
tristate "Fish Master 3000 support"
default n
help
If you say Y here, support for the Fish Master 3000 wi th computer interface will be compiled into the kernel and accessible via a device node . You can also say M here and the driver will be built as a
module named fishing.ko.
If unsure, say N.
  • 配置选项第一行定义了该选项所代表的配置目标。注意 CONFIG_ 前缀并不需要写上。
  • 第二行声明选项类型为住istate,也就是说可以编译进内核(Y),也可作为模块编译(M),或者干脆不编译它(N)。如果编译选项代表的是一个系统功能,而不是一个模块,那么编译选项将用 bool 指令代替往istate,这说明它不允许被编译成模块。处于指令之后的引号内文字为该选项指定了名称。
  • 第三行指定了该选项的默认选择,这里默认操作是不编译它(则。也可以把默认选择指定为编译进内核飞凹,或者编译成一个模块(M)。对驱动程序而言,默认选择通常为不编译进内核(N)。
  • Help 指令的目的是为该选项提供帮助文档。各种配置工具都可以按要求显示这些帮助。因为这些帮助是面向编译内核的用户和开发者的,所以帮助内容简洁扼要。一般的用户通常不会编译内核,但如果他们想试试,往往也能理解配置帮助的意思。

17.2.7 模块参数

所有宏需要包含<linux/module.h>头文件。

17.2.8 导出符号表

在内核中,导出内核函数需要使用特殊的指令:

EXPORT_ SYMBOL()和 EXPORTSYMBOLGPL()

17.3 设备模型

统一设备模型 :

设备模型提供了一个独立的机制专门来表示设备,并描述其在系统中的拓扑结构,从而使得系统具有以下优点:

  • 代码重复最小化.
  • 提供诸如引用计数这样的统一机制。
  • 可以列举系统中所有的设备,观察它们的状态,并且查看它们连接的总结.
  • 可以将系统中的全部设备结构以树的形式完整、有效地展现出来一一包括所有的总统和内部连接。
  • 可以将设备和其对应的驱动联系起来,反之亦然。
  • 可以将设备按照类型加以归类,比如分类为输入设备,而无需理解物理设备的拓扑结构.
  • 可以沿设备树的叶子向其根的方向依次遍历,以保证能以正确顺序关闭各设备的电源。

17.3.1 kobject

设备模型的核心部分就是 kobject,它自 struct kobject 结构体表示,定义于头文件<linux/kobject.b>中。

17.3.2 ktype

ktype 的存在是为了描述一族kobject 所具有的普遍特性.

17.3.3 kset

kset 是 kobject 对象的集合体。把它看成是一个容器,可将所有相关的 kobject 对象,比如“全部的块设备”置于同一位置。

17.3.4 kobject、ktype和kset的相互关系

kobject,由 struct koject 表示。 kobject 为我们引入了诸如引用计数、父子关系和对象名称等基本对象道具,并且是以一个统一的方式提供这些功能。

17.3.5 管理和操作kobject

使用 kobjcet 的第一步需要先来声明和初始化。 kobject 通过函数ko均ect_init 进行初始化,该函数定义在文件 <linux/kobject.h>中 :

void kobjectinit(struct kobject •kobj, struct kobjtype •ktype);

  • 第一个参数就是需要初始化的 kobject 对象,在调用初始化函数前, kobject 必须清空。
  • 这个工作往往会在 kobject 所在的上层结构体初始化时完成。
  • 如果 kobject 未被清空,那么只需要调用 memset().

17.3.6 引用计数

  • 增加引用计数称为获得对象的引用,减少引用计数称为释放对象的引用。
  • 当引用计数跌到零时,对象便可以被撤销,同时相关内存也都被释放。

17.4 sysfs

  • sysfs文件系统是个处于内存中的虚拟文件系统
  • 它为我们提供了 kobject 对象层次结构的视图。
  • 帮助用户能以一个简单文件系统的方式来观察系统中各种设备的拓扑结构。

17.4.1 sysfs中添加和删除kobject

函数都定义于文件 lib/kobject.c 中,声明于头文件<linux/kobject.b>中。

17.4.2 向sysfs中添加文件

1、 默认属性

  • 默认的文件集合是通过 kobject 和 kset 中的 ktype 字段提供的。因此所有具有相同类型的 kobject 在它们对应的 sysfs 目录下都拥有相同的默认文件集合.

2、创建新属性

  • 在sysfs 中创建一个符号连接:

int sysfscreatelink(struct kobject kobj, struct kobject target, char name);

3、删除新属性 - 删除一个属性需通过函数sysfsremove file() 完成:

void sysfsremovefile (struct kobject kobj, const struct attribute attr);

  • 由sysfs_ creat_ link()创建的符号连接可通过删除:

void sysfsremovelink(struct kobject kobj , char name);

17.4.3 内核事件层

1、内核事件由内核空间传递到用户空间需要经过 netlink. netlink 一个用于传送网络信息的多点传送套接字。

2、在内核代码中向用户空间发送信号使用函数 kobject uevent():

int kobject_uevent(struct kobject *kobj,enum kobject_ action action);

  • 第一个参数指定发送该信号的 koject 对象。实际的内核事件将包含该 koject 映射到 sysfs路径。
  • 第二个参数指定了描述该信号的“动作”或“动词”。

《linux内核设计与实现》读书笔记第十七章的更多相关文章

  1. Linux内核设计与实现 读书笔记 转

    Linux内核设计与实现  读书笔记: http://www.cnblogs.com/wang_yb/tag/linux-kernel/ <深入理解LINUX内存管理> http://bl ...

  2. Linux内核设计与实现 读书笔记

    第三章 进程管理 1. fork系统调用从内核返回两次: 一次返回到子进程,一次返回到父进程 2. task_struct结构是用slab分配器分配的,2.6以前的是放在内核栈的栈底的:所有进程的ta ...

  3. Linux内核设计与实现 总结笔记(第二章)

    一.Linux内核中的一些基本概念 内核空间:内核可独立于普通应用程序,它一般处于系统态,拥有受保护的内存空间和访问硬件设备的所有权限.这种系统态和被保护起来的内存空间,称为内核空间. 进程上下文:当 ...

  4. Linux内核设计与实现读书笔记(8)-内核同步方法【转】

    转自:http://blog.chinaunix.net/uid-10469829-id-2953001.html 1.原子操作可以保证指令以原子的方式执行——执行过程不被打断.内核提供了两组原子操作 ...

  5. Linux内核设计与实现——读书笔记2:进程管理

    1.进程: (1)处于执行期的程序,但不止是代码,还包括各种程序运行时所需的资源,实际上进程是正在执行的 程序的实时结果. (2)程序的本身并不是进程,进程是处于执行期的程序及其相关资源的总称. (3 ...

  6. Linux内核设计与实现——读书笔记1:内核简介

    内核:有的时候被称管理者或者操作系统核心,通常内核负责响应中断的中断服务程序, 负责管理多个进程从而分享处理器时间的调度程序,负责管理进程地址空间德内存管理程序 和网络,进程间通信等系统服务程序共同组 ...

  7. Linux内核设计与实现 总结笔记(第九章)内核同步介绍

    在使用共享内存的应用程序中,程序员必须特别留意保护共享资源,防止共享资源并发访问. 一.临界区和竞争条件 1.1 临界区和竞争条件 所谓临界区就是访问和操作共享数据代码段.多个执行线程并发访问同一个资 ...

  8. 《Linux内核设计与实现》课本第四章自学笔记——20135203齐岳

    <Linux内核设计与实现>课本第四章自学笔记 进程调度 By20135203齐岳 4.1 多任务 多任务操作系统就是能同时并发的交互执行多个进程的操作系统.多任务操作系统使多个进程处于堵 ...

  9. 《Linux内核设计与实现》课本第三章自学笔记——20135203齐岳

    <Linux内核设计与实现>课本第三章自学笔记 进程管理 By20135203齐岳 进程 进程:处于执行期的程序.包括代码段和打开的文件.挂起的信号.内核内部数据.处理器状态一个或多个具有 ...

  10. 《Linux内核设计与实现》课本第五章学习笔记——20135203齐岳

    <Linux内核设计与实现>课本第五章学习笔记 By20135203齐岳 与内核通信 用户空间进程和硬件设备之间通过系统调用来交互,其主要作用有三个. 为用户空间提供了硬件的抽象接口. 保 ...

随机推荐

  1. iOS 获取沙盒路径方法

    //获取家目录路径的函数: NSString *homeDir = NSHomeDirectory(); //获取Documents目录路径的方法: NSArray *paths = NSSearch ...

  2. 使用emIDE创建STM32项目

    emIDE是一个开源的嵌入式集成开发环境,基于Code::Blocks开发,能够支持多个平台和多个厂家的嵌入式硬件,继承了Code::Blocks的有点. 下载emIDE并安装,也可选择绿色版.若需要 ...

  3. AngularJS 事件

    AngularJS 有自己的 HTML 事件指令. ng-click指令: ng-click 指令定义了 AngularJS 点击事件. <!DOCTYPE html> <html& ...

  4. Fiddler响应post的请求 request body里面填写什么?

    若是想传json格式的数据,请求头可以这样写:(应该先勾选 post,然后写上正确滴请求地址)User-Agent: Fiddler Host: localhost:1455 <span sty ...

  5. 以前用SQL实现的机构职能树,再看看

    DECLARE CNT NUMBER; TMP ); vtmp ); ltmp1 ); ltmp2 ); ltmp3 ); ltmp4 ); NTMP NUMBER; CURSOR CSR_TEST ...

  6. [BI项目记]-对项目文件进行规划

    BI项目中会有很多不同种类的项目,此篇会对这些项目进行一个总结,并且在TFS中进行分类. 根据笔者对BI项目的经验和理解,主要将BI项目中的项目类型进行如下分类: DB脚本 DB脚本是BI项目中重要的 ...

  7. [Android]电话拨号器开发

    继续今天的Android,经过昨天大体了解了Android开发的一些基本文件结构,今天来做一个电话拨号器! 预期达到的效果 实现过程 首先还是按照昨天第一篇教程,新建一个项目叫PhoneCall的An ...

  8. File类基础

    File类的作用: Java的io包中定义了File类,用于对文件或文件夹的管理操作. File类只能够用于表示文件或文件夹的信息(属性)和对该文件或文件夹的删除创建操作 (不能对内容进行访问) 通过 ...

  9. devexpress 安装及破解

    安装dx DXperience-10.1.4 破解文件下载

  10. asp.net 数据库面试题(基础)

    今天到某公司笔试,数据库考的比较多,但是说老实话,考的也比较基础.现在趁回忆得起来,将数据库知识简单整理如下: 一.建表指令 比如创建一个学生表student,它由学号Sno,姓名Sname,性别Ss ...