用windbg寻找设备树根节点

来源:互联网 发布:mac梦幻西游更新失败 编辑:程序博客网 时间:2024/05/16 02:25

    用ReactOS上明确说过,Pnp管理器对每种设备都会创建一个虚拟root device用于构建设备树;同时这个新创建的root device又作为一个设备栈的栈底,往上形成完整的设备栈。用windbg调试时,可以看到这个虚拟设备属于/driver/pnpmanager驱动。

    昨天出于好奇想看下设备树,结果发现只有虚拟设备attach在/driver/pnpmanger创建的设备上,而类似pci/usb设备的设备栈栈底根本不是/driver/pnpmanager设备,这让我很是怀疑,M$到底怎样形成以root为根节点的设备树。

如mssmbios.sys位于设备管理器system设备类下,注册表路径为:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\Root\SYSTEM\0002

用windbg查看设备堆栈,可以看到这个设备attach在/driver/pnpmanger根节点上:

kd> !drvobj mssmbiosDriver object (81f81da0) is for: \Driver\mssmbiosDriver Extension List: (id , addr)Device Object list:81c8e408  kd> !devstack 81c8e408    !DevObj   !DrvObj            !DevExt   ObjectName> 81c8e408  \Driver\mssmbios   81c8e4c0    821e73d0  \Driver\PnpManager 821e7488  00000034 !DevNode 821e7288 :  DeviceInst is "Root\SYSTEM\0002"  ServiceName is "mssmbios"
又如DDK样例toaster的虚拟总线设备busenum同样位于system设备类下,注册表路径为:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\Root\SYSTEM\0003

其设备栈为:,亦可看到栈底pnpmanager设备

kd> !drvobj busenumDriver object (81f81030) is for: \Driver\busenumDriver Extension List: (id , addr)Device Object list:81ff3030  kd> !devstack 81ff3030    !DevObj   !DrvObj            !DevExt   ObjectName> 81ff3030  \Driver\busenum    81ff30e8    821e7190  \Driver\PnpManager 821e7248  00000035!DevNode 821a0008 :  DeviceInst is "Root\SYSTEM\0003"  ServiceName is "busenum"
    然而,对于一些总线设备根本找不到pnpmanager,如PCI总线和USB总线:

kd> !drvobj pciDriver object (82189218) is for: \Driver\PCIDriver Extension List: (id , addr)Device Object list:82127c70  82127e50  82127030  821e03a0...8219cb98  821e5370  821ba160  kd> !devstack 82127c70    !DevObj   !DrvObj            !DevExt   ObjectName  81d34028  \Driver\usbehci    81d340e0  USBFDO-1  82127790  \Driver\ACPI       82187810  00000064> 82127c70  \Driver\PCI        82127d28  NTPNP_PCI0043!DevNode 821272e8 :  DeviceInst is "PCI\VEN_15AD&DEV_0770&SUBSYS_077015AD&REV_00\4&47b7341&0&1888"  ServiceName is "usbehci"

kd> !drvobj usbhubDriver object (820de2c0) is for: \Driver\usbhubDriver Extension List: (id , addr)Device Object list:81c74c98  81d542f0  820f1b70  81fcac9881c7ac98  kd> !devstack  81c74c98    !DevObj   !DrvObj            !DevExt   ObjectName> 81c74c98  \Driver\usbhub     81c74d50  00000079  81d542f0  \Driver\usbhub     81d543a8  USBPDO-3!DevNode 81c82c48 :  DeviceInst is "USB\Vid_0e0f&Pid_0002\6&2edefd9b&0&2"  ServiceName is "usbhub"
    对此,我百思不得解,pnpmanager去哪了?经过周AM指点,搞明白一件事:用!drvobj PCI列出pci设备中,除了最后一个是Fdo,其他都是Pdo(这里Fdo设备的意思是由PCI总线驱动AddDevice函数创建的设备,附加在底层的ACPI总线上,而Pdo设备是PCI总线探测到总线上接入了新设备,从而为这个新设备创建了一个Pdo以形成设备栈)。这些Fdo本身是由PCI总线创建,因此并不会attach在pnpmanager上,而通过查找Fdo设备的设备栈,才能找出栈底Pnpmanager。

    顺着周AM的思路,我重新调试了一遍,的确找到了PCI总线所在的Pnpmanager,以上面的环境为例,

kd> !drvobj pciDriver object (82189218) is for: \Driver\PCIDriver Extension List: (id , addr)Device Object list:82127c70  82127e50  82127030  821e03a0...8219cb98  821e5370  821ba160 
Pci总线驱动创建的设备0x821ba160就是Fdo(为什么Fdo位于最后?因为这是PCI!AddDevice创建的第一个设备对象,之后创建的设备对象都通过InsertListTail插入到设备队列头部,因此遍历设备队列时,Fdo是最后被遍历到的),查看它的设备栈:

kd> !devstack 821ba160  !DevObj   !DrvObj            !DevExt   ObjectName> 821ba160  \Driver\PCI        821ba218    821731a8  \Driver\ACPI       821e2940  00000038!DevNode 821de178 :  DeviceInst is "ACPI\PNP0A03\2&daba3ff&0"  ServiceName is "pci"
    PCI设备堆叠在ACPI的Pdo上,怪不得找不到在PCI的设备栈中找不到Pnpmanager。继续寻祖,查找ACPI驱动创建的Fdo:

kd> !drvobj ACPIDriver object (8219ca10) is for: \Driver\ACPIDriver Extension List: (id , addr)Device Object list:8212c628  8212c740  8212c858  82126538...821731a8  8219c8f8  kd> !devstack 8219c8f8    !DevObj   !DrvObj            !DevExt   ObjectName> 8219c8f8  \Driver\ACPI       821e2ea0    821a0aa8  \Driver\ACPI_HAL   821a0b60  00000037!DevNode 8219cd50 :  DeviceInst is "ACPI_HAL\PNP0C08\0"  ServiceName is "ACPI"
    同样ACPI的Fdo堆叠在ACPI_HAL驱动的Pdo上,继续寻祖,这次找ACPI_HAL的堆叠情况:

kd> !drvobj ACPI_HALDriver object (821a0f38) is for: \Driver\ACPI_HALDriver Extension List: (id , addr)Device Object list:821a0aa8  821a0bc8  kd> !devstack 821a0bc8    !DevObj   !DrvObj            !DevExt   ObjectName> 821a0bc8  \Driver\ACPI_HAL   821a0c80    821a4c68  \Driver\PnpManager 821a4d20  00000001!DevNode 821a4b20 :  DeviceInst is "Root\ACPI_HAL\0000"
    终于在ACPI_HAL驱动的Fdo设备栈中找到了Pnpmanager。这和Windows内核原理与实现书中提供的设备树的结构完全相似

    如果此时再深究一下PnpManager驱动创建的设备对象,会发现系统中果真只有一个根设备节点,而其他的PnpManager设备对象都是为了扩展设备树一点一点生长出来的:

kd> !drvobj PnpManagerDriver object (821eb2e8) is for: \Driver\PnpManagerDriver Extension List: (id , addr)Device Object list:821e7190  821e73d0  821e7610  821e7850...821a4c68  821a4020  kd> !devstack  821a4020    !DevObj   !DrvObj            !DevExt   ObjectName> 821a4020  \Driver\PnpManager 821a40d8  !DevNode 821a4ee8 :  DeviceInst is "HTREE\ROOT\0" <----从名字能感觉出这是根设备节点kd> !devstack 821a4c68    !DevObj   !DrvObj            !DevExt   ObjectName  821a0bc8  \Driver\ACPI_HAL   821a0c80  > 821a4c68  \Driver\PnpManager 821a4d20  00000001  <----<span style="font-family: Arial, Helvetica, sans-serif;">名字看着这么没个性,肯定不是根设备节点了</span>!DevNode 821a4b20 :  DeviceInst is "Root\ACPI_HAL\0000" 





0 0
原创粉丝点击