Win10 Storport DmaRemappingCompatible 阻塞问题调试记录
日期: 2026-03-08
项目: Bayhub SD Host Controller Storport 驱动
目的: 调试 Bayhub 驱动在 Win10 上因 DmaRemappingCompatible 导致安装卡死的问题
适用: Windows 10 + Kernel DMA Protection + Storport Miniport
目录
PART 1:驱动分析
PART 2:调试过程记录
- 1.4.1 阶段一:DIFx 日志对比分析
- 1.4.2 阶段二:添加超时机制解决安装 Hang
- 1.4.3 阶段三:WinDbg 日志确认 API 失败
- 1.4.4 阶段四:改用 StorPortAllocateDmaMemory API
- 1.4.5 调试流程总结
- 1.4.6 调试结果分析
- 1.4.7 阶段五:检查 MapBuffers 设置
- 1.4.8 阶段六:MapBuffers 修改无效,确认 Storport 框架问题
- 1.4.9 阶段七:DmaRemappingCompatible=2 测试
- 1.4.10 阶段八:Win10 vs Win11 日志对比分析
- 1.4.12 阶段九:IRP_MN_START_DEVICE 深入分析
- 1.4.11 阶段十:最终结论
PART 3:调试方法
- 2.1 启用 DIFx 日志
- 2.2 启用 Storport 驱动日志
- 2.3 内核调试 (Kernel Debugging)
- 2.4 ETW 跟踪
- 2.5 Process Monitor 监控
- 2.6 检查 ACPI/DMAR 表
- 推荐调试顺序
- WinDbg 关键断点脚本
PART 1:驱动分析
1.1 卡死时机分析
1.1.1 结论更新(基于 Win10/Win11 日志对比)
| 分析角度 | 最初假设 | 日志验证结论 |
|---|---|---|
| 卡死时机 | 安装阶段,驱动代码不执行 | 驱动代码执行,卡死在 PnP Start: 之后 |
| 卡死阶段 | AddService 阶段 | DriverEntry 加载后 |
| 日志表现 | - | Win10 日志在 Start: 后中断,乱码 |
| 根因位置 | Storport 框架 | Storport 框架或驱动的 DMA 初始化 |
1.1.2 日志对比分析
Win10 日志(卡住)
1 | 11:20:45.955 {Restarting Devices} 11:20:45.955 |
关键发现:
- 日志在
Start:之后完全中断 - 之后是乱码,说明系统已卡死或崩溃
- 驱动代码已执行(因为进入了
Start阶段)
Win11 日志(正常)
1 | 19:55:15.259 Install Device: Starting device 'PCI\VEN_1217&DEV_9860...' |
关键发现:
Starting device和completed在同一毫秒完成(0ms 耗时)- 问题代码
0x37是CM_PROB_CONSOLE_LOCKED(会话锁定),不是驱动问题 - Win11 驱动加载/初始化快速完成
1.1.3 时序对比图
1 | Win10 Win11 |
1.1.4 结论
确认:驱动代码会执行,卡死发生在驱动加载的 DMA 缓冲区分配阶段。
1.2 驱动中潜在的卡死点
基于 Win10/Win11 日志对比,确认卡死发生在驱动加载阶段。
1.2.1 驱动加载时序图
1 | PnP Manager (Start:) |
1.2.2 验证方案
方案 1:在 os_alloc_dma_buffer 入口添加调试打印
目的:验证卡死确实在这个函数内部
修改文件:SDSTORDriver/sdstor/windows_os/winapi.c
1 | bool os_alloc_dma_buffer(void * pdx, void * ctx, u32 nbytes, dma_desc_buf_t * pdma) |
预期结果:
- 如果打印了
Enter os_alloc_dma_buffer但没有GetUncachedExtension() returned NULL/succeeded→ 确认卡死在GetUncachedExtension调用中 - 如果连
Enter都没有打印 → 卡死在os_alloc_dma_buffer之前
1.2.3 StorPortGetUncachedExtension 与 Win10 DMAR 兼容性分析
问题背景
当 INF 中设置 DmaRemappingCompatible=1 时,Storport 框架会以 DMA Remapping 兼容模式 初始化 DMA 子系统。
Win10 vs Win11 差异
| 方面 | Win10 | Win11 |
|---|---|---|
| Storport 版本 | 较旧 (19041+) | 较新 (22000+) |
| DMA Remapping 框架 | 2018-2020 版本 | 2021+ 版本 |
GetUncachedExtension 行为 |
可能同步阻塞 | 异步处理 |
| IOMMU 超时机制 | 可能不完善 | 已修复 |
可能的卡死原因
1 | DmaRemappingCompatible=1 |
验证方法
方法 A:检查 Win10 Storport 版本
1 | # 查看 storport.sys 版本 |
方法 B:检查 DMA remapping 状态
1 | # 在 WinDbg 中检查 |
方法 C:临时禁用 DmaRemappingCompatible 测试
修改 INF 文件:
1 | ; 原始设置 |
如果禁用后安装正常 → 确认是 DmaRemappingCompatible 相关问题
1.2.4 潜在卡死点详细分析
卡死点 A:os_alloc_dma_buffer 中的 StorPortGetUncachedExtension(高优先级)
文件位置:SDSTORDriver/sdstor/windows_os/winapi.c:2004-2030
代码:
1 | bool os_alloc_dma_buffer(void * pdx, void * ctx, u32 nbytes, dma_desc_buf_t * pdma) |
卡死原因:
- 当 INF 声明了
DmaRemappingCompatible=1 StorPortGetUncachedExtension尝试分配符合 IOMMU/DMAR 要求的缓冲区- 在 Win10 上,这个过程可能触发同步等待(等待 IOMMU/DMAR 表解析)
- 如果 IOMMU 无响应或超时机制不完善 → 整个调用卡死
卡死点 B:StorHwPassiveInitialize 中的 PowerFx 初始化(中优先级)
文件位置:SDSTORDriver/sdstor/windows_os/winscsientry.c:370-453
1 | BOOLEAN StorHwPassiveInitialize(IN PVOID DeviceExtension) |
卡死原因分析:
StorPortInitializePoFxPower是 Power Management Framework 初始化- 在 Win10 上可能与 DMA remapping 初始化有依赖关系
- 如果 DMA remapping 初始化未完成,PowerFx 可能等待
卡死点 C:Storport 框架的 DMA Remapping 初始化(根本原因)
这是最可能的根因位置
1 | bayhub 驱动声明 DmaRemappingCompatible=1 |
1.2.5 为什么 Win11 不卡死?
| 方面 | Win10 | Win11 |
|---|---|---|
| Storport 版本 | 较旧 (19041+) | 较新 (22000+) |
| DMA Remapping 框架 | 2018-2020 版本 | 2021+ 版本 |
GetUncachedExtension 行为 |
可能同步阻塞 | 异步处理 |
| IOMMU 超时机制 | 可能不完善 | 已修复 |
| IOMMU 集成 | 松散耦合 | 紧密集成 |
1.2.6 建议的调试方向
步骤1:添加调试打印(最优先)
在 os_alloc_dma_buffer 函数入口添加调试打印,验证卡死位置:
1 | bool os_alloc_dma_buffer(void * pdx, void * ctx, u32 nbytes, dma_desc_buf_t * pdma) |
验证结果:
- 如果打印了
Enter但没有后续日志 → 确认卡死在函数内部 - 如果连
Enter都没有 → 卡死在更早的位置
步骤2:临时禁用 DmaRemappingCompatible
修改 INF 文件,临时禁用:
1 | ; 临时禁用 |
如果禁用后安装正常 → 确认是 DmaRemappingCompatible 相关问题
步骤3:使用 WinDbg 内核调试
在 WinDbg 中设置断点:
1 | bp bhtsddr!os_alloc_dma_buffer "kv; g" |
1.3 代码位置速查表
1.3.1 驱动加载相关函数
| 函数名 | 文件:行号 | 功能 | 卡死风险 |
|---|---|---|---|
DriverEntry |
winscsientry.c:2675 |
驱动入口点 | 低 |
scsi_HwFindAdapter |
winscsientry.c:989 |
适配器查找和初始化 | 高 |
os_alloc_dma_buffer |
winapi.c:2004 |
DMA缓冲区分配 | 最高 |
StorHwPassiveInitialize |
winscsientry.c:370 |
被动初始化回调 | 中 |
scsi_HwInitialize |
winscsientry.c:488 |
硬件初始化 | 低 |
1.3.2 DMA 相关 API
| API | 说明 | 与DMAR的关系 |
|---|---|---|
StorPortGetUncachedExtension |
分配公共缓冲区 | 关键:在DMAR环境下分配符合要求的缓冲区 |
StorPortAllocateDmaMemory |
分配DMA内存 | 返回IOVA而非PA |
StorPortMapDmaTransfer |
DMA映射传输 | 使用IOVA |
StorPortGetD3ColdSupport |
查询D3Cold支持 | 可能与DMAR交互 |
StorPortInitializePoFxPower |
PowerFx初始化 | 可能与DMAR有依赖 |
1.3.3 关键代码片段
关键点1:Dma64BitAddresses 配置 (winscsientry.c:1133-1148)
1 | if(SCSI_DMA64_SYSTEM_SUPPORTED == ConfigInfo->Dma64BitAddresses && |
关键点2:MapBuffers 配置 (winscsientry.c:1255-1288)
原始逻辑(已修改):
1 | if(FALSE == cfg_dma_need_sdma_like_buffer(pdev_ext->cfg->host_item.test_dma_mode_setting.dma_mode)) |
修改后逻辑(2026-03-19):
- 在 DMA remapping 模式下(
DmaRemappingCompatible=1或2),强制使用STOR_MAP_NON_READ_WRITE_BUFFERS - 与 StorAHCI 示例驱动行为一致
- 可能解决 Win10 上的
STATUS_INSUFFICIENT_RESOURCES问题
1.4 调试过程记录(2026-03-19)
1.4.1 阶段一:DIFx 日志对比分析
时间:2026-03-19 初始分析
方法:对比 Win10 和 Win11 的 setupapi.dev.log 安装日志
发现:
- Win10 日志:在
Start: PCI\VEN_1217&DEV_9860...之后日志中断,出现乱码,系统卡死 - Win11 日志:
Starting device和completed在同一毫秒完成(0ms),问题代码为CM_PROB_CONSOLE_LOCKED(会话锁定,非驱动问题)
结论:
- ✅ 确认卡死发生在驱动加载后(
Start:阶段之后) - ✅ 驱动代码确实在执行(
DriverEntry→scsi_HwFindAdapter→os_alloc_dma_buffer) - ✅ 卡死发生在 DMA 缓冲区分配阶段
相关文件:
setupapi-win10.dev.log:Win10 卡死日志setupapi-win11.dev.log:Win11 正常安装日志
1.4.2 阶段二:添加超时机制解决安装 Hang
时间:2026-03-19
问题:scsi_HwFindAdapter 中的 while(1) 循环在 DMA 分配失败时导致无限循环,系统卡死
修改:
文件:
SDSTORDriver/sdstor/windows_os/winscsientry.c- 将
while(1)改为for(;;)循环 - 添加 10 秒总超时机制(使用
util_init_waitloop和util_is_timeout) - 在每次
os_alloc_dma_buffer调用前检查超时
- 将
文件:
SDSTORDriver/sdstor/windows_os/winapi.c- 简化
os_alloc_dma_buffer,移除内部 30 秒超时(由外层统一管理)
- 简化
代码变更:
1 | // winscsientry.c: 添加超时控制 |
结果:
- ✅ 解决了安装过程中的系统卡死问题
- ✅ 驱动在 10 秒超时后优雅失败,不再 hang 系统
- ⚠️ 但设备仍无法启动(DMA 分配失败)
1.4.3 阶段三:WinDbg 日志确认 API 失败
时间:2026-03-19
方法:使用 WinDbg 内核调试器抓取驱动加载日志
关键发现(WinDbg 日志片段):
1 | 行 594: BHT-OSAPI : [DMA_ALLOC] Attempt 1/10, calling StorPortGetUncachedExtension(0x113eaa0)... |
关键观察:
- ✅
StorPortGetUncachedExtension立即返回 NULL(非阻塞) - ✅ 每次失败后触发 PnP
IRP_MN_QUERY_INTERFACE查询 - ✅ 重试 9 次后,
buf_size减半继续尝试(113eaa0 → 8b2d50 → 46cea8 → 249f54…) - ✅ 所有尝试均失败,直到 10 秒超时
- ✅ 重启后设备无法启动,显示错误代码 10(系统资源不足)
结论:
- ❌
StorPortGetUncachedExtension在 Win10 + DMAR compatible 环境下无法工作 - ❌ API 立即返回 NULL,不是阻塞问题,而是不兼容 Win10 DMAR 模式
- ✅ 之前的
while(1)没有超时导致安装 hang 问题已解决 - ⚠️ 根因:需要改用其他 Storport DMA 分配 API
设备管理器错误:
- 错误代码:10(
STATUS_INSUFFICIENT_RESOURCES) - 错误信息:”该设备无法启动。系统资源不够,无法完成 API。”
1.4.4 阶段四:改用 StorPortAllocateDmaMemory API
时间:2026-03-19
问题根因:
StorPortGetUncachedExtension在 Win10 DMAR 环境下不兼容- 需要改用 Microsoft 推荐的 DMA remapping 兼容 API
解决方案:
参考 Microsoft StorAHCI 示例驱动(Windows-driver-samples/storage/miniports/storahci/src/common.h),使用 StorPortAllocateDmaMemory API。
API 对比:
| API | 说明 | Win10 DMAR 兼容性 | 返回值 |
|---|---|---|---|
StorPortGetUncachedExtension |
旧式 DMA 缓冲区分配 | ❌ 不兼容(立即返回 NULL) | 虚拟地址 |
StorPortAllocateDmaMemory |
Microsoft 推荐的 DMAR API | ✅ 兼容 | 虚拟地址 + IOVA |
关键差异:
StorPortGetUncachedExtension:返回物理地址(PA),在 DMAR 环境下不适用StorPortAllocateDmaMemory:返回 IOVA(IO Virtual Address),专为 DMA remapping 设计
代码修改:
文件:
SDSTORDriver/sdstor/windows_os/winapi.c- 修改
os_alloc_dma_buffer:使用BhtAllocateDmaBuffer(内部调用StorPortAllocateDmaMemory)替代StorPortGetUncachedExtension - 修改
os_free_dma_buffer:使用BhtFreeDmaBuffer(内部调用StorPortFreeDmaMemory)释放内存
- 修改
已有函数:
BhtAllocateDmaBuffer(winapi.c:4096):已实现,基于 StorAHCI 模式BhtFreeDmaBuffer(winapi.c:4148):已实现,基于 StorAHCI 模式
修改后的 os_alloc_dma_buffer 逻辑:
1 | bool os_alloc_dma_buffer(void * pdx, void * ctx, u32 nbytes, dma_desc_buf_t * pdma) |
预期效果:
- ✅
StorPortAllocateDmaMemory在 Win10 DMAR 环境下应能正常工作 - ✅ 返回的地址是 IOVA,符合 DMA remapping 要求
- ✅ 设备应能正常启动
下一步调试:
- 重新编译驱动并测试
- 使用 WinDbg 验证
StorPortAllocateDmaMemory是否成功 - 检查设备是否能正常启动
1.4.5 调试流程总结
1 | 阶段一:DIFx 日志对比 |
1.4.6 调试结果分析(2026-03-20)
WinDbg 日志关键发现
DMA 分配成功(✅):
1 | 行 264: BHT-ERROR : DMAR_DIAG: BhtAllocateDmaBuffer: VA=FFFFEF7B80C00000 IOVA=0x000000007224B000 len=18082464 |
驱动初始化完成(✅):
1 | 行 905: BHT-OSENTRY: Exit StorHwPassiveInitialize |
PnP START_DEVICE 失败(❌):
1 | 行 2911: BHT-OSENTRY: Exit BHTDispatchPnp, status=0xC000009A |
设备被移除:
1 | 行 2913: BHT-OSENTRY: Enter BHTDispatchPnp - MinorFunction: (IRP_MN_REMOVE_DEVICE) |
状态码分析
| 状态码 | 含义 | 来源 |
|---|---|---|
0xC000009A |
STATUS_INSUFFICIENT_RESOURCES |
Storport 框架返回 |
| Code 10 | “该设备无法启动。系统资源不够,无法完成 API。” | 设备管理器 |
问题根因分析
1 | Win10 测试系统(无 IOMMU): |
Win10 系统 IOMMU 状态验证
更正:通过 msinfo32 确认 Kernel DMA Protection 已启用,说明:
- ✅ IOMMU 硬件存在且已启用
- ✅ BIOS 已正确配置 VT-d/IOMMU
- ✅ Windows 已检测到并启用了 Kernel DMA Protection
因此,问题不是 IOMMU 不存在,而是其他原因。
可能的问题根因
| 可能原因 | 说明 | 可能性 |
|---|---|---|
| Win10 Storport 版本问题 | Win10 (19041) Storport 对 DMA remapping 支持不完善,在验证/使用 IOVA 时失败 | ✅ 高 |
| IOVA 地址范围限制 | 虽然 IOVA 在 2GB 范围内(0x7224B000),但 Storport 可能对某些地址范围有特殊要求 | 中 |
| DMA 缓冲区配置 | 缓冲区大小、对齐或缓存类型可能不符合 Storport 在 Win10 上的要求 | 中 |
| Storport 框架 Bug | Win10 Storport 在处理 DMA remapping 兼容驱动时的已知 bug | 中 |
关键发现
从日志分析:
- DMA 分配成功:
BhtAllocateDmaBuffer成功返回 IOVA=0x7224B000 - 驱动初始化完成:所有驱动初始化步骤成功
- Storport 框架返回错误:
Exit BHTDispatchPnp, status=0xC000009A(不是驱动代码返回的)
结论:驱动代码已正确实现(使用 StorPortAllocateDmaMemory),但 Win10 Storport 框架在处理 DMA remapping 时返回 STATUS_INSUFFICIENT_RESOURCES。
验证步骤
检查测试系统是否有 IOMMU:
1
2
3
4
5
6
7# 检查系统信息
msinfo32.exe
# 查找 "IOMMU" 或 "VT-d" 或 "AMD-Vi"
# 或在 WinDbg 中
!amddeviceinfo # AMD
!intelinfo # Intel检查 BIOS 设置:
- 进入 BIOS/UEFI
- 查找 “Intel VT-d” 或 “AMD-Vi” 或 “IOMMU”
- 确保已启用
尝试禁用 DmaRemappingCompatible 测试:
1
2; 在 INF 中临时禁用
HKLM,...\Parameters\DmaRemappingCompatible = 0x00010001 ; DWORD = 0重要发现:根据 Microsoft 官方文档,
DmaRemappingCompatible值含义:值 含义 Windows 10 支持 0 Opt-out ✅ 1 Opt-in (完全) ⚠️ 可能导致问题 2 Opt-in,仅外部设备或 Driver Verifier ✅ 推荐 3 Opt-in (仅 Windows 11+) ❌ Windows 10 不支持 建议:先尝试
值=0(禁用),确认是否是 DmaRemappingCompatible 导致的问题。然后尝试值=2。尝试 DmaRemappingCompatible=2:
1
2; 值 2:在 Windows 10 上更安全
HKLM,...\Parameters\DmaRemappingCompatible = 0x00010001 ; DWORD = 2使用原生 Win10 系统测试:
- 使用 OEM 台式机或笔记本(通常有 IOMMU)
- 或使用支持 VT-d 的服务器系统
总结
| 调试阶段 | 结果 | 说明 |
|---|---|---|
| 阶段一: DIFx 日志对比 | ✅ 完成 | 确认卡死发生在驱动加载后 |
| 阶段二:添加超时机制 | ✅ 完成 | 解决了安装 hang 问题 |
| 阶段三:WinDbg 日志分析 | ✅ 完成 | 确认 StorPortGetUncachedExtension 在 Win10 DMAR 下失败 |
| 阶段四:改用 StorPortAllocateDmaMemory | ✅ 完成 | DMA 分配成功,但 START_DEVICE 失败 |
| 阶段五:验证 IOMMU 状态 | ✅ 完成 | 确认 Kernel DMA Protection 已启用,IOMMU 存在 |
| 阶段六:检查 MapBuffers 设置 | ✅ 完成 | 在 DMA remapping 模式下强制使用 STOR_MAP_NON_READ_WRITE_BUFFERS |
| 阶段七:MapBuffers 修改无效 | ❌ 失败 | 修改 MapBuffers 后仍出现 Code 10,重启时失败 |
| 阶段八:DmaRemappingCompatible=2 测试 | ❌ 失败 | 同样返回 status=0xC000009A |
| 阶段九:Win10 vs Win11 日志对比 | ✅ 完成 | 确认问题在 Storport 框架,不是驱动代码 |
结论:
- ✅ 驱动代码已修复:使用
StorPortAllocateDmaMemory替代StorPortGetUncachedExtension - ✅ DMA 分配成功:
BhtAllocateDmaBuffer成功返回 IOVA=0x7223B000 - ✅ IOMMU 已启用:通过
msinfo32确认 Kernel DMA Protection 已启用 - ✅ Win10 vs Win11 对比:
- Win10:Storport 返回
status=0xC000009A,设备被移除 - Win11:Storport 返回
status=0x00000000,设备正常工作
- Win10:Storport 返回
- ❌ DmaRemappingCompatible=2 也失败:与值=1 一样,返回
status=0xC000009A - ❌ MapBuffers 修改无效:强制使用
STOR_MAP_NON_READ_WRITE_BUFFERS后问题依然存在 - ❌ BHTDispatchPnp 代码不是问题来源:
0xC000009A来自SavedDispatchPnp(Storport 框架)
根因确认:这是 Windows 10 Storport 框架在处理 DMA remapping 兼容驱动时的已知问题,不是驱动代码问题。
建议的下一步调试步骤:
- 尝试禁用 DmaRemappingCompatible(值=0):确认是否是 DMA remapping 导致的问题
- 尝试 DmaRemappingCompatible=2:仅在外部设备或 Driver Verifier 时启用,更安全
- 参考 Microsoft 文档:
StorPortAllocateDmaMemory是StorPortAllocateContiguousMemorySpecifyCacheNode的扩展版本,底层相同 - 使用 Driver Verifier 测试:Microsoft 文档建议在测试 DMA remapping 时启用 Driver Verifier
1.4.7 阶段五:检查 MapBuffers 设置(2026-03-19)
时间:2026-03-19
问题:在 DMA remapping 模式下,STOR_MAP_ALL_BUFFERS_INCLUDING_READ_WRITE 可能与 Storport 的 DMA remapping 处理冲突,导致 STATUS_INSUFFICIENT_RESOURCES。
分析:
StorAHCI 示例驱动行为:
- StorAHCI 使用
STOR_MAP_NON_READ_WRITE_BUFFERS - StorAHCI 未声明
DmaRemappingCompatible(使用默认值)
- StorAHCI 使用
当前驱动行为:
- 根据 DMA 模式动态设置
MapBuffers:- 非 SDMA-like 模式:
STOR_MAP_NON_READ_WRITE_BUFFERS - SDMA-like 模式:
STOR_MAP_ALL_BUFFERS_INCLUDING_READ_WRITE
- 非 SDMA-like 模式:
- 在 DMA remapping 模式下,
STOR_MAP_ALL_BUFFERS_INCLUDING_READ_WRITE可能不兼容
- 根据 DMA 模式动态设置
问题根因假设:
STOR_MAP_ALL_BUFFERS_INCLUDING_READ_WRITE要求 Storport 为所有缓冲区(包括 READ/WRITE)提供虚拟地址映射- 在 DMA remapping 模式下,Storport 需要处理 IOVA 映射
- Win10 Storport 可能无法同时满足这两个要求,导致验证失败
修改:
在 winscsientry.c 的 scsi_HwFindAdapter 函数中,添加 DMA remapping 检测逻辑:
1 | // DMAR Fix: Check DmaRemappingCompatible setting |
代码位置:winscsientry.c:1255-1288
预期效果:
- 当
DmaRemappingCompatible=1或2时,强制使用STOR_MAP_NON_READ_WRITE_BUFFERS - 与 StorAHCI 示例驱动行为一致
- 可能解决 Win10 上的
STATUS_INSUFFICIENT_RESOURCES问题
测试结果(2026-03-19):
- ❌ 修改无效:强制使用
STOR_MAP_NON_READ_WRITE_BUFFERS后,问题依然存在 - 安装时:OK(不再 hang)
- 重启后:Code 10 错误,设备无法启动
- 日志显示:
Exit BHTDispatchPnp, status=0xC00000BB(STATUS_NOT_SUPPORTED)
结论:MapBuffers 设置不是根本原因,问题在于 Storport 框架本身。
1.4.8 阶段六:MapBuffers 修改无效,确认 Storport 框架问题(2026-03-19)
时间:2026-03-19
问题:修改 MapBuffers 设置后,问题依然存在。安装时 OK,但重启后出现 Code 10 错误。
测试结果:
| 测试项 | 结果 | 说明 |
|---|---|---|
| 安装时 | ✅ OK | 不再 hang,驱动安装成功 |
| 重启后 | ❌ Code 10 | 设备无法启动 |
| 错误码 | 0xC000009A |
STATUS_INSUFFICIENT_RESOURCES(Storport 框架返回) |
| 错误信息 | “Insufficient system resources exist to complete the API.” | 设备管理器显示 |
日志关键信息:
1 | Exit BHTDispatchPnp, status=0xC000009A |
结论:MapBuffers 设置不是根本原因,问题在于 Storport 框架本身。
1.4.9 阶段七:DmaRemappingCompatible=2 测试(2026-03-20)
时间:2026-03-20
问题:尝试 DmaRemappingCompatible=2(仅外部设备或 Driver Verifier 时兼容),看是否能解决问题。
测试结果:
| DmaRemappingCompatible 值 | Win10 结果 | 说明 |
|---|---|---|
| = 0 | 黄叹号 | 设备被策略拦截 |
| = 1 | ❌ Code 10 | status=0xC000009A |
| = 2 | ❌ Code 10 | status=0xC000009A |
结论:DmaRemappingCompatible=2 同样失败,问题不是值的选择,而是 Win10 Storport 框架本身。
1.4.10 阶段八:Win10 vs Win11 日志对比分析(2026-03-20)
时间:2026-03-20
问题:对比 Win10 和 Win11 的 DbgView 日志,确认问题根源。
测试环境:
- Win10:OS Version 10.0.19045
- Win11:OS Version 10.0.26200
Win10 失败日志关键序列:
1 | 行 2910: BHT-OSENTRY: Exit StorHwPassiveInitialize |
Win11 成功日志关键序列:
1 | 行 919: BHT-OSENTRY: Exit StorHwPassiveInitialize |
关键发现:
驱动初始化都成功:两边的
StorHwPassiveInitialize都正常退出DMA 分配都成功:
- Win10:
BhtAllocateDmaBuffer succeeded: IOVA=0x7223B000 - Win11:
BhtAllocateDmaBuffer succeeded: IOVA=0x720C8000
- Win10:
区别在于
IRP_MN_QUERY_INTERFACE处理:- Win10:第二次
QUERY_INTERFACE返回0xC000009A - Win11:所有
QUERY_INTERFACE都返回成功
- Win10:第二次
设备后续行为:
- Win10:设备被移除(
IRP_MN_REMOVE_DEVICE) - Win11:设备正常工作
- Win10:设备被移除(
BHTDispatchPnp 代码分析:
1 | // DispatchPnpAdapter 中的 IRP_MN_QUERY_INTERFACE 处理 |
1 | // BHTDispatchPnp 中返回实际状态 |
结论:
0xC000009A来自SavedDispatchPnp(Storport 框架),不是驱动代码返回的BHTDispatchPnp代码不处理IRP_MN_QUERY_INTERFACE,直接透传给下层驱动- 问题在于 Win10 Storport 框架在处理 DMA remapping 兼容驱动时返回
STATUS_INSUFFICIENT_RESOURCES - 驱动代码无需修改
1.4.12 阶段九:IRP_MN_START_DEVICE 深入分析(2026-03-19)
日期:2026-03-19
问题:进一步定位 0xC000009A 的来源
最新测试日志:
1 | 行 806: IRP_MN_START_DEVICE: Calling SavedDispatchPnp |
关键发现:
| MinorFunction | SavedDispatchPnp 返回值 | 含义 |
|---|---|---|
| IRP_MN_QUERY_INTERFACE (第1次) | 0xC00000BB | STATUS_NOT_SUPPORTED |
| IRP_MN_QUERY_INTERFACE (第2次) | 0xC00000BB | STATUS_NOT_SUPPORTED |
| IRP_MN_QUERY_INTERFACE (第3次) | 0x00000000 | STATUS_SUCCESS |
| IRP_MN_QUERY_INTERFACE (第4次) | 0x00000103 | STATUS_PENDING |
| IRP_MN_START_DEVICE | 0xC000009A | STATUS_INSUFFICIENT_RESOURCES |
错误码含义:
0xC000009A= STATUS_INSUFFICIENT_RESOURCES0xC00000BB= STATUS_NOT_SUPPORTED
根本原因:
IRP_MN_START_DEVICE 期间,Storport 返回 STATUS_INSUFFICIENT_RESOURCES,可能原因:
DMA Remapping 资源分配失败
- INF 中
DmaRemappingCompatible=1声明支持 DMA remapping - 但平台 IOMMU 未正确配置或不支持该设备
- Storport 无法分配 DMA 映射资源
- INF 中
INF 配置状态:
1
2[DmaRemappingCompatible_AddReg]
HKR,Parameters,DmaRemappingCompatible,0x00010001,1 ; 当前值 = 1
解决方案:
方案 1:禁用 DMA Remapping 兼容性(测试用)
1 | [DmaRemappingCompatible_AddReg] |
方案 2:驱动层捕获并覆盖错误
在 BHTDispatchPnp 中添加 IRP_MN_START_DEVICE 专门处理:
1 | else if (DeviceType == FILE_DEVICE_CONTROLLER && MinorFuncIndex == IRP_MN_START_DEVICE) |
注意:驱动已实现方案 2,但问题仍然存在,说明问题可能不在驱动层。
1.4.11 阶段十:最终结论(2026-03-20)
问题根源:Windows 10 Storport 框架的已知问题/限制
证据链:
- ✅ 驱动代码正确(使用
StorPortAllocateDmaMemory) - ✅ DMA 分配成功(IOVA 正确返回)
- ✅ IOMMU 已启用(Kernel DMA Protection 已启用)
- ✅
MapBuffers设置正确(强制STOR_MAP_NON_READ_WRITE_BUFFERS) - ❌
DmaRemappingCompatible=1和=2都失败 - ❌ Win10 Storport 返回
STATUS_INSUFFICIENT_RESOURCES (0xC000009A) - ✅ Win11 Storport 正常工作
不是驱动代码问题的证据:
BHTDispatchPnp不处理IRP_MN_QUERY_INTERFACE0xC000009A(资源不可获取)来自SavedDispatchPnp(Storport 框架)处理IRP_MN_START_DEVICE返回- 所有驱动级别的初始化都成功
- Win11 相同代码正常工作
建议的下一步:
- 不修改miniport部分驱动代码(问题不在这里,在框架层storport)
- 向 Microsoft 报告此问题(使用
20260319_Microsoft_Storport_DMAR_Issue_Report.md) - 考虑条件安装:Win10 使用不同的 INF 配置,禁用DmaRemappingCompatible,Group Policy如果开启Enumeration policy,需选择Allow all避免Yellow-bang黄标
PART 2:调试方法
方法 1:启用 Driver Install Framework (DIFx) 日志
DIFx 是 Windows 处理驱动安装的组件,开启详细日志可以看到安装过程中每一步的状态。
1.1 启用 DIFx 日志
1 | # 方法 A:设置全局 DIFx 日志 |
1.2 查看安装日志
1 | # 找到 setupapi 日志 |
1.3 日志内容解读
日志中搜索关键字:
1 | >>> [InstallHInfSection] |
观察:
- 哪个 AddReg 最后执行
- 是否有错误代码
- 卡在哪一步
方法 2:启用 Storport 驱动日志
Storport.sys 有内置的跟踪功能。
2.1 启用 Storport 日志
1 | # 启用 Storport 日志(需要管理员权限) |
2.2 使用 tracelog 捕获
1 | # 创建跟踪会话 |
2.3 查看事件日志
1 | # 打开事件查看器并导航到 |
方法 3:内核调试 (Kernel Debugging)
这是最有效的方法,可以观察到卡死的具体位置和调用栈。
3.1 设置双机调试环境
目标机 (Win10) 设置
1 | # 启用调试模式 |
主机 (WinDbg) 设置
1 | # 串口连接 |
3.2 加载符号
1 | // WinDbg 中设置符号路径 |
3.3 关键断点位置
注册表读取相关
1 | // DmaRemappingCompatible 被读取 |
DMA Remapping 初始化
1 | // DMA setup 入口 |
PnP 安装相关
1 | // PnP 处理程序 |
可能阻塞的位置
1 | // 等待相关 |
DMAR/IOMMU 相关
1 | // DMA remapping 设备 |
3.4 诊断命令
查看卡住的线程和进程
1 | // 查看所有进程 |
查看 IRP
1 | // 查看挂起的 IRP |
查看 DMA 信息
1 | // DMA 相关 IOCTL |
3.5 使用脚本自动设置断点
创建一个 storport_debug.txt 文件:
1 | .echo ======================================== |
在 WinDbg 中加载:
1 | $$>a< storport_debug.txt |
方法 4:ETW 跟踪
使用 Windows 事件跟踪 (ETW) 捕获详细的安装过程。
4.1 使用 tracelog
1 | # 创建 ETW 跟踪会话 |
4.2 使用 WPR (Windows Performance Recorder)
1 | # 使用 WPR 捕获 |
4.3 分析 ETW 跟踪
1 | # 使用 tracerpt 转换 |
4.4 使用 TraceView
1 | # 打开 TraceView |
方法 5:Process Monitor 监控 INF 处理
使用 Process Monitor 监控注册表和文件操作。
5.1 下载和设置
- 下载 Process Monitor
- 以管理员身份运行
5.2 过滤器设置
设置以下过滤器:
| 过滤器类型 | 条件 | 值 |
|---|---|---|
| Process Name | is | pnputil.exe |
| Operation | begins with | Registry |
| 或 | ||
| Operation | begins with | File |
5.3 观察要点
最后写入的注册表键
- 查找
DmaRemappingCompatible相关键 - 找到最后成功完成的操作
- 查找
挂起的操作
- 是否有状态为 “Pending” 或 “Timeout” 的操作
- 查找长时间无响应的注册表查询
循环等待
- 是否反复查询同一键
- 是否有 “Name Not Found” 后重试
5.4 导出日志
1 | File > Export > CSV |
方法 6:检查 Storport 与 ACPI/DMAR 表的交互
问题可能出在 Storport 查询 DMAR 表时的超时。
6.1 检查 DMAR 表
1 | # 使用 RWEverything 查看 ACPI 表 |
6.2 查看 ACPI 表内容
1 | # 查看 DMAR 表 |
6.3 WinDbg 中检查 DMA remapping 状态
1 | // 检查 IOMMU 状态 |
6.4 检查 _DMA 方法
1 | # 使用 ACPI_INFO 或 DeviceTree 工具 |
推荐调试顺序
| 顺序 | 方法 | 难度 | 能获得的信息 |
|---|---|---|---|
| 1 | DIFx 日志 | 低 | 安装卡在哪一步 |
| 2 | Process Monitor | 低 | 注册表操作卡在哪 |
| 3 | ETW 跟踪 | 中 | Storport 内部的调用序列 |
| 4 | Storport 日志 | 中 | 驱动级别的详细信息 |
| 5 | 内核调试 (WinDbg) | 高 | 最详细信息:调用栈、阻塞位置 |
常见问题排查清单
安装阶段卡死
- DIFx 日志是否记录到最后一步
- Process Monitor 显示最后访问的注册表键
- 断点是否命中
内核调试无响应
- 串口连接是否正常
- 波特率是否匹配
- 目标机是否正确进入调试模式
符号加载失败
- 网络连接是否正常
- 尝试使用本地缓存
- 使用
.symfix和.reload
ETW 跟踪为空
- 检查 Provider GUID 是否正确
- 使用
logman query -ets查看活动会话 - 确认管理员权限
获取帮助
相关文档
工具下载
| 工具 | 下载链接 |
|---|---|
| WinDbg | Windows SDK |
| Process Monitor | Sysinternals |
| WPR/WPA | Windows Assessment and Deployment Kit (ADK) |
文档生成: 2026-03-19
适用版本: Windows 10 (所有版本)