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

📄 jiurl键盘驱动 4.htm

📁 JIURL键盘驱动
💻 HTM
📖 第 1 页 / 共 5 页
字号:
      [Non-Fpo])<BR>05 f901f764 8048e040 fe4fed68 f901f88c 00000000 
      nt!IopStartAndEnumerateDevice+0x1c7 (FPO: [Non-Fpo])<BR>06 f901f784 
      804e504e fe4fed68 f901f88c fe4d6368 nt!IopProcessStartDevicesWorker+0x72 
      (FPO: [Non-Fpo])<BR>07 f901f794 804a4670 fe4d6368 804a4618 f901f88c 
      nt!IopForAllChildDeviceNodes+0x1f (FPO: [3,0,1])<BR>08 f901f7b8 804e504e 
      fe4d6368 f901f88c fe4e7c28 nt!IopProcessStartDevicesWorker+0x55 (FPO: 
      [Non-Fpo])<BR>09 f901f7c8 804a4670 fe4e7c28 804a4618 f901f88c 
      nt!IopForAllChildDeviceNodes+0x1f (FPO: [3,0,1])<BR>0a f901f7ec 804e504e 
      fe4e7c28 f901f88c fe5181a8 nt!IopProcessStartDevicesWorker+0x55 (FPO: 
      [Non-Fpo])<BR>0b f901f7fc 804a4670 fe5181a8 804a4618 f901f88c 
      nt!IopForAllChildDeviceNodes+0x1f (FPO: [3,0,1])<BR>0c f901f820 804e504e 
      fe5181a8 f901f88c fe51b5e8 nt!IopProcessStartDevicesWorker+0x55 (FPO: 
      [Non-Fpo])<BR>0d f901f830 804a4670 fe51b5e8 804a4618 f901f88c 
      nt!IopForAllChildDeviceNodes+0x1f (FPO: [3,0,1])<BR>0e f901f854 804a4607 
      fe51b5e8 f901f88c 00000003 nt!IopProcessStartDevicesWorker+0x55 (FPO: 
      [Non-Fpo])<BR>0f f901f870 8054e017 fe51b2c8 f901f88c 80087000 
      nt!IopProcessStartDevices+0x43 (FPO: [EBP 0xf901f8c0] [2,0,4])<BR>10 
      f901f8c0 8054c5c9 00000000 00000032 00000000 
      nt!IopInitializeSystemDrivers+0x5d (FPO: [Non-Fpo])<BR>11 f901fa58 
      8054b35a 80087000 00000000 00000000 nt!IoInitSystem+0x644 (FPO: 
      [Non-Fpo])<BR>12 f901fda8 804524f6 80087000 00000000 00000000 
      nt!Phase1Initialization+0x71b (FPO: [Non-Fpo])<BR>13 f901fddc 80465b62 
      8054aca6 80087000 00000000 nt!PspSystemThreadStartup+0x69 (FPO: 
      [Non-Fpo])<BR><BR>kbdclass!KeyboardPnP 和 i8042prt!I8xPnP 
      中都没有做什么处理。<BR><BR>[启动ps/2鼠标的 IRP_MJ_PNP 
      IRP_MN_START_DEVICE]<BR><BR>硬件的初始化工作,对于ps/2的鼠标和ps/2的键盘都是向i8042发一些命令。所以驱动 
      i8042prt 把ps/2键盘鼠标的硬件初始化工作放在了一起进行。<BR>前面已经给键盘设备栈发 IRP_MJ_PNP 
      IRP_MN_START_DEVICE 的 IRP 将键盘启动了。现在给鼠标设备栈发 IRP_MJ_PNP IRP_MN_START_DEVICE 
      的 IRP,启动鼠标,将在鼠标启动的最后初始化键盘和鼠标的硬件。<BR><BR># ChildEBP RetAddr Args to 
      Child&nbsp;<BR>00 f901f5c8 8041f54b fe4d3ba0 fe4fea08 fe4d3b18 
      i8042prt!I8xPnP(struct _DEVICE_OBJECT * DeviceObject = 0xfe4d3ba0, struct 
      _IRP * Irp = 0xfe4fea08) (CONV: stdcall)<BR>01 f901f5dc f91ff8c2 fe4d3a60 
      fe4fea08 fe4fea08 nt!IopfCallDriver+0x35 (FPO: [0,0,2])<BR>WARNING: Stack 
      unwind information not available. Following frames may be wrong.<BR>02 
      f901f604 8041f54b fe4d3a60 fe4fea08 00000000 vmmouse+0x8c2<BR>03 f901f618 
      f8ec26fd fe4fea08 fe4d3928 fe043801 nt!IopfCallDriver+0x35 (FPO: 
      [0,0,2])<BR>04 f901f638 f8ec12d8 fe4d3a60 fe4fea08 00000001 
      mouclass!MouseSendIrpSynchronously+0x57 (FPO: [Non-Fpo])<BR>05 f901f6a4 
      8041f54b fe4feb50 fe4fea08 fe4d3870 mouclass!MousePnP+0x2b2 (FPO: 
      [Non-Fpo])<BR>06 f901f6b8 8049cb91 00020000 fe4fec88 00000000 
      nt!IopfCallDriver+0x35 (FPO: [0,0,2])<BR>07 f901f6e4 804289ce fe4d3870 
      f901f704 f901f72c nt!IopSynchronousCall+0xca (FPO: [Non-Fpo])<BR>08 
      f901f730 8048e06a fe4dd610 00000000 fe4fec88 nt!IopStartDevice+0x127 (FPO: 
      [Non-Fpo])<BR>09 f901f764 8048e040 fe4fec88 f901f88c 00000000 
      nt!IopStartAndEnumerateDevice+0x22 (FPO: [Non-Fpo])<BR>0a f901f784 
      804e504e fe4fec88 f901f88c fe4d6368 nt!IopProcessStartDevicesWorker+0x72 
      (FPO: [Non-Fpo])<BR>0b f901f794 804a4670 fe4d6368 804a4618 f901f88c 
      nt!IopForAllChildDeviceNodes+0x1f (FPO: [3,0,1])<BR>0c f901f7b8 804e504e 
      fe4d6368 f901f88c fe4e7c28 nt!IopProcessStartDevicesWorker+0x55 (FPO: 
      [Non-Fpo])<BR>0d f901f7c8 804a4670 fe4e7c28 804a4618 f901f88c 
      nt!IopForAllChildDeviceNodes+0x1f (FPO: [3,0,1])<BR>0e f901f7ec 804e504e 
      fe4e7c28 f901f88c fe5181a8 nt!IopProcessStartDevicesWorker+0x55 (FPO: 
      [Non-Fpo])<BR>0f f901f7fc 804a4670 fe5181a8 804a4618 f901f88c 
      nt!IopForAllChildDeviceNodes+0x1f (FPO: [3,0,1])<BR>10 f901f820 804e504e 
      fe5181a8 f901f88c fe51b5e8 nt!IopProcessStartDevicesWorker+0x55 (FPO: 
      [Non-Fpo])<BR>11 f901f830 804a4670 fe51b5e8 804a4618 f901f88c 
      nt!IopForAllChildDeviceNodes+0x1f (FPO: [3,0,1])<BR>12 f901f854 804a4607 
      fe51b5e8 f901f88c 00000003 nt!IopProcessStartDevicesWorker+0x55 (FPO: 
      [Non-Fpo])<BR>13 f901f870 8054e017 fe51b2c8 f901f88c 80087000 
      nt!IopProcessStartDevices+0x43 (FPO: [EBP 0xf901f8c0] 
      [2,0,4])<BR><BR>我们只讨论键盘部分的内容。<BR><BR>i8042prt!I8xPnP 中,调用 
      I8xMouseStartDevice。<BR>I8xMouseStartDevice 
      中都是鼠标相关的内容,我们并不关心,直到最后,判断,如果没有ps/2键盘,或者有ps/2键盘但是已经启动了,那么将调用 
      i8042prt!I8xMouseInitializeHardware 
      初始化硬件。我这里有ps/2键盘,并且已经启动了,i8042prt!I8xMouseInitializeHardware 
      将被调用。<BR><BR>i8042prt!I8xMouseInitializeHardware 中,<BR>调用 
      I8xInitializeHardwareAtBoot ,初始化硬件。<BR>调用 I8xKeyboardConnectInterrupt 
      ,连接键盘中断。<BR><BR>I8xInitializeHardwareAtBoot 中,<BR>调用 
      I8xSanityCheckResources ,检查必要的资源是否存在。<BR>调用 I8xToggleInterrupts(FALSE) 
      ,disable 键盘中断。<BR>调用 I8xInitializeHardware ,初始化键盘硬件和鼠标硬件,我们只讨论键盘。<BR>调用 
      I8xToggleInterrupts(TRUE) ,enable 键盘中断。<BR><BR>I8xSanityCheckResources 
      中,<BR>将 Globals.ControllerData-&gt;DeviceRegisters[i] 设置为 
      Globals.ControllerData-&gt;Configuration.PortList[i].u.Port.Start.LowPart<BR><BR>驱动中把 
      0x60 叫数据端口。<BR>驱动中把 0x64 叫命令端口。<BR>关于各种命令的详细内容请参考"1 ps/2 
      键盘的硬件"。<BR><BR>I8xToggleInterrupts(FALSE) 中,<BR>向命令端口发 0x20 
      ,取出i8042的命令字节。我这里取出的命令字节为 0x47,即二进制 01000111,看到Bit0为1,说明 enable 
      键盘中断。Bit1为1,说明 enable 鼠标中断。使用指定的 ByteMask: ~((UCHAR) 
      CCB_ENABLE_KEYBOARD_INTERRUPT |(UCHAR) CCB_ENABLE_MOUSE_INTERRUPT) 
      执行一个指定的操作: AND_OPERATION。于是命令字节变为 0x44,即二进制 01000100。禁止了键盘和鼠标的中断。向命令端口发 
      0x60 
      ,写入i8042的命令字节,将修改过的命令字节作为参数发送到数据端口,从而禁止了键盘和鼠标的中断。<BR><BR>I8xInitializeHardware 
      中,调用 I8xInitializeKeyboard 初始化键盘硬件,I8xInitializeKeyboard 中,Reset 
      Keyboard,关闭键盘的 Translate 模式,设置键盘的 Typematic Rate 和 Typematic 
      Delay,设置键盘指示灯,重新打开键盘的 Translate 模式。<BR><BR>Reset Keyboard,向数据端口发 0xff ,来 
      Reset 
      Keyboard。这个命令将使Keyboard,首先回复一个ACK,然后启动自身的Reset程序,并进行自身基本正确性检测(BAT-Basic 
      Assurance Test)。等这一切结束之后,将返回给系统一个单字节的结束码(AAh=Success, 
      FCh=Failed),并将键盘的Scan code set设置为2。<BR><BR>关闭键盘的 Translate 模式,首先向命令端口发 
      0x20 ,取出i8042的命令字节。我这里取出的命令字节为 0x44,即二进制 01000100。使用指定的 ByteMask: 
      ~((UCHAR)CCB_KEYBOARD_TRANSLATE_MODE) 执行一个指定的操作: AND_OPERATION。于是命令字节变为 
      0x4,即二进制 00000100,Bit6被清0,关闭了 Translate 模式。向命令端口发 0x60 
      ,写入i8042的命令字节,将修改过的命令字写入i8042控制器命令字节,从而关闭了 Translate 模式。<BR><BR>设置 
      Typematic Rate 和 Typematic Delay,向数据端口发 0xf3,这是设置 Typematic Rate 和 
      Typematic 
      Delay的命令,然后将deviceExtension-&gt;KeyRepeatCurrent.Rate,deviceExtension-&gt;KeyRepeatCurrent.Delay 
      转换为1个字节的设置命令的参数。deviceExtension-&gt;KeyRepeatCurrent.Rate,deviceExtension-&gt;KeyRepeatCurrent.Delay 
      在前面的 I8xKeyboardConfiguration 中,被设置为 KEYBOARD_TYPEMATIC_RATE_DEFAULT 和 
      KEYBOARD_TYPEMATIC_DELAY_DEFAULT ,KEYBOARD_TYPEMATIC_RATE_DEFAULT 为 
      30,KEYBOARD_TYPEMATIC_DELAY_DEFAULT 为 
      250。将转换得到的设置参数,发到数据端口。<BR><BR>设置键盘指示灯,向数据端口发 
      0xed,这是设置LED命令,然后将deviceExtension-&gt;KeyboardIndicators.LedFlags 
      作为命令的参数,发到数据端口。deviceExtension-&gt;KeyboardIndicators.LedFlags 在前面的 
      I8xKeyboardConfiguration 中,被设置为 KEYBOARD_INDICATORS_DEFAULT,即 
      0。<BR><BR>重新打开键盘的 Translate 模式,键盘默认发送 scan code set 
      2,当设置了i8042命令字节中的translate 位时,i8042在把扫描码发送给 CPU 之前,转换为 scan code set 
      1。首先向命令端口发 0x20 ,取出i8042的命令字节。我这里取出的命令字节为 0x4,即二进制 00000100。使用指定的 
      ByteMask: CCB_KEYBOARD_TRANSLATE_MODE 执行一个指定的操作: OR_OPERATION。于是命令字节变为 
      0x44,即二进制 01000100,Bit6被置1,打开了 Translate 模式。向命令端口发 0x60 
      ,写入i8042的命令字节,将修改过的命令字写入i8042控制器命令字节,从而打开了 Translate 
      模式。<BR><BR>I8xToggleInterrupts(TRUE) 中,<BR>向命令端口发 
      0xad,禁止键盘接口。向命令端口发0xa7,禁止鼠标接口。向命令端口发 0x20 ,取出i8042的命令字节。我这里取出的命令字节为 
      0x74,即二进制 01110100,看到Bit0为0,说明 disable 键盘中断。Bit1为0,说明 disable 
      鼠标中断。Bit4为1,Bit5为1,说明禁止了键盘和鼠标。向命令端口发 
      0xae,打开键盘接口。向命令端口发0xa8,打开鼠标接口。于是命令字节变为 0x44。使用指定的 ByteMask: 
      CCB_ENABLE_KEYBOARD_INTERRUPT |CCB_ENABLE_MOUSE_INTERRUPT 执行一个指定的操作: 
      OR_OPERATION。于是命令字节变为 0x47,即二进制 01000111。enable 了键盘和鼠标的中断。向命令端口发 0x60 
      ,写入i8042的命令字节,将修改过的命令字节作为参数发送到数据端口,从而打开了键盘和鼠标的中断。<BR><BR>I8xKeyboardConnectInterrupt 
      中,<BR><BR>以i8042prt键盘设备扩展中的一些域为参数,调用 IoConnectInterrupt 
      连接键盘中断。<BR><BR>IoConnectInterrupt(<BR>&amp;(KeyboardExtension-&gt;InterruptObject),<BR>(PKSERVICE_ROUTINE) 
      I8042KeyboardInterruptService,<BR>self,<BR>&amp;KeyboardExtension-&gt;InterruptSpinLock,<BR>KeyboardExtension-&gt;InterruptDescriptor.u.Interrupt.Vector,&nbsp;<BR>(KIRQL) 
      KeyboardExtension-&gt;InterruptDescriptor.u.Interrupt.Level,<BR>configuration-&gt;InterruptSynchIrql,&nbsp;<BR>KeyboardExtension-&gt;InterruptDescriptor.Flags<BR>== 
      CM_RESOURCE_INTERRUPT_LATCHED ? Latched : LevelSensitive,<BR>(BOOLEAN) 
      (KeyboardExtension-&gt;InterruptDescriptor.ShareDisposition<BR>== 
      CmResourceShareShared),<BR>KeyboardExtension-&gt;InterruptDescriptor.u.Interrupt.Affinity,&nbsp;<BR>configuration-&gt;FloatingSave<BR>);<BR><BR>其中 
      IoConnectInterrupt 的参数 ServiceRoutine 为 I8042KeyboardInterruptService ,参数 
      Vector 为 KeyboardExtension-&gt;InterruptDescriptor.u.Interrupt.Vector ,值为 
      0xb3。也就是说,键盘中断IRQ1,将引起中断描述符表中 0xb3 中的中断服务例程被执行,最终将执行 
      i8042!prtI8042KeyboardInterruptService。驱动的中断有一些特殊,详细我们将在以后讨论。<BR><BR>之后会得到键盘设备栈的栈顶设备对象,然后向栈顶发一个 
      IRP_MJ_INTERNAL_DEVICE_CONTROL 
      IOCTL_INTERNAL_I8042_KEYBOARD_START_INFORMATION 的 
      IRP,不过键盘设备栈对此不做什么处理。<BR><BR>[kbdclass!KeyboardClassFindMorePorts]<BR><BR>由于在 
      kbdclass!DriverEntry 中 
      IoRegisterDriverReinitialization(DriverObject,KeyboardClassFindMorePorts,NULL);<BR>所以现在 
      kbdclass!KeyboardClassFindMorePorts 被调用了。<BR><BR># ChildEBP RetAddr Args 
      to Child&nbsp;<BR>00 f901f614 804d92bc fe4f6330 00000000 00000001 
      kbdclass!KeyboardClassFindMorePorts(struct _DRIVER_OBJECT * DriverObject = 
      0xfe4f6330, void * Context = 0x00000000, unsigned long Count = 1) (CONV: 
      stdcall)<BR>01 f901f638 8052a72f f901f668 f901f6c4 f901f740 
      nt!IopLoadUnloadDriver+0x7a (FPO: [EBP 0xf901f6b8] [1,1,4])<BR>02 f901f6b8 
      80461691 f901f760 8000003c 80000040 nt!NtLoadDriver+0x199 (FPO: 
      [Non-Fpo])<BR>03 f901f6b8 80400d15 f901f760 8000003c 80000040 
      nt!KiSystemService+0xc4 (FPO: [0,0] TrapFrame @ f901f6c4)<BR>04 f901f734 
      fe22a8bd f901f760 fe4da470 fe4fea08 nt!ZwLoadDriver+0xb (FPO: 
      [1,0,0])<BR>05 f901f774 8041f54b fe4da470 fe4fea9c fe4da470 
      NDIS!ndisPnPDispatch+0x40e (FPO: [Non-Fpo])<BR>06 f901f788 8049cb91 
      00020000 fe519408 00000000 nt!IopfCallDriver+0x35 (FPO: [0,0,2])<BR>07 
      f901f7b4 804289ce fe4da470 f901f7d4 f901f7fc nt!IopSynchronousCall+0xca 
      (FPO: [Non-Fpo])<BR>08 f901f800 8048e06a fe519510 00000000 fe519408 
      nt!IopStartDevice+0x127 (FPO: [Non-Fpo])<BR>09 f901f834 8048e040 fe519408 
      f901f88c 00000000 nt!IopStartAndEnumerateDevice+0x22 (FPO: 
      [Non-Fpo])<BR>0a f901f854 804a4607 fe519408 f901f88c 00000003 
      nt!IopProcessStartDevicesWorker+0x72 (FPO: [Non-Fpo])<BR>0b f901f870 
      8054e017 fe519208 f901f88c 80087000 nt!IopProcessStart

⌨️ 快捷键说明

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