如下,在代码中定义了三设备 A下面有B,驱动枚举到C设备的时候,怎么获取它父设备的资源呢?
13条回答 默认 最新
关注引自免费微信小程序:皆我百晓生
在您的KMDF驱动程序中,要访问嵌套设备
C的父设备B的ACPI资源(包括OperationRegion、Field、IndexField以及_B_/_ADR),您可以遵循以下步骤:-
识别设备层次结构: 使用WDF设备对象(WDFDEVICE)表示设备
C。通过调用WdfIoTargetGetParent函数,可以获取设备C的父设备B对应的WDFDEVICE对象。WDFDEVICE wdfDeviceC = ...; // 设备C的WDFDEVICE对象 WDFDEVICE wdfDeviceB; NTSTATUS status = WdfIoTargetGetParent(wdfDeviceC, &wdfDeviceB); if (!NT_SUCCESS(status)) { // 处理错误 } -
查询ACPI资源: 对于设备
B,利用WdfFdoQueryForResources函数查询其ACPI资源。这里主要关注CM_RESOURCE_TYPE_IO类型的资源,它们可能对应您定义的SystemIO OperationRegion。ULONG resourceCount; CM_RESOURCE_LIST* resourceList; status = WdfFdoQueryForResources(wdfDeviceB, CM_RESOURCE_TYPE_IO, WDF_NO_QUERY_CONDITION, &resourceCount, &resourceList); if (!NT_SUCCESS(status)) { // 处理错误 } for (ULONG i = 0; i < resourceCount; ++i) { PCM_PARTIAL_RESOURCE_DESCRIPTOR partialResource = &resourceList->List[i].PartialResourceList.PartialDescriptors[0]; if (partialResource->Type == CmResourceTypePort) { // 分析并使用此I/O端口资源 } } // 释放资源列表 ExFreePool(resourceList); -
解析OperationRegion、Field和IndexField: 直接从Windows驱动程序中访问这些ACPI定义的数据结构并不直观。通常情况下,操作系统在加载ACPI表时已经处理了这些信息,并将其映射到实际的硬件资源上。因此,您在第2步中查询到的I/O端口资源很可能就是
NXOperationRegion的实际地址范围。如果确实需要根据ACPI描述符进行精细操作(例如,直接访问
R07H字段),则可能需要编写自定义内核模式代码来解析ACPI表,但这通常是不必要的。若必须这样做,请查阅ACPI规范及相关的开源实现(如Linux kernel中的acpi-parser模块)以了解如何解析OperationRegion、Field和IndexField。 -
访问_B_/_ADR: 若要访问设备
B的_ADR方法(即_ADD标识符在您的示例中),可使用AcpiOsReadMemory等API(需自行实现或使用第三方库)执行ACPI方法调用。然而,对于大多数应用场景,直接查询设备对象的硬件资源(如上述I/O端口资源)更为合适。
总结来说,您可以通过WDF提供的接口获取设备
C的父设备B的I/O端口资源,并将其用于与硬件交互。至于直接访问ACPI定义的OperationRegion、Field和IndexField,除非有特殊需求,否则不推荐在Windows驱动程序中这样做。通常情况下,操作系统已经将这些抽象描述转换为实际的硬件资源供驱动程序使用。如果您确实需要访问_ADD方法,可以考虑使用ACPI API进行方法调用。但请注意,这一步骤通常不是必需的,且可能需要额外的工作来实现对ACPI表的解析和方法调用支持。解决 无用评论 打赏 举报 编辑记录-