IO Processing

2023-05-16

Types of IO

IRP Buffer Management

首先区分一下page的内存与nonpaged的内存,内存如果用页管理,就难免面对被swap out的命运;但是如果用nonpaged管理,就会一直存在在物理内存中。

一般来说,内核以及驱动承担繁重的工作,因此常用nonpaged内存,以保证效率。

 

当application或者driver通过调用下列API/函数创建一个IRP请求数据包时,

  1. ReadFile/NtReadFile
  2. WriteFile/NtWriteFile
  3. DeviceIoControl/NtDeviceIoControl

IO manager会根据情况选用不同的buffer管理机制:

  • Buffered IO

由IO manager直接在nonpaged pool中分配内存,分配的buffer供driver使用,并且在适当的时机,将这块内存与用户态应用程序指定的内存进行同步。

  • Direct IO

将用户态应用程序传递进来的内存进行转化,由paged转化为nonpaged,转化的过程又称作lock。

转化之后的内存通过MDL(Memory Description List)进行维护,MDL描述的是物理内存。

如果driver不需要访问这段物理内存中的内容,比如DMA驱动,它不需要CPU的参与便可以在物理内存与IO设备之间进行传输数据,那么直接使用MDL就可以了;

但是如果driver需要访问这段物理内存中的内容,可以将物理内存map到system address space中的某段上,再进行访问。

  • Neither IO

即不同于以上两种方式的其他类型,就是不需要IO Manager的参与,由driver自己来管理缓存

基本上意味着驱动直接访问用户态内存,这种情况下必须保证是访问用户态的缓存的驱动是同步驱动代码或者APC例程,即当前正在执行的线程就是请求IO操作的线程,可以访问该线程的页表描述的用户态地址空间,而不是ISR/DPC等异步例程。

 

具体选用什么类型的Buffer management方式,由driver在初始化时,指定在创建的device object对象里。

对于DeviceIoControl来说,buffer management的方式由相应的参数决定。

 

对于buffer management方式的选择,有以下规律:

1. 如果申请的是小于一页内存(4KB),选用Buffered IO,因为这时在用户态与内核态进行拷贝的代价还不是很大。

2. 如果申请的是大于一页内存,选用Direct IO。

一页内存可以看作是Buffered IO在用户态与内核态之间拷贝内存,与Direct IO锁定一块内存的开销的平衡点(trade-off)。

3. 文件系统驱动一般会使用Neither IO,因为该驱动只要保证对应用户态程序的进程被切换执行时,它将文件系统中的文件内容拷贝到用户态程序指定的内存中去就好了,因为这时的页表对于驱动来说是有效的(因为已经任务切换到该driver代表的用户态进程了);

4. 但是大多数的驱动不能使用Neither IO,比如driver如果需要在ISR/DPC routine中传递数据时,就没有办法保证当前状态下的页表对应的是正确的用户态应用程序。

 

当driver使用Neither IO(即意味着直接访问用户态内存)时,需要格外注意:

1. 用户态的地址是否valid,即是否已经映射,而不是内存区域间的间隙或者空洞,可以通过try/catch来捕获segmentation fault/access denied等待内存相关的异常;

2. 用户态的应用程序传递进来的地址是否包含内核空间地址,如果是的话,就可以从一个设备(比如文件、网络)中inject数据、代码到内核地址空间,这是非常危险的行为;driver可以使用ProbeForRead/ProbeForWrite来测试用户态应用程序传递进来的内存地址是否是单纯的用户态内存区域。

3. 用户态传递进来的内存是否可能被用户态应用程序作为其他用途,因此最好由内核态的缓存来捕获IO设备的输入;

 


 

IO Request to Single-Layered Driver

ISR DPC APC

  • ISR: Interrupt Servicing Rountine
  • DPC: Defered Procedure Call
  • APC: Asynchronous Procedure Call

驱动与IO设备交互的方式可以分为两种:同步和异步

同步很简单,直接调用HAL提供的API就可以向IO设备下达各种操作命令,或者读取IO设备的状态信息;

但是很多时候,驱动无法预知IO设备会何时发出请求或者完成IO操作,因此只有依赖于“中断机制”来通知驱动。

 

可以认为driver中正常的函数调用是同步的,而driver注册的ISR例程,以及ISR又注册的DPC例程,以及APC例程都是异步的。

异步的意思,就是无法确定它们的执行与driver中同步执行的一条指令之间的先后顺序。

 

中断服务

首先,驱动需要在IDT(Interrupt Dispatch Table)中注册相应的ISR例程;

当中断发生时,ISR被调用,ISR运行在相应的中断对应的特权级别,这是高于普通情况的特权级别,在ISR中通常需要尽可能地少做停留,只要获取到IO设备的状态,就应该退出ISR,剩余的操作由一个DPC例程来完成,DPC例程被queue到IO Manager中,当其他高于DPC特权级别的任务(ISR任务)都被完成了,IO Manager就会逐个处理DPC例程。

 

ISR与DPC例程在执行时,都与当前正在执行的线程Context没有关系,也就是说,它们不与具体的线程相关联,因此它们无法访问用户态地址空间;

 

Complete IO Request

当驱动完成了IRP的请求后,它需要调用IoCompleteRequest函数通知IO Manager,IO Manager需要把本次IRP的结果返回给用户态的应用程序。但是在异步操作中,此时正在执行的用户态应用程序很可以不是发起IRP请求的应用程序,那么IO Manager需要一种机制,在下一次用户态的应用程序被调度执行时,通知应用程序完成IO操作,并且将内核态中的结果拷贝回用户态内存地址空间中。

这种机制叫做APC。

APC可以分为用户态与内核态两种,都与具体的线程Context相关联。APC的运行级别低于DPC,但是高于正常的代码执行级别。

 

Synchronization

当driver中的同步代码与ISR/DPC/APC中异步代码同时访问一些全局数据时,需要在二者之间进行同步协调操作,以免使全局数据发生不一致现象。

driver可以调用KeSynchronizeExecution,该函数会在driver同步代码访问全局数据时,阻止ISR等异步例程被执行。

 

除此之外,在多核系统中,driver同步代码也可能在多个processor上运行,因此只要driver访问到全局数据时,就需要使用SpinLock,以防止全局数据发生不一致现象。

IO Request to Layered Drivers

多层驱动模型与单层驱动模型在本质上是一样的,唯一的区别在于,需要多层的驱动之间需要互动和通信,那么它们之间通信的媒介也还是IRP,区别在于IRP是复用驱动收到的IRP,还是新生成一个新的IRP。

 

对于新生成的IRP,那么与单层驱动模型就更加相似了,就是一个过程重复了几次而已;

而对于复用IRP,这里关键的是复用机制。

 

复用IRP

IRP在创建的时候,可以有几种方法,或者说可以创建不同大小的IRP,IRP由定长的header和不定长的几个stack locations组成,但是对于一个具体的IRP来说,在header中会保存整个IRP的长度。

简单来说,每个stack location是为一层driver而保留的,因为虽然是同一个IRP,但是对于不同的driver,IRP中包含的消息是不同的,最显而易见的是MAJOR_CODE就不可能一样,举例来说,读文件操作的IRP,在文件系统驱动这一层,是读取几个的cluster操作,而在磁盘驱动这一层,就是读取几个sector的操作,也就是说在应用程序看来相同的IO操作,分解到不同层次的驱动上,就是完成不同的操作。

IO Cancellatio

IO Completion Ports

IO Priority

转载于:https://www.cnblogs.com/long123king/p/3778140.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

IO Processing 的相关文章

  • RLException: while processing /home/yzxie/桌面/Autobot_ws/src/it_move_config/launch/move_group.launch:

    RLException while processing home yzxie 桌面 Autobot ws src it move config launch move group launch while processing home
  • 讲讲如何写论文和发论文(通信类)

    发信人 AWESOME Slavery in Town 信区 GoAbroad 标 题 讲讲如何写论文和发论文 发信站 北邮人论坛 Sun Feb 15 21 22 15 2009 站内 有几个同学发站内信问我如何在本科和硕士期间写论文 发
  • Processing如何打包导出中文字体

    Processing如何打包导出中文字体 文章目录 Processing如何打包导出中文字体 原理 步骤 用途 原理 使用Processing自带的字体创建工具 创建 vlw字体 该工具为每个character创建一个贴图 然后将它们作为
  • 将数组传递给构造函数而不声明它?

    在处理中 我定义了以下类 class SomeClass SomeClass int someArray println someArray 现在我想创建该类的实例 但在将数组传递给构造函数时遇到问题 SomeClass myVar new
  • 将屏幕坐标转换为模型坐标

    我有一些新手问题 在我的应用程序 processingjs 中 我使用scale 和translate 来允许用户缩放和滚动场景 只要我将比例设置为 1 0 就没有问题 但每当我使用比例 即比例 0 5 时 我都会迷失 我需要将 mouse
  • 处理中的新窗口

    昨天我发现以下代码用于在处理中创建第二个窗口 import javax swing JFrame PFrame f secondApplet s void setup size 600 340 void draw background 25
  • 如何使用更少的 import 语句导入 Java 中的多个类? [复制]

    这个问题在这里已经有答案了 我对在 Java 中使用包还很陌生 我想知道是否有一种更简单的方法来使用更少的 import 语句导入类 我正在使用处理并且我已经开始使用用于处理的 Box2D创建一些游戏 为了使用该库 我必须将以下内容添加到我
  • 处理塔防游戏 - 塔攻击敌人

    我会保持简短 我正在制作一个塔防游戏作为一个迷你项目 同时我有一些空闲时间 我正在尝试弄清楚如何实现塔 以便能够在敌人进入射程时使用 dist 射击敌人但我只是不知道如何实现使用敌人位置和塔位置的方法 我有一个 CreepSprites 和
  • Java数学表达式解析器可以将复数作为变量?

    我正在写一个程序加工转换复数 但是 我想要一种获取输入字符串并使用复杂变量计算转换的方法 例如 1 z 1 z 2 z 2 其中 z 是复数 现在 我看了 JEP 和一些examples 但我无法确定它是否允许您实际输入 z 作为变量 并且
  • 如何在处理开发环境(PDE)中进行调试,还有支持智能感知的插件吗

    我是处理开发环境的新手 我做了功课 我发现的只是将处理库导入Java IDE eclipse 并使用调试 我想知道是否有一个PDE插件可以帮助进行智能感知和调试 就像小草图偏微分方程非常方便 调试 自推出以来处理3 调试现在是Process
  • 计算椭圆尺寸与距中心点距离的关系

    我想在每次崩溃时实现尺寸的缓慢消失 换句话说 当圆最大时 椭圆的尺寸也最大 反之 收缩时则相反 到目前为止 我试图通过从中心点的距离重新映射 cSize 来实现这种影响 但在此过程中的某个地方出了问题 目前 我的椭圆尺寸正在从小到大的缓慢过
  • 每个字母表的排列最多 29 个字符?

    我正在尝试编写一个程序 该程序将生成一个文本文件 其中包含从一个字符到二十九个字符的每种可能的字母表排列 我选择了29作为大家都知道的最长的英文单词 它是antidistitutionalarianism 长度为28个字符 还有一些较长的
  • 越野车弹跳球

    我在处理中制作碰撞球草图时 遇到了一个奇怪的错误 尽管有从墙上弹起的条件 有些球粘在上面 我在这里找不到错误的根源 有人可以帮忙吗 我还意识到可能很少 很多 糟糕的编码实践 但我事先道歉 我在下面发布代码 1 主要 https pasteb
  • 如何在Processing中创建3D平台游戏,包括玩家移动、熔岩和移动块障碍物?

    这非常重要请帮忙 我想在这段代码中添加以下功能 我创建的玩家可以停留在我创建的阶段的顶部 并且无法通过它 如果玩家触及熔岩 游戏就会停止并写上 你输了 如果玩家来到我按下熔岩时创建的终端平台 你赢了 写下来 让我创建的阶段在 y 轴上上下移
  • 处理 float() 函数

    首先 是这个功能 https processing org reference floatconvert html特殊处理还是默认存在于java中 当我在处理下面的行时编码时 println float 88 t float 88 n t
  • Android - 处理构建未编译

    我在 IDE 处理方面遇到问题 我正在尝试将一些东西编译到Android 上 当然 我使用的是 Android 模式 但我在编译时收到此错误 这不是代码本身 我已经安装了 adb devices 看起来没问题 我已经完成了所有 51 and
  • 改变正方形相交区域的颜色

    这些天我正在做一个项目 我的目标是改变两个正方形相交区域的颜色 我已经编写了检测两个正方形相交的代码 但我不知道如何更改相交区域的颜色 请帮我解决这个问题 var sketch function p with p let squares l
  • 使用处理的二次曲线上的点 (p5.js)

    我使用这个公式来计算二次曲线上的点 cPx2 1 t 1 t x1 2 1 t t qcX t t x2 cPy2 1 t 1 t y1 2 1 t t qcY t t y2 当我设置 t 10 并迭代曲线时 我得到 看起来它不仅获得了曲线
  • 如何使用 Java 访问 Kinect?

    我目前正在学习计算机视觉课程 对于我的期末项目 我将制作一款与 Kinect 交互的小游戏 现在我想用 Java 制作这个游戏 因为我以前从未真正尝试过制作游戏 而且我对这种语言非常满意 但我似乎找不到一种方法来访问深度数据 我只需要将其打
  • 处理中渲染极地带面体时出现问题

    我最近一直在研究 Zohedrons 和Rob Bell http zomadic com 做出了美丽的 我玩了免费的极地带面体 Sketchup 插件 http zomebuilder com 并考虑使用几何图形加工 http proce

随机推荐

  • Nervos CKB 共识协议 NC-Max:突破 Nakamoto Consensus 吞吐量的极限

    带宽实际上是区块链吞吐量的最大限制 xff0c 在美国旧金山举办的 Scaling Bitcoin Meetup 中 xff0c Nervos amp Cryptape 研究员张韧从 带宽利用率 角度分析了诸多共识协议的效率和可行性 Alg
  • ES6: import和export

    模块化 前端模块化的好处都已经被说烂了 xff0c 归纳为两点 xff1a 避免全局变量污染有效的处理依赖关系 ES2015 xff08 ES6 xff09 终于引入了模块的概念 xff0c 最近学习了下 xff0c 顺便记下笔记 准备工作
  • 6个常见校园网认证客户端故障原因及解决方法

    故障 一 xff1a 本地连接打叉或受限制 xff1b 客户端 提示 无法获取IP信息 可能原因 1 xff0e 网线虚接 2 xff0e 学生端网络 跳线质量太差 3 xff0e 网卡 或网卡驱动程序过久 4 xff0e 交换机的某个端口
  • C语言编程 求两个数的平均值方法(三种方法)

    第一种方法是最常见的 average 61 xff08 a 43 b xff09 2这种方式 xff0c 求两个数的平均值 第二种方法是 当 a lt b 时 averag 61 a 43 b a 2 这里着重介绍的是第三种方法 avera
  • IDEA创建GIT分支并提交到其他分支

    1 xff0c 创建分支 2 xff0c 提交自己的分支 3 xff0c 写代码 xff0c 写完之后切换到你想要提交的分支 xff0c 例子develop 切花分支 xff0c 选择分支 xff0c checkOut 4 下载该分支的更新
  • 【C#学习笔记】写文件

    using System using System IO namespace ConsoleApplication class Program static void Main string args FileStream file 61
  • socket编程——一个简单的例子(转)

    原文地址 xff1a http blog csdn net wind19 article details 6156339 从一个简单的使用TCP例子开始socket编程 xff0c 其基本步骤如下 xff1a server client 4
  • BI 多维数据 处理错误

    哎 响应中的错误和警告 后端数据库访问模块中存在错误 OLE DB 报告列 11 出现了数据类型溢出现象 OLAP 存储引擎中存在错误 处理 Fact Order Sales 分区时出错 xff0c 该分区属于 Analysis 数据库的
  • AutoLISPDCL各种控件

    AutoLISP对话框DCL一共包括23个常用控件和8个固定控件 xff0c 每种控件属于一种类型 xff0c 创建一个DCL对话框窗体就是创建各种控件实例的过程 xff0c 控件是各种属性 事件 方法的集合 按照各种控件的特点 xff0c
  • 完整克隆、链接克隆

    在VMware中安装虚拟主机时 xff0c 若想简便快速的部署多台虚拟主机 xff0c 可先配置一台虚拟主机的一些基础设置 xff0c 然后通过 34 克隆 34 的方式快速部署 而 34 克隆 34 又分为完整克隆和链接克隆 xff1a
  • 急求mapx控件下载!!!

    急求mapx控件下载 Delphi Windows SDK API http www delphi2007 net DelphiMultimedia html delphi 2006121723132453 html 刚刚在网上搜了好久 没
  • 【Android】Mac安装EasyTether导致无法识别设备的问题

    正文 想让手机走PC网络 xff0c 然后抓包 xff0c 于是搜索一番后安装了一个叫EasyTether的软件 还没来得及测试 xff0c 就忙着写代码去了 xff0c 重启MAC以后就发现连不上手机了 xff0c 一开始并没有怀疑是 E
  • C# 操作PDF

    Spire PDF组件概述 Spire PDF是一个专业的PDF组件 xff0c 用于在 NET应用程序中创建 xff0c 编辑 xff0c 处理和阅读PDF文档 支持丰富的PDF文档处理操作 xff0c 如PDF文档合并 拆分 转换 xf
  • 液晶显示器面板型号速查[转贴]

    原文链接 xff1a http itbbs pconline com cn topic jsp tid 61 3132291 生产厂家 显示器型号 61 面板尺寸 面板类型 xff08 面板制造商和面板型号 xff09 例 xff1a 比如
  • Node.js mm131图片批量下载爬虫1.01 增加断点续传功能

    这里的断点续传不是文件下载时的断点续传 xff0c 而是指在爬行页面时有时会遇到各种网络中断而从中断前的页面及其数据继续爬行的过程 xff0c 这个过程和断点续传原理上相似故以此命名 我的具体做法是 xff1a 在下载出现故障或是图片已经全
  • MySQL服务正在启动或停止中,请稍候片刻后再试一次【解决方案】

    相信有些小伙伴在使用数据库的过程中会经常频繁的启动和停止MySQL服务 xff0c 有时候会出现 服务正在启动或停止中 xff0c 请稍候片刻后再试一次 这样的提示 xff0c 如下图所示 于是乎想办法去解决这个问题 xff0c 但是发现连
  • if、else if、else判断语句的几个小例子

    var num 61 parseInt span class hljs string 39 10px 39 span 10 span class hljs keyword if span num gt 10 console log span
  • 微信浏览器点击系统返回,安卓返回会重载页面回到页面顶部,iOS则返回则会保留之前浏览位置的解决方法...

    后续补充 xff1a 页面css设置了height xff1a 100 xff0c 来避免使用fixed定位弹窗引起的部分机型兼容问题 xff0c 因此会在返回的时候回到页面顶部 xff0c 补充解决办法 xff1a 在弹窗出现的时候在设置
  • Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported

    2019独角兽企业重金招聘Python工程师标准 gt gt gt Uncaught DOMException Failed to execute 39 toDataURL 39 on 39 HTMLCanvasElement 39 Tai
  • IO Processing

    Types of IO IRP Buffer Management 首先区分一下page的内存与nonpaged的内存 xff0c 内存如果用页管理 xff0c 就难免面对被swap out的命运 xff1b 但是如果用nonpaged管理