Debugging Tools for Windows

!dma

!dma 扩展显示直接内存访问(Direct Memory Access (DMA))子系统的信息,以及驱动程序验证器的DMA Verifier选项。

语法

!dma 
!dma Adapter [Flags

参数

Adapter
指定要显示的DMA适配器的16进制地址。如果是0,则显示所有的DMA适配器。
Flags
指定显示中包含的信息。可以是下面这些位的任意组合。默认值为0x1。
Bit 0 (0x1)
显示一般的适配器信息。
Bit 1 (0x2)
显示映射记录(map register)信息。(仅当DMA Verification激活时。)
Bit 2 (0x4)
显示公共缓冲区(common buffer)信息。 (仅当DMA Verification激活时。)
Bit 3 (0x8)
显示分散/聚合列表(scatter/gather list)信息。 (仅当DMA Verification激活时。)
Bit 4 (0x10)
显示硬件设备的设备描述(device description)。 (仅当DMA Verification激活时。)
Bit 5 (0x20)
显示等待上下文块(Wait context block)的信息。

DLL

Windows 2000 不可用
Windows XP和之后 Kdexts.dll

注释

使用非法参数(例如,!dma 1)会显示简单的帮助文本。

不带参数使用!dma 扩展时,显示所有DMA适配器和它们的地址的简明列表。这可以用来获得在更长的命令形式中使用的适配器地址。

下面是一个如何在驱动程序验证器的DMA Verification选项打开时使用该扩展的示例:

0:kd> !dma

Dumping all DMA adapters...

Adapter: 82faebd0     Owner: SCSIPORT!ScsiPortGetUncachedExtension 
Adapter: 82f88930     Owner: SCSIPORT!ScsiPortGetUncachedExtension 
Adapter: 82f06cd0     Owner: NDIS!NdisMAllocateMapRegisters 
Master adapter: 80076800

从输出中,可以看到系统中有三个DMA适配器。SCSIPORT 有两个, NDIS拥有第三个。要查看NDIS适配器的详细信息,可以对它的地址使用!dma

0:kd> !dma  82f06cd0
Adapter: 82f06cd0     Owner: NDIS!NdisMAllocateMapRegisters (0x9fe24351)
   MasterAdapter:       00000000
   Adapter base Va      00000000
   Map register base:   00000000
   WCB:                 82f2b604
   Map registers: 00000000 mapped, 00000000 allocated, 00000002 max

   Dma verifier additional information:
   DeviceObject: 82f98690
   Map registers:        00000840 allocated, 00000000 freed
   Scatter-gather lists: 00000000 allocated, 00000000 freed
   Common buffers:       00000004 allocated, 00000000 freed
   Adapter channels:     00000420 allocated, 00000420 freed
   Bytes mapped since last flush: 000000f2

第一块数据是HAL开发者可以用来调试问题的特定数据。对于自己的情况,"Dma verifier additional information"下面才是感兴趣的数据。在这个例子中,可以看到NDIS分配了0x840个映射记录( map registers)。 这是一个很大的数字,特别是因为NDIS指出了它只需要使用最多2个映射记录。该适配器显然没有用到分散/聚合列表(scatter/gather lists),并且释放了(put away)它所有的adapter channel。查看映射寄存记录更详细的信息:

0:kd> !dma  82f06cd0 2
Adapter: 82f06cd0     Owner: NDIS!NdisMAllocateMapRegisters 
...

  Map register file 82f06c58 (0/2 mapped)
     Double buffer mdl: 82f2c188
     Map registers:
        82f06c80: Not mapped
        82f06c8c: Not mapped

  Map register file 82f06228 (1/2 mapped)
     Double buffer mdl: 82f1b678
     Map registers:
        82f06250: 00bc bytes mapped to f83c003c
        82f0625c: Not mapped

  Map register file 82fa5ad8 (1/2 mapped)
     Double buffer mdl: 82f1b048
     Map registers:
        82fa5b00: 0036 bytes mapped to 82d17102
        82fa5b0c: Not mapped
...

例中,可以看到特定的映射记录已经被映射了。每个map register file是驱动分配的一个映射记录。即,它对应于一次AllocateAdapterChannel调用。当一些驱动在需要时每次创建一个,并且用完之后又释放掉的情况下,NDIS搜集了大量的这种映射记录文件(map register file)。

映射记录文件也是以"MapRegisterBase"为名字返回给设备的地址。注意DMA验证器仅hook每个驱动的前64个映射记录(map register)。剩下的由于空间原因被忽略掉(每个映射记录对应三个物理页面)。

这个例子中,有两个映射记录文件正在被使用。这意味着驱动已经映射了对硬件可见的缓冲区。对第一个来说,有 0xBC个字节映射到了系统虚拟地址 0xF83C003C。

下面是对公共缓冲区的查看:

0:kd> !dma  82f06cd0 4
Adapter: 82f06cd0     Owner: NDIS!NdisMAllocateMapRegisters 
...
   Common buffer allocated by NDIS!NdisMAllocateSharedMemory:
      Length:           1000
      Virtual address:  82e77000
      Physical address: 2a77000

   Common buffer allocated by NDIS!NdisMAllocateSharedMemory:
      Length:           12010
      Virtual address:  82e817f8
      Physical address: 2a817f8

   Common buffer allocated by NDIS!NdisMAllocateSharedMemory:
      Length:           4300
      Virtual address:  82e95680
      Physical address: 2a95680

   Common buffer allocated by NDIS!NdisMAllocateSharedMemory:
      Length:           4800
      Virtual address:  82e9d400
      Physical address: 2a9d400

这里是比较清楚直接,有四个不同长度的公共缓冲区。物理地址和虚拟地址也显示出来了。

附加信息

关于驱动程序验证器的更多信息,查看Windows Driver Kit (WDK) 文档。关于DMA的信息,查看Windows Driver Kit (WDK) 文档以及Mark Russinovich 和David Solomon 编写的Microsoft Windows Internals

Build machine: CAPEBUILD