qqwx

导航

13. 块设备驱动程序 2010-02-28 20:14 257人阅读 评论(0) 收藏

        块设备特点:CPU读写时间远小于硬件时间。Linux块设备处理程序很复杂,此处大略介绍软件体系。对磁盘的I/O操作就是在磁盘与RAM单元之间传送相邻扇区内容,最下层是硬盘控制器。磁盘的物理结构对它透明,这只知道磁盘由一个个连续的扇区组成。扇区是每次它读写的单位,一般512字节。读时转换为(扇区号,长度)。最上层是VFS,它确定是否磁盘高速缓存可用,若不可用,则要I/O,这时会由VFS下层的真实文件系统确定数据的“物理位置”(文件系统中)。文件系统以“块”为最小存储单位,一个文件可视为多个块组成。Linux中块的大小为2的幂。是扇区大小的倍数且不能大于一个页框。块是从硬件最终读出的数据的组织形式,它存放在内存的块缓冲区供使用。缓冲区有个“缓冲区首部”buffer_head类型的描述符,它用来找到块缓冲区页框的位置。块设备驱动程序在磁盘控制器上层,它通过DMA传数据。DMA虽然可以通过磁盘控制器传不相邻扇区,但磁头移动慢,效率低,所以一般直接读相邻扇区。老式控制器只支持简单的DMA,它要求与RAM中连续的内存单元传。新的可以与不连续的RAM传,只要将每个区的描述符用链表串起即可,每一连续的区叫段,它由一页或页内一部分组成。设备驱动程序只认扇区与段,相邻段的页框正好连续,那么可以合并成更大的段(在通用块层中完成)。磁盘文件系统下面即为通用块层,此层联系上面的文件系统与下面的相应层,所以它了解扇区、块、段、页,它最重要的功能是对文件系统定位出的I/O要用的块进行I/O。一次I/O请求在文件系统处定位后可能不在相邻块,此时,通用块层针对每个相邻块I/O请求分别启动I/O,每次I/Obio结构的数据结构描述。Bio本身在通用块层启动I/O时由slab分配器分配并初始化。磁盘本身由gendisk对象表示,其中hd_struct提出了其分区。块设备处理的关键是尽可能将可合并的扇区I/O合并在一起,由驱动程序一次完成以减少磁头移动,所以采取人为延迟I/O操作的方法。引入I/O调度程序,通用块层在最后会调用它。通用块层的I/O操作bio按相邻的请求归类,扩展已有请求。请求对应request结构,它以双向链表组织成请求队列request_queueI/O调试程序将通用块层传来的bio或加入链表、或扩展已有的request元素。这个请求队列由通用块层创建、由I/O调试程序管理、被设备驱动程序使用。请求队列默认有128个读写上限,当大于113时,内核为避免拥塞会试图降低请求创建速率。当I/O调度程序往请求链表中加请求时,它会通过扇区将链表排序,这是电梯算法。负载严重时,不好。Linux2.6中提供4种不同的I/O调度程序(电梯算法)。Noop算法不排序直接搞;CFQ算法按进程组织队列,依次调度以求公平;“最后期限”算法本质上是加了超时定时器的电梯;“预期”算法是Linux提供的最后期限算法的演变,较复杂。设备驱动程序最后调用“策略例程”,对I/O调度程序整理过的请求队列逐个服务,服务后的删除。它没有实现为一个专门内核线程,而是做完后就终止,中断时再启用。

版权声明:本文为博主原创文章,未经博主允许不得转载。

posted on 2010-02-28 20:14  qqwx  阅读(136)  评论(0编辑  收藏  举报