[Linux 驱动] -- Linux 设备驱动 -- 块设备(一)之概念和框架

基本概念

块设备(Block device)

--- 是一种具有一定结构的随机存取设备,对这种设备的读写是按进行的,他使用缓冲区来存放暂时的数据,待条件成熟后,从缓存一次性写入设备或者从设备一次性读到缓冲区。

字符设备(Character device)

--- 是一个顺序的数据流设备,对这种设备的读写是按字符进行的,而且这些字符是连续地形成一个数据流。他不具备缓冲区,所有对这种设备的读写是实时的

 

扇区(Sectors):任何块设备硬件对数据处理的基本单位。通常,1个社区的大小为512byte。(对设备而言)

块(Blocks):由Linux指定对内核或文件系统等数据处理的基本单元。通常,1个块由1个或多个扇区组成。(对Linux操作系统而言)

段(Segments):由若干相邻的块组成。是Linux内存管理机制总一个内存也或者内存页的一部分。

页、段、块、扇区之间的关系图如下:

 

块设备驱动整体框架

块设备的应用在Linux中是一个完整的子系统。

在Linux中,驱动对块设备的输入或输出(I/O)操作,都会想块设备发出一个请求,在驱动中用 request 结构体描述。但对于一些磁盘设备而言请求的速度很慢,这时候内核就提供一种队列的机制把这些 I/O 请求添加到队列中(即:请求队列),在驱动中用 request_queue 结构体描述。在向块设备提交这些请求前内核会执行请求的合并和排序预操作,以提高访问的效率,然后再由内核中的 I/O 调度程序子系统来负责提交 I/O 请求,调度程序将磁盘资源分配给系统中所有挂起的块 I/O 请求,其工作是管理块设备的请求队列,决定队列中的请求的排列顺序以及什么时候派发请求到设备

由通用块层(Generic Block Layer)负责维持一个 I/O 请求在上层文件系统与底层屋里磁盘之间的关系。在通用块层中,通常用一个bio结构体来对应一个I/O请求

Linux提供了一个 gendisk 数据结构体,用来表示一个独立的磁盘设备或分区,用于对底层物理磁盘进行访问。在 gendisk 中又一个类似字符设备中 file_operations 的硬件操作结构指针,是 block_device_operations结构体

当多个请求提交给块设备时,执行效率依赖与请求的顺序。如果所有的请求是同一个方向(如:写数据),执行效率是最大的。内核在调用块设备驱动程序例程处理请求之前,先收集 I/O 请求并将请求排序,然后,将连续扇区操作的多个请求进行合并以提高执行效率(内核算法会自己做,不用你管),对 I/O 请求排序的算法称为电梯算法(elevator algorithm)。电梯算法在 I/O 调度层完成。内核提供了不同类型的电梯算法,电梯算法有:

  1. noop(实现简单的 FIFO,基本的直接合并与排序)
  2. anticipatory(延迟I/O请求,进行临界区的优化排序)
  3. Deadline(针对anticipatory缺点进行改善,降低延迟时间)
  4. Cfq(均匀分配I/O带宽,公平机制)

PS:其实IO调度层(包括请求合并排序算法)是不需要用户管的,内核已经做好

相关数据结构

block_device:描述一个分区或整个磁盘对内核的一个块设备实例

gendisk:描述一个通用硬盘(generic hard disk)对象。

hd_struct:描述分区应有的分区信息

bio:描述块数据传送时怎样完成填充或读取块给 driver

request:描述向内核请求一个列表准备做队列处理

request_queue:描述内核申请request资源建立请求链表并填写BIO形成队列。

 

 

 

 

 

 

 

 

 

 

 

 

猜你喜欢

转载自blog.csdn.net/u014674293/article/details/104406005