当前课程知识点:Linux 内核分析与应用 > 第9章 设备驱动 > 9.5 块设备驱动程序简介 > Video
大家好 今天我们来开始讲块设备驱动程序
块驱动程序提供了面向块设备的访问
这种设备以随机访问的方式传输数据
并且数据总是具有固定大小的块
块设备和字符设备的区别是什么呢
块设备上可以通过mount文件系统 而字符设备是不可以的
数据经过块设备相比操作字符设备呢
需要多经历一个数据缓冲层(buffer cache )机制,如图所示
这里我们给出块(驱动)设备模型
那么如图呢是Linux中的块设备模型示意图
应用层程序有两种方式访问一个块设备
一种是通过/dev目录 一种是文件系统挂载点
前者和字符设备一样 通常用于配置
后者就是我们mount之后通过文件系统直接访问一个块设备
比如说 read()系统调用最终呢
它会调用一个适当的VFS函数read()
接着是sys_read() 然后到vfs_read()
将文件描述符fd呢
和文件内的偏移量offset传递给它
VFS会判断这个系统调用的处理方式
如果访问的内容已经被缓存在缓冲区中
就直接访问 否则呢从磁盘中读取
第三层 为了从物理磁盘中读取呢 内核就
依赖映射层mapping layer层
也就是上图中的磁盘文件系统
确定该文件所在文件系统
块的大小 并根据文件块的大小
计算所请求数据的长度
步从本质上来说呢就是文件
被拆成很多的块
因此呢内核需要确定所请求的数据所在的块
映射层调用一个具体的文件系统的函数
这个层的函数会访问文件的磁盘节点
然后根据逻辑块号
确定所请求的数据在磁盘上的位置
内核利用通用块层
启动IO操作来传达所请求的数据
通常呢一个IO操作只针对
磁盘上一组连续的块
第五步,IO调度程序根据预先定义的
内核策略将待处理的IO
进行重新排列和合并
最后呢块设备驱动程序向磁盘控制器硬件接口
发送适当的指令 进行实际的数据操作
下面我们来说一下I/O调度
I/O调度器的总体目标就是希望让
磁头总能往一个方向移动
移动到底了再往反方向走
这恰恰就是现实生活中的电梯模型
所以IO调度器也被叫做
电梯(elevator)调度,而相应的算法呢
也就被叫做电梯调度算法
我们知道 磁盘的读写是通过机械性的移动磁头来实现的
理论上磁盘设备满足块设备的
随机读写的要求
但是出于节约磁盘 提高效率的考虑呢
我们希望当磁头处于某一个位置的时候
一起将最近需要写在附近的数据都写入
而不是这写一下 那写一下然后再回来
IO调度就是将上层发下来的IO请求的顺序呢
进行重新的排序
以及对多个请求进行合并
这样就可以实现上述的提高效率 节约磁盘的目的
Linux内核中提供了下面的几种电梯调度算法来实现IO调度
第一种调度算法叫做先来先服务算法
它只实现了简单的FIFO
只进行最简单的合并 ,比较适合基于Flash的存储
第二种调度算法叫做预测调度算法
它推迟IO请求 大约能推迟几个微秒
以期待能对他们进行排序 获得更高的效率
第三种调度算法叫最后期限调度算法
试图把每次请求的延迟降到最低
同时也会对BIO重新排序
特别适用于读取较多数据的场合
比如说数据库的场合
最后一种叫公平调度算法
它为系统内所有的任务分配均匀的IO带宽
提供一个公平的工作环境
这种一般用在多媒体环境中
能够保证音视频及时从磁盘中读取数据
是当前内核默认的调度算法
那么如何指定或者改变调度算法呢 有两种方式
一种是内核传参的方式来指定使用的调度算法
一种通过命令来改变内核调度算法
那么下面我们再说一下阿
块和扇区这个概念
前面已经说了 块是文件系统
读写的基本单位
那么一个块的大小是2的n次方个扇区
比如说ext4 文件系统
他的块的缺省是4k
那么块呢是VFS和文件系统传送数据的基本单位
那么扇区呢是磁盘读写的基本单位
扇区是硬盘上最小的操作单位
是文件系统和设备之间传送数据的单位
一般一个扇区的大小是512字节 但是也有特殊的情况
比如说SSD就是4096个字节
那么当一个扇区的大小超过512字节的时候
只需要将多个内核扇区对应一个设备扇区就可以了
下面我们来给出块设备驱动的
几个主要的核心结构
那么第一个呢就是磁盘描述符gendisk
它是对一个物理磁盘或分区的描述
第二个数据结构block_device_operations
它是描述磁盘的操作方法集
与file_operations比较类似
第三个数据结构request_queue
针对一个磁盘对象所有请求的一个队列
是相应磁盘对象的一个域
第四个数据结构request
表示经过IO调度之后针对一个
磁盘的一个"请求"
是request_queue的一个节点
多个request构成了一个request_queue
第五个数据结构bio
它表示应用程序对一个
磁盘原始的访问请求 一个bio由多个bio_vec组成
多个bio经过IO调度和
合并之后就会形成一个request
第六个数据结构bio_vec
它描述的应用层准备读写一个
磁盘时需要使用的内存页的一部分
也就是"段segment"
多个bio_vec和bio_iter就形成了一个bio
那么最后一个数据结构是bvec_iter
用于记录当前
bio_vec被处理的情况
用于遍历bio
前面我们对这些数据结构进行介绍以后呢 那么
怎么样来描述它们之间的关系呢 这里给出了一张图
来描述了这些
核心数据结构之间的关系
比较清晰的表达出了
它们之间是怎样的排列组合
核心数据结构和核心方法更详细的内容在此不进行表述
在网上看到一篇非常详尽的
块设备驱动程序相关知识的介绍
大家可以去看
上面我们所讲的内容大部分来自本篇
因此呢建议大家仔细阅读
并动手实践 块设备编程基本就可以入门了
最后呢 我们对块设备驱动程序给一个小结
从这张图我们可以看出从文件系统呢
一直打通到了驱动程序
那么最上层是VFS 层
VFS是对各种具体文件系统的一种封装
是用户程序访问文件提供的统一的接口
第二层是缓存层
就是当用户发起文件访问请求的时候
首先会到磁盘缓存中
进行文件的查找
看是否被缓存了 如果在缓存中
则直接从缓存中读取
如果数据不在缓存中 则必须要到
具体的文件系统中读取数据
第三层是映射层
映射层分为两部分
首先确定文件系统的块大小 然后
计算所请求的数据包含多少个块
第二步调用具体文件系统的函数
来访问文件的索引结点
确定所请求的数据在磁盘上的地址
第四步骤呢就是通用块层
Linux内核把块设备看做是由若干个扇区组成的数据结构
上层的读写请求在通用块层就被
构造成一个或多个bio结构
第五层就是I/O 调度层
I/O调度层负责采用
某种算法 比如说刚才讲的
电梯调度算法 将I/O操作呢进行排序
最底层就是块设备驱动层
由块设备驱动根据排序好的请求呢
对硬件进行数据访问
最后我们给出参考文献
依然是《Linux 驱动开发》
同时呢 网上有大量详尽的块驱动开发资料
读者可自行查阅这里给大家推荐一篇
那么文中的大多数图片来自google搜索
版权归原作者所有
最后大家带着疑问上路
从虚拟文件系统到硬件
为什么要对块设备进行分层管理
-1.1 Linux操作系统概述
-1.2 Linux内核结构以及内核模块编程
--Video
-1.3 Linux内核源码中的双链表结构
--Video
-1.4 源码分析-内核中的哈希表
--Video
-1.5 动手实践-Linux内核模块的插入和删除
--Video
-第1章 概述--章节测验
-2.1 内存管理之内存寻址
--Video
-2.2 段机制
--Video
-2.3分页机制
--Video
-2.4 动手实践-把虚拟地址转换成物理地址
--Video
-第2章 内存寻址--章节测验
-3.1 进程概述
--Video
-3.2 Linux进程创建
--Video
-3.3 Linux进程调度
--Video
-3.4 动手实践-打印进程描述符task_struct中的字段
--Video
-3.5工程实践-基于内核模块的负载监控
--Video
-第3章 进程管理--章节测验
-4.1 Linux内存管理机制
--Video
-4.2 进程用户空间管理机制
--Video
-4.3 物理内存分配与回收机制(上)
--Video
-4.4 物理内存分配与回收机制(下)
--Video
-4.5 动手实践-Linux内存映射基础(上)
--Video
-4.6 动手实践-Linux内存映射实现(中)
--Video
-4.7 动手实践-Linux内存映射测试(下)
--Video
-4.8 初学者对内存管理的常见疑惑
-第4章 内存管理--章节测验
-5.1 中断机制概述
--Video
-5.2 中断处理机制
--Video
-5.3 中断下半部处理机制
--Video
-5.4 时钟中断机制
--Video
-5.5 动手实践-中断上半部的代码分析及应用
--Video
-5.6 动手实践-中断下半部的代码分析及应用
--Video
-第5章 中断--章节测验
-6.1 Linux中的各种API
--Video
-6.2 系统调用机制
--Video
-6.3 动手实践-添加系统调用(系统调用日志收集系统)
--Video
-第6章 系统调用--章节测验
-7.1 内核同步概述
--Video
-7.2 内核同步机制
--Video
-7.3 动手实践-内核多任务并发实例(上)
--Video
-7.4 动手实践-内核多任务并发实例(下)
--Video
-第7章 内核同步--章节测验
-8.1 虚拟文件系统的引入
--Video
-8.2 虚拟文件系统的主要数据结构
--Video
-8.3 文件系统中的各种缓存
--Video
-8.4 页高速缓存机制以及读写
--Video
-8.5 动手实践-编写一个文件系统(上)
--Video
-8.6 动手实践-编写一个文件系统(中)
--Video
-8.7 动手实践-编写一个文件系统(下)
--Video
-第8章 文件系统--章节测验
-9.1 设备驱动概述
--Video
-9.2 I/O空间管理
--Video
-9.3 设备驱动模型
--Video
-9.4 字符设备驱动程序简介
--Video
-9.5 块设备驱动程序简介
--Video
-9.6 动手实践-编写字符设备驱动程序
--Video
-9.7工程实践-编写块设备驱动的基础(上)
--Video
-9.8 工程实践-块设备驱动程序分析(中)
--Video
-9.9 工程实践-块设备驱动程序实现(下)
--Video
-第9章 设备驱动--章节测验
-致谢与说明
--Video