块设备驱动程序

块设备驱动程序负责实现对块设备数据的读写功能。内核代码统一使用缓冲块间接和块设备(如磁盘)交换数据,缓冲区数据通过块设备驱动程序和块设备交换数据。

块设备的管理

块设备表

内核通过一张块设备表blk_dev[]管理各种块设备,每个表项对应一个块设备,并为每一个块设备维护一个请求队列。

  • current_request:指向设备请求队列第一个节点,请求队列通过链表实现。
  • request_fn:函数指针,用于处理请求队列里面的读写请求。

设备请求队列

内核为每个块设备维护一个请求队列,请求队列中请求等待被处理,current_request指向设备请求队列。

  • 请求项

用于描述请求操作,包含读写磁盘扇区位置信息、缓冲区地址信息、操作类别(读/写)信息等。

请求项数据结构:

  • 请求项数组

一块连续内存,被分割为请求项大小的块,形成数组,充当内存池的角色。请求队列中的请求项的内存从请求项数组中进行分配,请求操作完成后,请求项会被释放回该内存池中。

  • 请求队列

处理读写设备请求时,从请求项数组中获取一个空闲块,建立请求项,并插入设备请求队列中。

块设备操作方式

在内核与块设备进行数据交换(IO)时,涉及到三个对象之间的交互作用,其中主要需要了解系统和控制器之间的交互过程。

  • 系统(内核):内核可以向控制器发送命令(发出请求)或等待设备控制器发出中断请求(完成请求)。
  • 控制器:完成读写操作后,向系统(CPU)发出中断。
  • 驱动器:受设备控制器控制

写数据过程

  1. 系统向控制器发出写命令后,等待块设备准备好接收数据,期间CPU需要主动查询控制器的状态寄存器判断是否准备好接收数据(忙等待)。
  2. 控制器准备好后,CPU将数据写入控制器的缓存中。(控制器具有一块缓存)
  3. 控制器将缓存中的数据通过驱动器全部写入块设备。
  4. 向CPU发出中断,中断处理程序完成写数据后的处理

读数据过程

  1. 向控制器发出读命令
  2. 控制器读取磁盘数据到其缓存中
  3. 向系统发起中断,中断处理程序从控制器缓存中取走数据

请求队列处理过程

ll_rw_block函数将请求放入块设备请求队列,设备中断处理程序会不断处理请求队列,直到队列为空。

  • 写请求的处理过程
  1. ll_rw_block为写请求建立请求项,并插入设备的请求队列。若插入前队列为空,则调用请求项操作函数(request_fn)处理当前写请求,对块设备进行写操作。

  2. 设备块设备完成一个写请求后,向CPU发出中断信号,CPU运行中断处理函数。

  3. 中断处理程序判断是否还有数据要写(一个请求会可能写多个扇区),如果有则继续写,然后等待下一次中断,这一过程重复直到该写请求数据全部写入设备。

  4. 完成数据写之后,中断处理程序将唤醒一些等待进程

    • 唤醒等待该请求项有关数据的相关进程
    • 唤醒等待请求项的进程(当内存池没有空闲请求项时,将导致某些请求读写的进程睡眠)
    • 释放当前请求项并从链表中删除该请求项以及释放锁定的相关缓冲区。
  5. 唤醒等待进程后,中断处理程序将调用请求项操作函数处理下一个读/写请求

  • 读请求处理过程

与写请求处理过程类似

  • ll_rw_block与中断处理程序

ll_rw_block,负责将读写请求放入队列中,并启动对请求队列的处理。

中断处理程序,设备完成读写操作后,发出中断,不断处理请求队列中的请求操作,直到请求队列为空。

相关知识

  • I/O调度算法,读写请求不是按访问顺序放入请求队列的,0.11内核使用电梯算法调度读写请求

总结

  • 每个块设备具有一个请求队列,对块设备的读写请求被插入到队列中。
  • 中断处理程序不断处理请求队列中的请求,直到队列为空。完成某个请求后,会唤醒一些等待的进程。

Linux 0.11源码阅读笔记-块设备驱动程序的更多相关文章

  1. Linux 0.11源码阅读笔记-文件管理

    Linux 0.11源码阅读笔记-文件管理 文件系统 生磁盘 未安装文件系统的磁盘称之为生磁盘,生磁盘也可以作为文件读写,linux中一切皆文件. 磁盘分区 生磁盘可以被分区,分区中可以安装文件系统, ...

  2. Linux 0.11源码阅读笔记-中断过程

    Linux 0.11源码阅读笔记-中断过程 是什么中断 中断发生时,计算机会停止当前运行的程序,转而执行中断处理程序,然后再返回原被中断的程序继续运行.中断包括硬件中断和软件中断,硬中断是由外设自动产 ...

  3. Linux 0.11源码阅读笔记-总览

    Linux 0.11源码阅读笔记-总览 阅读源码的目的 加深对Linux操作系统的了解,了解Linux操作系统基本架构,熟悉进程管理.内存管理等主要模块知识. 通过阅读教复杂的代码,锻炼自己复杂项目代 ...

  4. Linux 0.11源码阅读笔记-总结

    总结 Linux 0.11主要包含文件管理和进程管理两个部分.进程管理包括内存管理.进程管理.进程间通信模块.文件管理包含磁盘文件系统,打开文件内存数据.磁盘文件系统包括空闲磁盘块管理,文件数据块的管 ...

  5. Linux 0.11源码阅读笔记-文件IO流程

    文件IO流程 用户进程read.write在高速缓冲块上读写数据,高速缓冲块和块设备交换数据. 什么时机将磁盘块数据读到缓冲块? 什么时机将缓冲块数据刷到磁盘块? 函数调用关系 read/write( ...

  6. Linux 0.11源码阅读笔记-高速缓冲

    高速缓冲 概念 高速缓冲区是内存中的一块内存,在块设备与内核其它程序之间起着一个桥梁作用.内核程序如果需要访问块设备中的数据,都需要经过高速缓冲区来间接的操作. 高速缓冲区结构 高速缓冲区被划分为1k ...

  7. Linux 0.11源码阅读笔记-内存管理

    内存管理 Linux内核使用段页式内存管理方式. 内存池 物理页:物理空闲内存被划分为固定大小(4k)的页 内存池:所有空闲物理页组成内存池,以页为单位进行分配回收.并通过位图记录了每个物理页是否空闲 ...

  8. 【从头到脚品读 Linux 0.11 源码】第一回 最开始的两行代码

    从这一篇开始,您就将跟着我一起进入这操作系统的梦幻之旅! 别担心,每一章的内容会非常的少,而且你也不要抱着很大的负担去学习,只需要像读小说一样,跟着我一章一章读下去就好. 话不多说,直奔主题.当你按下 ...

  9. linux 0.11 源码学习+ IO模型

    http://www.cnblogs.com/Fredric-2013/category/696688.html

随机推荐

  1. Azure DevOps 介绍

    伴随着敏捷的遍地开花,如今各个开发团队越来越希望可以实现敏捷在自己团队内的落地,但是往往单纯的依赖人力难以实现敏捷的各个环节的管理, 大家开始渐渐的意识到,为了按时交付软件产品和服务,开发和运营工作必 ...

  2. 《手把手教你》系列技巧篇(七十一)-java+ selenium自动化测试-自定义类解决元素同步问题(详解教程)

    1.简介 前面宏哥介绍了几种关于时间等待的方法,也提到了,在实际自动化测试脚本开发过程,百分之90的报错是和元素因为时间不同步而发生报错.本文介绍如何新建一个自定义的类库来解决这个元素同步问题.这样, ...

  3. 极速体验|使用 Erda 微服务观测接入 Jaeger Trace

    在大型网站系统设计中,随着分布式架构,特别是微服务架构的流行,我们将系统解耦成更小的单元,通过不断的添加新的.小的模块或者重用已经有的模块来构建复杂的系统.随着模块的不断增多,一次请求可能会涉及到十几 ...

  4. (3)RabbitMQ交换器(Exchange)

    1.前言 上个章节也有简单介绍过RabbitMQ交换器,这里主要了解下它的类型和如何使用.交换器有四种类型,分别是direct.fanout.topic.headers. 2.Virtual host ...

  5. 2022年官网下安装GIT最全版与官网查阅方法

    目录 安装部署Git 1.百度搜索git,双击进入. 2.进入主页,双击如图位置. 3.进入下载列表,双击下载. 4.找到本地文件位置,双击安装,弹出界面,选择next 5.进入安装路径位置,修改路径 ...

  6. tp5 商城商品模型删除

    1:控制器代码 public function delete($id) { //验证id是否正确 $id if (!intval($id)) { return getJsonData(10010, ' ...

  7. Centos7 使用Docker安装rocket.chat聊天工具

    镜像下载.域名解析.时间同步请点击阿里云开源镜像站 下载安装 Rocket.Chat 目前最新的版本为 4.0.1,可以通过手动或者容器的方式安装.这里我推荐使用容器,部署过程会方便不少. 如果要用容 ...

  8. 17调试经验之串口读写flash协议

    一是设计功能 我的理解协议就是一个命令包,通过给出不同的控制命令,来调动不同的功能模块,实现不同的功能,如读数据,写数据,擦除等. 二设计过程 先看了尤老师的视频,主要讲了大致设计原理和总体框架,当然 ...

  9. mac phpStrom 卸载

    cd ~/Library/Logs/cd ~/Library/Application\ Supportcd ~/Library/Preferences/cd ~/Library/Caches/

  10. Java中如何强制类型转换

    例如,当程序中需要将 double 型变量的值赋给一个 int 型变量,该如何实现呢? 显然,这种转换是不会自动进行的!因为 int 型的存储范围比 double 型的小.此时就需要通过强制类型转换来 ...