⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jiurl键盘驱动 5.htm

📁 JIURL键盘驱动
💻 HTM
📖 第 1 页 / 共 5 页
字号:
      to 0xfe3a0b88<BR>KBDCLASS-KeyboardClassServiceCallback: bytes remaining 
      after move to SystemBuffer 0x0<BR>KBDCLASS-KeyboardClassServiceCallback: 
      exit<BR>8042: I8042KeyboardIsrDpc: Call callback consumed 1 items, left 
      0<BR>8042: I8xSetDataQueuePointer: enter<BR>8042: I8xSetDataQueuePointer: 
      old keyboard DataOut 0xfe4cf60c, InputCount 14<BR>8042: 
      I8xSetDataQueuePointer: new keyboard DataOut 0xfe4cf618, InputCount 
      13<BR>8042: I8xSetDataQueuePointer: exit<BR><BR>8042: 
      I8xDpcVariableOperation: enter<BR>8042: Performing decrement at 0xfe4f529c 
      (current value 0xd)<BR>8042: I8xDpcVariableOperation: exit with value 
      0xc<BR>8042: I8xDpcVariableOperation: enter<BR>8042: Performing write at 
      0xfe4f529c (current value 0xc)<BR>8042: Writing 0x0<BR>8042: 
      I8xDpcVariableOperation: exit with value 0x0<BR>8042: I8042KeyboardIsrDpc: 
      loop in DPC<BR>8042: I8xGetDataQueuePointer: enter<BR>8042: 
      I8xGetDataQueuePointer: keyboard<BR>8042: I8xGetDataQueuePointer: DataIn 
      0xfe4cf6b4, DataOut 0xfe4cf618<BR>8042: I8xGetDataQueuePointer: 
      exit<BR>8042: I8042KeyboardIsrDpc: calling class callback<BR>8042: 
      I8042KeyboardIsrDpc: with Start 0xfe4cf618 and End 
      0xfe4cf6b4<BR>KBDCLASS-KeyboardClassServiceCallback: 
      enter<BR>KBDCLASS-KeyboardClassServiceCallback: bytes remaining after move 
      to SystemBuffer 0x9c<BR>KBDCLASS-KeyboardClassServiceCallback: unused 
      bytes in class queue 0x4b0, remaining bytes in port queue 
      0x9c<BR>KBDCLASS-KeyboardClassServiceCallback: total number of bytes to 
      move to class queue 0x9c<BR>KBDCLASS-KeyboardClassServiceCallback: number 
      of bytes to end of class buffer 
      0x12c<BR>KBDCLASS-KeyboardClassServiceCallback: number of bytes in first 
      move to class 0x9c<BR>KBDCLASS-KeyboardClassServiceCallback: move bytes 
      from 0xfe4cf618 to 0xfe4f5c8c<BR>KBDCLASS-KeyboardClassServiceCallback: 
      changed InputCount to 13 entries in the class 
      queue<BR>KBDCLASS-KeyboardClassServiceCallback: DataIn 0xfe4f5d28, DataOut 
      0xfe4f5c8c<BR>KBDCLASS-KeyboardClassServiceCallback: Input data items 
      consumed = 13<BR>KBDCLASS-KeyboardClassServiceCallback: exit<BR>8042: 
      I8042KeyboardIsrDpc: Call callback consumed 13 items, left 0<BR>8042: 
      I8xSetDataQueuePointer: enter<BR>8042: I8xSetDataQueuePointer: old 
      keyboard DataOut 0xfe4cf618, InputCount 13<BR>8042: 
      I8xSetDataQueuePointer: Okay to log keyboard overflow<BR>8042: 
      I8xSetDataQueuePointer: new keyboard DataOut 0xfe4cf6b4, InputCount 
      0<BR>8042: I8xSetDataQueuePointer: exit<BR>8042: I8xDpcVariableOperation: 
      enter<BR>8042: Performing decrement at 0xfe4f529c (current value 
      0x0)<BR>8042: I8xDpcVariableOperation: exit with value 0xffffffff<BR>8042: 
      I8042KeyboardIsrDpc: exit<BR><BR>KBDCLASS-KeyboardClassRead: 
      enter<BR>KBDCLASS-KeyboardClassStartIo: 
      enter<BR>KBDCLASS-KeyboardClassStartIo: DataIn 0xfe4f5d28, DataOut 
      0xfe4f5c8c<BR>KBDCLASS-KeyboardClassStartIo: entries in queue 
      13<BR>KBDCLASS-KeyboardClassStartIo: queue size 0x9c, read length 
      0x78<BR>KBDCLASS-KeyboardClassStartIo: bytes to end of queue 
      0x12c<BR>KBDCLASS-KeyboardClassStartIo: number of bytes in first move 
      0x78<BR>KBDCLASS-KeyboardClassStartIo: move bytes from 0xfe4f5c8c to 
      0xfe3a0b88<BR>KBDCLASS-KeyboardClassStartIo: new DataIn 0xfe4f5d28, 
      DataOut 0xfe4f5d04<BR>KBDCLASS-KeyboardClassStartIo: new InputCount 
      3<BR>KBDCLASS-KeyboardClassStartIo: exit<BR>KBDCLASS-KeyboardClassRead: 
      exit<BR><BR>KBDCLASS-KeyboardClassRead: 
      enter<BR>KBDCLASS-KeyboardClassStartIo: 
      enter<BR>KBDCLASS-KeyboardClassStartIo: DataIn 0xfe4f5d28, DataOut 
      0xfe4f5d04<BR>KBDCLASS-KeyboardClassStartIo: entries in queue 
      3<BR>KBDCLASS-KeyboardClassStartIo: queue size 0x24, read length 
      0x78<BR>KBDCLASS-KeyboardClassStartIo: bytes to end of queue 
      0xb4<BR>KBDCLASS-KeyboardClassStartIo: number of bytes in first move 
      0x24<BR>KBDCLASS-KeyboardClassStartIo: move bytes from 0xfe4f5d04 to 
      0xfe3a0b88<BR>KBDCLASS-KeyboardClassStartIo: Okay to log 
      overflow<BR>KBDCLASS-KeyboardClassStartIo: new DataIn 0xfe4f5d28, DataOut 
      0xfe4f5d28<BR>KBDCLASS-KeyboardClassStartIo: new InputCount 
      0<BR>KBDCLASS-KeyboardClassStartIo: exit<BR>KBDCLASS-KeyboardClassRead: 
      exit<BR><BR>KBDCLASS-KeyboardClassRead: 
      enter<BR>KBDCLASS-KeyboardClassStartIo: 
      enter<BR>KBDCLASS-KeyboardClassStartIo: DataIn 0xfe4f5d28, DataOut 
      0xfe4f5d28<BR>KBDCLASS-KeyboardClassStartIo: entries in queue 
      0<BR>KBDCLASS-KeyboardClassStartIo: exit<BR>KBDCLASS-KeyboardClassRead: 
      exit<BR><BR>7.7.2 
      分析<BR><BR>由于按住不放,使得不断的发生中断,让排队的DPC没有机会执行,从而在i8042prt的输入数据队列中累积了大量的数据。导致了在kbdclass层等待的那个 
      IRP_MJ_READ 的 IRP 不能一次把所有数据读走,于是 KeyboardClassServiceCallback 把剩余的数据放入 
      kbdclass 的输入数据队列。之后应用层发来的 IRP_MJ_READ 的 IRP 将直接从 kbdclass 
      的输入数据队列中读数据,直到所有的数据都被读完了,应用层再发来的 IRP_MJ_READ 的 IRP 才会在 kbdclass 
      上等待数据。<BR><BR>由于第一个 MakeCode 和第二个 MakeCode 之间有一个 Typematic Delay 
      ,之间间隔时间比较长,所以 DPC 有机会被执行。这里就是被执行,不过执行了一半,又被后面的 MakeCode 中断。关于 Typematic 
      Delay 的详细介绍,请看前面对于 ps/2 键盘硬件的介绍。<BR><BR>7.8 输入数据队列讨论<BR><BR>i8042prt 和 
      kbdclass 各有自己的一个输入数据队列,循环使用的缓冲区。他们的每个单元是一个 KEYBOARD_INPUT_DATA 
      结构。<BR><BR>kbclass 和 i8042prt 的输入数据队列是在键盘驱动的初始化过程中分配内存的。<BR><BR>kbdclass 
      的输入数据队列是在 kbdclass!KeyboardAddDevice 
      中,分配内存,并初始化设备扩展中的使用输入数据队列的相关域。<BR><BR>i8042prt 的输入数据队列是在 
      i8042prt!I8xKeyboardStartDevice 
      中,分配内存,并初始化设备扩展中的使用输入数据队列的相关域。<BR><BR>kbdclass 和 i8042prt 
      的输入数据队列的单元个数都是读取注册表中的参数决定的,如果注册表中不存在相应的键值,那么使用默认值。默认值为 
      0x64(十进制100)。<BR><BR>对于这两个输入数据队列,<BR>放入一个数据,这个数据应该被放在 DataIn 处,然后DataIn 
      后移一格,InputCount 加 1。当 DataIn 移到队列的结尾时,将从队列的开头重新开始。<BR>取出一个数据,这个数据应该从 
      DataOut 处取出,然后 DataOut 后移一格,InputCount 减 1。当 DataOut 
      移到队列的结尾时,将从队列的开头重新开始。<BR><BR>对于 i8042prt 
      的输入数据队列。键盘中断服务例程中,从i8042读出的按键信息,放入i8042prt的输入数据队列。上层处理输入的回调函数中,取出i8042prt的输入数据队列中的数据。由于一次键盘中断只会放入一个数据,所以i8042prt的输入数据队列,只会放入一个一个的放入数据。<BR><BR>对于 
      kbdclass 的输入数据队列。只有当那个等待的 IRP_MJ_READ IRP 
      要求读的大小,小于i8042prt的输入队列中放入的数据时,才被使用。也就是说,只有当那个等着读的 IRP 读不完输入数据时,才使用 
      kbdclass 的输入数据队列。当那个等着读的 IRP 
      读完要求的数据后,还有剩余时,剩余的数据放入kbdclass的输入数据队列。下一次的应用层发来的 IRP_MJ_READ 
      IRP,当发现kbdclass的输入数据队列中有数据时,直接从kbdclass的输入数据队列中读出数据。<BR><BR><BR>输入数据队列反转的判断和处理<BR><BR>随着数据的输入,DataIn 
      不断后移,就会出现下图的情况。 
      <P align=center><IMG src="JIURL键盘驱动 5.files/Queue1.gif" border=0> 
      <P>遇到这种情况的话,要想从输入数据队列中复制数据,就需要把数据分为两段来复制,从 DataOut 到 DataEnd 一段,从 
      InputData 到 DataIn 是另一段。<BR><BR>对于i8042prt的输入数据队列,如果 DataOut &gt;= DataIn 
      ,并且 InputCount &gt; 0,就说明遇到了这种情况。分两段,分别调用 
      KeyboardClassServiceCallback。<BR><BR>对于kbdclass的输入数据队列,如果要传给 IRP 
      的数据大小&gt;从DataOut到输入数据队列尾部的大小,说明遇到了这种情况。分两段,分两次复制到IRP的 
      AssociatedIrp.SystemBuffer 
      中。<BR><BR><BR>输入数据队列覆盖的判断和处理<BR><BR>随着数据的输入,DataIn 
      不断后移,最终用完了整个输入数据队列,如下图所示。 
      <P align=center><IMG src="JIURL键盘驱动 5.files/Queue2.gif" border=0> 
      <P>如果再有输入数据,DataIn 再后移,就会出现下图的情况。 
      <P align=center><IMG src="JIURL键盘驱动 5.files/Queue3.gif" border=0> 
      <P>覆盖会使数据不正确。<BR><BR>i8042prt的输入数据队列,一次只会写入一个数据。写入数据时做判断,如果 DataIn 等于 
      DataOut ,并且 InputCount 
      不为0的话,说明如果将当前的输入数据写入输入数据队列会造成覆盖。处理方法就是丢弃当前的输入数据不写入输入数据队列。并且丢弃前一个输入数据,用腾出的单元放一个 
      MakeCode 为KEYBOARD_OVERRUN_MAKE_CODE 
      的数据。<BR><BR><BR>DataIn移到队尾时的处理<BR><BR>对于 i8042prt 的输入数据队列,写入数据时判断,如果写入数据后 
      DataIn 等于 DataEnd,那么说明 DataIn 已经移到了队尾,将 DataIn 设置为队头 InputData。<BR><BR>对于 
      kbdclass 的输入数据队列,只有当需要移入数据的大小&gt;从当前 DataIn 到队尾的大小时,才会出现 DataIn 
      移到队尾的情况。遇到这种情况,移入数据将分两次移入,第一次移入到 DataIn 到 队尾,移完之后DataIn就到了队尾,然后把DataIn 
      设置为队头 InputData。<BR><BR><BR>DataOut移到队尾时的处理<BR><BR>对于 i8042prt 
      的输入数据队列,只有分两段时,DataOut才会出现移到队尾的情况。分两段取走数据,当第一段(从 DataOut 到 
      DataEnd)全部取完之后,就把 DataOut 设置为队头 InputData。<BR><BR>对于 kbdclass 
      的输入数据队列,只有分两段时,DataOut才会出现移到队尾的情况。分两段,分两次复制到IRP的 
      AssociatedIrp.SystemBuffer 中。DataOut 到队尾不需要特殊处理。<BR><BR><BR><B>8 
      升华</B><BR><BR>&nbsp;&nbsp;&nbsp; 
      学会了写驱动,就可以控制硬件了,想想吧,有多好,能干多少有意思的事啊。<BR><BR>&nbsp;&nbsp;&nbsp; 
      我们以键盘驱动为对象,从硬件直到应用层,这一整套做了一定的研究。对碰到的各种 Windows 
      驱动的基本问题,比如驱动对象,设备对象,设备栈,IRP机制,等等,也做了一定的研究。对一个的了解,就可以推及其他。对 Windows 
      驱动建立起了整体的认识。键盘驱动成了一个我们十分熟悉的很好的范例,以后在其他驱动中遇到的很多问题,很可能都可以在键盘驱动中找到值得参考的解决方法。最后我们以键盘驱动为例,来谈一谈 
      Windows 驱动中的一些概念,认识。<BR><BR>&nbsp;&nbsp;&nbsp; 
      与所有硬件设备的通信,对所有硬件设备的控制,使用,都是通过读写端口。要给一个硬件写驱动,需要对这个硬件有一定的了解,尤其是通过端口访问的一些寄存器,一些命令。比如键盘驱动中,通过对0x60和0x64这两个端口的读写,完成从键盘上读数据,命令键盘点亮led指示灯,之类的工作。<BR><BR><BR>&nbsp;&nbsp;&nbsp; 
      FDO, Functional Device Object ,功能设备对象。i8042prt的用于键盘的那个设备对象就是键盘设备栈中的 
      FDO,而所有与键盘硬件有关的操作都是在 i8042prt 中实现。<BR><BR>&nbsp;&nbsp;&nbsp; PDO,Physical 
      Device Object ,物理设备对象。acpi的用于键盘的那个设备对象就是键盘设备栈中的 
      PDO,它是设备栈中最低下的那个设备对象,管一些总线的事,比如处理电源管理之类。对于键盘相关的各种处理不起什么作用。<BR><BR>&nbsp;&nbsp;&nbsp; 
      port 
      driver,端口驱动,驱动i8042prt就是键盘驱动中的端口驱动,所有的读写端口的工作都是在这个驱动进行的,这也就是为什么叫做端口驱动。<BR><BR>&nbsp;&nbsp;&nbsp; 
      class 
      driver,类驱动,驱动kbdclass就是键盘驱动中的类驱动。ps/2键盘的端口驱动和usb键盘的端口驱动是绝对不同的,而ps/2键盘和usb键盘的类驱动都是kbdclass,kbdclass驱动完成的是硬件无关的,键盘这一类设备共同的工作,这也就是为什么叫做类驱动。<BR><BR>&nbsp;&nbsp;&nbsp; 
      从这些概念中,我们也可以对驱动为什么要分层,如何分层,有一点感觉。<BR><BR><B>完</B><BR><BR><BR>欢迎访问<BR>主页 <A 
      href="http://jiurl.yeah.net/" target=_blank>http://jiurl.yeah.net/</A> <A 
      href="http://jiurl.nease.net/" target=_blank>http://jiurl.nease.net/</A> 
      论坛 <A href="http://jiurl.cosoft.org.cn/forum" 
      target=_blank>http://jiurl.cosoft.org.cn/forum</A> 
      <P>f啊k,不带你们这样的啊,有好事不叫我。
      <P>  
      <P>  </P></TD></TR></TBODY></TABLE></DIV>
<SCRIPT src="JIURL键盘驱动 5.files/nnselect.js"></SCRIPT>
</BODY></HTML>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -