qiuzhiyu
发贴 14
注册 2007-2-27
状态 离线
|
同步与IRP
我看到一段《漫谈兼容内核之十二:Windows的APC机制》
开头的一段描述
"原来,文件操作有“同步”和“异步”之分。普通的写文件操作是同步写,启动这种操作的线程在内核进行写文件操作期间被“阻塞(blocked)”而进入“睡眠”,直到设备驱动完成了操作以后才又将该线程“唤醒”而从系统调用返回。"
我参阅过很多资料和书籍都是这么描述的。我觉得有些悖论。悖论的地方我最后再列出
先从IRP开始
先说说我现有的对IRP的粗淡理解,方面大伙知道我是否哪里理解有误。
IRP可以看成一个数据结构。它的功用是作为一个I/0请求包的一个容器与驱动程序相交互,沟通。
那么它生于何处? writefile的调用过程怎么产生一个IRP呢?我们调用该函数与驱动交互的时候
无非设置其相关的一些参数罢了。其中的一个参数决定交互采用的方式为同步或者是异步.
那么我是不是就可以这么猜测,当该函数调用一层一层的调用下去
到达ring0,调用到NtWriteFile。中间慢慢对我们最初提交的参数进行了封装,填充(以IRP这个数据结构为模
型)。这个就是IRP形成的本质?
接着这里我想说下对于驱动程序其派遣函数所在上下文的粗拙的认识。
一般派遣函数可能会处于以下3种环境。
1:调用者线程的上下文
2:系统线程的上下文 创建系统线程来处理IRP \\ 有理解错的请一定指出,
3:任意线程的上下文 这种情况是DPC之类的机制造成的吧. \\ 因为发在论坛上,免得误导人。
现在假设我们写了自己的一个驱动,该驱动仅仅处理了一个IRP_MJ_WRITE的派遣例程。
然后我们又写了一个用户态程序,该程序也仅仅调用WriteFile函数对该设备同步操作(注:这里调用该函数参数设置同步标志)
现在我们回头看看 上面的那段描述。
“普通的写文件操作是同步写,启动这种操作的线程在内核进行写文件操作期间被“阻塞(blocked)”而进入“睡眠” ”
恩 现在我们的假设是符合这段描述的 同步写操作。接着它说我们的线程将会堵塞。(应该是调用了WaitForSingleObject) 。其实我用过windbg 来双机调试 来给这个函数下过断点,没断下来,我也试过直接在KeWaitForSingleObject函数上下断点。也没断下来。 现在得找下这个WaitForSingleObject是在什么地方被调用的。我查了本书《windows驱动开发技术详解》在书中说 应该是在系统服务函数NtWriteFile中被调用的。再调用该函数前,IRP已经在该函数中封装完毕,可以说创建完毕了。我不清楚这个时候IRP该怎么传给派遣例程去处理?通过什么机制? 假如是通过NtWriteFile里对封装好的IRP信息的判断,再去调用到派遣函数的话。
那么好了问题来了。上面的描述中说 线程会被 阻塞(blocked)”而进入“睡眠” 那么就是说先调用WaitForSingleObject 。(这里也有个问题,这里是ring0了,应该是调用KeWaitForSingleObject吧,所以我WINDGB的时候也在这个函数上下断了,可那本windows驱动开发技术书上说调用的这个函数WaitForSingleObject) 那么这个时刻线程就pending休眠了。接着的驱动里的派遣函数如何被调用呢?
这跟我实际调试的到的是不符合的,但是所有资料都是这么描述的。
从上面 派遣函数可能会处于3种环境中看,同步方式的话往往是在主调线程上下文中被执行的。
我实际调试的到这个例子派遣函数也是在主调线程的上下文中被调用...不知道我描述清楚没? 我想我一定有很
大程度上的理解误区。
[ Last edited by qiuzhiyu on 2009-4-29 at 12:57 AM ] |
|