1. 设备类型

linux中主要由3种类型的设备,分别是:

设备类型

代表设备

特点

访问方式

块设备

硬盘,光盘

随机访问设备中的内容

一般都是把设备挂载为文件系统后再访问

字符设备

键盘,打印机

只能顺序访问(一个一个字符或者一个一个字节)

一般不挂载,直接和设备交互

网络设备

网卡

打破了Unix "所有东西都是文件" 的设计原则

通过套接字API来访问

除了以上3种典型的设备之外,还有"伪设备",即一些虚拟的设备,仅提供访问内核功能而已,没有物理设备与之关联。

2. 内核模块

Linux内核是模块化组成的,内核中的模块可以按需加载,从而保证内核启动时不用加载所有的模块,即减少了内核的大小,也提高了效率。

通过编写内核模块来给内核增加功能或者接口是个很好的方式,既不用重新编译内核,也方便调试和删除。

2.1 内核模块示例

2.1.1. 无参数的内核模块

2.1.2. 带参数的内核模块

构造带参数的内核模块其实也不难,内核中已经提供了简单的框架来给我们声明参数。

1. module_param(name, type, perm) : 定义一个模块参数

+ 参数 name :: 既是用户可见的参数名,也是模块中存放模块参数的变量名

+ 参数 type :: 参数的类型(byte, short, int, uint, long, ulong, charp, bool...) byte型存放在char变量中,bool型存放在int变量中

+ 参数 perm :: 指定模块在 sysfs 文件系统中对应的文件权限(关于 sysfs 的内容后面介绍)

2. module_param_named(name, variable, type, perm) : 定义一个模块参数,并且参数对内对外的名称不一样

+ 参数 name :: 用户可见的参数名

+ 参数 variable :: 模块中存放模块参数的变量名

+ 参数 type和perm :: 同 module_param 中的 type 和 perm

3. module_param_string(name, string, len, perm) : 拷贝字符串到指定的字符数组

+ 参数 name :: 用户可见的参数名

+ 参数 string :: 模块中存放模块参数的变量名

+ 参数 len :: string 参数的缓冲区长度

+ 参数 perm :: 同 module_param 中的 perm

4. module_param_array(name, type, nump, perm) : 定义数组类型的模块参数

+ 参数 name :: 同 module_param 中的 name

+ 参数 type :: 同 module_param 中的 type

+ 参数 nump :: 整型指针,存放数组的长度

+ 参数 perm :: 同 module_param 中的 perm

5. module_param_array_named(name, array, type, nump, perm) : 定义数组类型的模块参数,并且数组参数对内对外的名称不一样

+ 参数 name :: 数组参数对外的名称

+ 参数 array :: 数组参数对内的名称

+ 参数 type,nump,perm :: 同 module_param_array 中的 type,nump,perm

6. 参数描述宏

可以通过 MODULE_PARM_DESC() 来给内核模块的参数添加一些描述信息。

这些描述信息在编译完内核模块后,可以通过 modinfo  命令查看。

2.2 内核模块的位置

2.2.1.  内核代码外

2.2.2. 内核代码中

内核模块的代码也可以直接放到内核代码树中。

编写驱动的时候就可以将完成此驱动功能的内核模块加到内核代码树中 driver 的相应位置。

之后,在编译内核的时候会将新的驱动以内核模块的方式编译出来。

2.3 内核模块相关操作

2.3.1. 模块安装

make modules_install  <-- 把随内核编译出来的模块安装到合适的目录中

2.3.2. 模块依赖性

linux中自动生产模块依赖性的命令:

depmod     <-- 产生内核依赖关系信息

depmod -A  <-- 只为新模块生成依赖信息(速度更快)

2.3.3. 模块的载入

内核模块实验时已经用过:

insmod module.ko

<-- 推荐使用以下的命令, 自动加载依赖的模块

modprobe module [module parameters]

2.3.4. 模块的卸载

内核模块实验时已经用过:

rmmod module.ko

<-- 推荐使用以下的命令, 自动卸载依赖的模块

modprobe -r module

2.3.5. 模块导出符号表

内核模块被载入后,就动态的加载到内核中,为了能让其他内核模块使用其功能,需要将其中函数导出。

内核模块中导出函数的方法:

EXPORT_SYMBOL(函数名)       <-- 接在要导出的函数后面即可

EXPORT_SYMBOL_GPL(函数名)   <-- 和EXPORT_SYMBOL一样,区别在于只对标记为GPL协议的模块可见

3. 内核对象

2.6内核中增加了一个引人注目的新特性--统一设备模型(device model)。

统一设备模型的最初动机是为了实现智能的电源管理,linux 内核为了实现智能电源管理,需要建立表示系统中所有设备拓扑关系的树结构,

这样在关闭电源时,可以从树的节点开始关闭。

实现了统一设备模型之后,还给内核带来了如下的好处:

1. 代码重复最小化(统一处理的东西多了)

2. 可以列举系统中所有设备,观察它们的状态,并查看它们连接的总线

3. 可以将系统中的全部设备以树的形式完整,有效的展示出来--包括所有总线和内部连接

4. 可以将设备和其对应的驱动联系起来,反之亦然

5. 可以将设备按照类型加以归类,无需理解物理设备的拓扑结构

6. 可以沿设备树的叶子向其根的反向依次遍历,以保证能以正确的顺序关闭设备电源

3.1 kobject 简介

统一设备模型的核心部分就是 kobject,通过下面对kobject结构体的介绍,可以大致了解它是如何使得各个物理设备能够以树结构的形式组织起来的。

3.1.1. kobject

kobject 本身不代表什么实际的内容,一般都是嵌在其他数据结构中来发挥作用。嵌入了kobject之后,cdev设备之间就有了树结构关系,cdev设备和其他设备之间也有可层次关系。

3.1.2. ktype

ktype是为了描述一族的kobject所具有的普遍属性,也就是将这一族的kobject的属性统一定义一下,避免每个kobject分别定义。

3.1.3. kset

kset是kobject对象的集合体,可以所有相关的kobject置于一个kset之中,比如所有“块设备”可以放在一个表示块设备的kset中。

3.1.4. kobject,ktype和kset之间的关系

这3个概念中,kobject是最基本的。kset和ktype是为了将kobject进行分类,以便将共通的处理集中处理,从而减少代码量,也增加维护性。

这里kset和ktype都是为了将kobject进行分类,为什么会有2中分类呢?

从整个内核的代码来看,其实kset的数量是多于ktype的数量的,同一种ktype的kobject可以位于不同的kset中。

做个不是很恰当的比喻,如果把kobject比作一个人的话,kset相当于一个一个国家,ktype则相当于人种(比如黄种人,白种人等等)。

人种的类型只有少数几个,但是国家确有很多,人种的目的是描述一群人的共通属性,而国家的目地则是为了管理一群人。

同样,ktype侧重于描述,kset侧重于管理。

3.1.5. kref

kref记录kobject被引用的次数,当引用计数降到0的时候,则执行release函数释放相关资源。

4. sysfs

sysfs是一个处于内存中的虚拟文件系统,它提供了kobject对象层次结构的视图。

可以用下面这个命令来查看 /sys 的结构

tree /sys       # 显示所有目录和文件

或者

tree -L 1 /sys  # 只显示一层目录

Linux内核设计与实现 第十七章的更多相关文章

  1. linux及安全《Linux内核设计与实现》第一章——20135227黄晓妍

    <linux内核设计与实现>第一章 第一章Linux内核简介: 1.3操作系统和内核简介 操作系统:系统包含了操作系统和所有运行在它之上的应用程序.操作系统是指整个在系统中负责完成最基本功 ...

  2. 《linux内核设计与实现》第一章

    第一章Linux内核简介 一.unix 1.Unix的历史 Unix是现存操作系统中最强大和最优秀的系统. ——1969年由Ken Thompson和Dernis Ritchie的灵感点亮的产物. — ...

  3. linux及安全《Linux内核设计与实现》第二章——20135227黄晓妍

    第二章:从内核出发 2.1获取源代码 2.1.1使用git Git:内核开发者们用来管理Linux内核源代码的控制系统. 我们使用git来下载和管理Linux源代码. 2.1.2安装内核源代码(如果使 ...

  4. Linux内核设计与实现 第三章

    1. 进程和线程 进程和线程是程序运行时状态,是动态变化的,进程和线程的管理操作都是由内核来实现的. Linux中的进程于Windows相比是很轻量级的,而且不严格区分进程和线程,线程不过是一种特殊的 ...

  5. Linux内核设计与实现 第五章

    1. 什么是系统调用 系统调用就是用户程序和硬件设备之间的桥梁. 用户程序在需要的时候,通过系统调用来使用硬件设备. 系统调用的存在意义: 1)用户程序通过系统调用来使用硬件,而不用关心具体的硬件设备 ...

  6. 《linux内核设计与实现》第二章

    第二章 从内核出发 一.获取内核源码 1.使用Git(linux创造的系统) 使用git来获取最新提交到linux版本树的一个副本: $ git clone git://git.kernel.org/ ...

  7. Linux内核设计与实现 第四章

    1. 什么是调度 现在的操作系统都是多任务的,为了能让更多的任务能同时在系统上更好的运行,需要一个管理程序来管理计算机上同时运行的各个任务(也就是进程). 这个管理程序就是调度程序,功能: 决定哪些进 ...

  8. 【读书笔记】Linux内核设计与实现(第一章&第二章)

    http://pan.baidu.com/s/1hqYAZNQ OneNote做的笔记没法儿带着格式一起导进来.所以上传到百度云,麻烦老师下载一下了. 下次不再用OneNote.

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

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

随机推荐

  1. Linux远程访问及控制(SSH)

    1.ssh协议:用于远程登录,端口号:22/tcp 配置文件: 1)服务器端口:/etc/ssh/sshd_config 2)客户端 :/etc/ssh/ssh_config 2.服务器监听选项: U ...

  2. ccf-20171203 Crontab问题

    这题有如下几个点要注意: 1.最开始输出的开始时间和截止时间,这里是不包含截止时间的. 2.月份和星期的英文表示是大小写任意的,并未规定必须是Sat这种形式. 3.星期天的数字标识是0. 我的思路是, ...

  3. Leviticus

    The head is empty and empty. Just practicing English will not have any effect. The best effect is to ...

  4. JavaScript中数组的增删改查以及应用方式

    数组的增加方法 1.push()方法向数组中末尾添加一个元素,原数组改变 var arr=[1,2,3,4]; var arr1=arr.push(6); console.log(arr);//打印出 ...

  5. golang中数组与切片的区别

    初始化:数组需要指定大小,不指定也会根据初始化的自动推算出大小,不可改变 数组: a := [...],,} a := [],,} 切片: a:= [],,} a := make([]) a := m ...

  6. 免费代理IP地址列表

    代理地址最后验证日期:2017-8-28 纯真 66免费代理网 #推荐 西刺免费代理IP 酷伯伯HTTP代理 快代理 proxy360.cn 站大爷 Free Proxy List 年少#不稳定 全网 ...

  7. 2个Excel表格核对技巧

    技巧1.利用Spreadsheet Camprare一秒钟识别差异数据 如下图所示,我们如何快速比对我们自己做的表格和上司修改后的表格的差异呢?这里首先来介绍一个非常棒的工具:Spreadsheet ...

  8. Servlet的生命周期以及在Spring MVC中调用流程

    接触Web时间比较久,虽然知道Servlet的生命周期但是理解却还是不够,今天刚好debug代码涉及这块就利用余下时间研究了一下. Servlet的生命周期以及处理浏览器请求的过程.Servlet接口 ...

  9. Domain Adaptation (3)论文翻译

    Abstract The recent success of deep neural networks relies on massive amounts of labeled data. For a ...

  10. Spring中实现多数据源事务管理

    文章转自  https://www.2cto.com/kf/201507/424229.html 前言 由于项目中引入了多个数据源,并且需要对多个数据源进行写操作,那么多数据源的事务管理自然成了不可避 ...