SCSIPeripheralsDriverKit中IOUserSCSIPeripheralDeviceType00方法返回kIOReturnUnsupported问题
DriverKit IOUserSCSIPeripheralDeviceType00所有方法返回kIOReturnUnsupported问题
问题描述
我有一个可正常运行的KEXT,以IOSCSIPeripheralDeviceNub作为提供者,能够向SCSI外设类型0设备发送SCSI厂商命令。现在正在迁移至DriverKit,采用SCSIPeripheralsDriverKit框架下的IOUserSCSIPeripheralDeviceType00类(该类方法与IOKit中的对应类类似,且官方有相关迁移参考建议)。
目前驱动已成功匹配并加载到目标nub——可通过IORegistryExplorer和systemextensionsctl list命令验证,但调用该类下的所有方法(包括尝试发送标准INQUIRY命令、自定义厂商特定CDB)均返回kIOReturnUnsupported(0xe00002c7)。
请问是否有人成功使用该框架向外设类型0设备发送SCSI命令?
附相关代码/配置片段
匹配用Info.plist片段
<key>IOResources</key> <dict> <key>IOClass</key> <string>IOUserSCSIPeripheralDeviceType00</string> <key>IOProviderClass</key> <string>IOSCSIPeripheralDeviceNub</string> <key>IOMatchCategory</key> <string>com.apple.scsi.peripheral-device-type-00</string> <key>IOVendorMatch</key> <string>0x1234</string> <key>IOProductMatch</key> <string>0x5678</string> </dict>
驱动初始化及发送INQUIRY命令的代码片段
#include <DriverKit/IOUserSCSIPeripheralDeviceType00.h> #include <DriverKit/IOBufferMemoryDescriptor.h> class MySCSIDriver : public IOUserSCSIPeripheralDeviceType00 { OSDeclareDefaultStructors(MySCSIDriver); public: bool init() override { if (!super::init()) return false; return true; } void free() override { super::free(); } kern_return_t Start(IOService* provider) override { kern_return_t ret = super::Start(provider); if (ret != KERN_SUCCESS) return ret; // 尝试发送INQUIRY命令 uint8_t cdb[6] = {0x12, 0x00, 0x00, 0x00, 0x20, 0x00}; auto buffer = IOBufferMemoryDescriptor::Create(kIOMemoryDirectionIn, 32, 0); if (!buffer) return KERN_FAILURE; ret = this->SendSCSICommand(cdb, sizeof(cdb), buffer, nullptr, nullptr, 0); OSLog(OSLogDefault, "Send INQUIRY returned: 0x%x", ret); // 输出0xe00002c7 buffer->release(); return ret; } kern_return_t Stop(IOService* provider) override { return super::Stop(provider); } }; OSDefineMetaClassAndStructors(MySCSIDriver, IOUserSCSIPeripheralDeviceType00);
解决方向与验证要点
权限与系统扩展配置检查
- 确保
Info.plist中添加com.apple.security.device.scsi权限,且签名时包含对应的entitlement。 - 用
systemextensionsctl list确认驱动处于activated状态,而非仅registered。
- 确保
设备类型匹配验证
- 通过
IORegistryExplorer查看目标IOSCSIPeripheralDeviceNub的SCSIPeripheralType属性值是否为0。 - 确认
Info.plist中的IOMatchCategory严格设置为com.apple.scsi.peripheral-device-type-00。
- 通过
命令参数正确性
- 确保CDB的操作码、参数长度、数据方向与命令规范匹配(比如INQUIRY命令的缓冲区方向必须为
kIOMemoryDirectionIn)。 - 优先尝试同步命令发送方法(如
SendSCSICommandSync)排查,避免异步回调干扰问题定位。
- 确保CDB的操作码、参数长度、数据方向与命令规范匹配(比如INQUIRY命令的缓冲区方向必须为
框架与系统兼容性
- 确认DriverKit SDK版本与目标macOS版本匹配(
SCSIPeripheralsDriverKit仅在macOS 11+可用)。 - 查看系统日志:执行
log show --predicate 'subsystem == "com.apple.DriverKit"' --info获取驱动加载和命令执行的详细错误信息。
- 确认DriverKit SDK版本与目标macOS版本匹配(
初始化流程检查
- 确保在
Start方法中等待nub完全初始化后再发送命令,避免过早调用方法导致的不支持错误。
- 确保在
成功案例反馈
已有开发者成功实现该场景,核心要点包括:
- 系统扩展必须获得正确的SCSI设备访问权限,且在系统偏好设置中完成授权。
- 严格遵循SCSI命令规范构造CDB,参数无遗漏或错误。
- 确保驱动与nub建立了完整的通信通道,未跳过必要的初始化步骤。
内容的提问来源于stack exchange,提问作者abkmd
相关产品推荐
相关产品推荐

