USBInterfaceOpen 总是报 kIOReturnExclusiveAccess 错误

Fly*_*Man 5 usb kernel iokit kernel-extension

最近遇到这个问题很头疼,我已经在这个问题上花了一个星期,但还是失败了。希望你能帮我把这块石头踢开,非常感谢。

我的问题:我们公司为iPhone生产USB存储设备,实际上这个存储设备中有一个SDCard。现在,我们要开发一个 Mac 应用程序来更新此存储设备的固件。但每次我的存储设备连接到Mac时,苹果会自动安装它,我总是失败,kIOReturnExclusiveAccess调用时USBInterfaceOpen

我也尝试写一个无代码的kext来增加探测分数,但它仍然不起作用。我不知道是我走错了路,还是在编写无代码 kext 时出现了一些错误,例如,写了一些错误的 IOClass、错误的包 ID。

我的无代码 kext info.plist 是:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>BuildMachineOSBuild</key>
  <string>14E46</string>
  <key>CFBundleDevelopmentRegion</key>
  <string>en</string>
  <key>CFBundleIdentifier</key>
  <string>com.mophie.MyDriverTest3</string>
  <key>CFBundleInfoDictionaryVersion</key>
  <string>6.0</string>
  <key>CFBundleName</key>
  <string>MyDriverTest3</string>
  <key>CFBundlePackageType</key>
  <string>KEXT</string>
  <key>CFBundleSignature</key>
  <string>????</string>
  <key>CFBundleVersion</key>
  <string>1.0.3</string>
  <key>DTCompiler</key>
  <string>com.apple.compilers.llvm.clang.1_0</string>
  <key>DTPlatformBuild</key>
  <string>6E35b</string>
  <key>DTPlatformVersion</key>
  <string>GM</string>
  <key>DTSDKBuild</key>
  <string>14D125</string>
  <key>DTSDKName</key>
  <string>macosx10.10</string>
  <key>DTXcode</key>
  <string>0640</string>
  <key>DTXcodeBuild</key>
  <string>6E35b</string>
  <key>IOKitPersonalities</key>
  <dict>
    <key>MyDriverTest3</key>
      <dict>
        <key>CFBundleIdentifier</key>
        <string>com.apple.iokit.IOUSBFamily</string>
        <key>IOClass</key>
        <string>IOService</string>
        <key>IOProviderClass</key>
        <string>IOUSBDevice</string>
        <key>bcdDevice</key>
        <string>256</string>
        <key>idProduct</key>
        <integer>4369</integer>
        <key>idVendor</key>
        <integer>6631</integer>
      </dict>
  </dict>
  <key>OSBundleRequired</key>
  <string>Root</string>
</dict>
</plist>    
Run Code Online (Sandbox Code Playgroud)

以下是 ioreg 对我的存储设备的结果:

space pack@1a122000  <class IOUSBDevice, id 0x100001773, registered, matched, active, busy 0 (300 ms), retain 9>
+-o IOUSBCompositeDriver  <class IOUSBCompositeDriver, id 0x100001775, !registered, !matched, active, busy 0, retain 4>
 +-o IOUSBInterface@0  <class IOUSBInterface, id 0x100001776, registered, matched, active, busy 0 (293 ms), retain 8>
  +-o IOUSBMassStorageClass  <class IOUSBMassStorageClass, id 0x100001777, registered, matched, active, busy 0 (201 ms), retain 9>
   +-o IOSCSIPeripheralDeviceNub  <class IOSCSIPeripheralDeviceNub, id 0x100001779, registered, matched, active, busy 0 (99 ms), retain 7>
    +-o IOSCSIPeripheralDeviceType00  <class IOSCSIPeripheralDeviceType00, id 0x10000177a, !registered, !matched, active, busy 0 (13 ms), retain 9>
     +-o IOBlockStorageServices  <class IOBlockStorageServices, id 0x10000177d, registered, matched, active, busy 0 (13 ms), retain 6>
      +-o IOBlockStorageDriver  <class IOBlockStorageDriver, id 0x10000177e, registered, matched, active, busy 0 (12 ms), retain 47>
       +-o mophie SpacePack Media  <class IOMedia, id 0x100001784, registered, matched, active, busy 0 (12 ms), retain 11>
        +-o IOMediaBSDClient  <class IOMediaBSDClient, id 0x100001785, registered, matched, active, busy 0 (0 ms), retain 6>
         +-o IOFDiskPartitionScheme  <class IOFDiskPartitionScheme, id 0x100001788, !registered, !matched, active, busy 0 (1 ms), retain 6>
          +-o Untitled 1@1  <class IOMedia, id 0x10000178a, registered, matched, active, busy 0 (1 ms), retain 10>
           +-o IOMediaBSDClient  <class IOMediaBSDClient, id 0x10000178b, registered, matched, active, busy 0 (0 ms), retain 7>
Run Code Online (Sandbox Code Playgroud)

希望你能帮助我解决这个问题,非常感谢,我非常感谢你的帮助!

pmd*_*mdj 1

几点:

  • 无代码 kext 方法通常适用于这种情况。
  • 通常,您的无代码 kext 将匹配(通过 IOProviderClass)一个IOUSBInterface,而不是一个IOUSBDevice. (例如参见FTDI 示例
  • 包标识符IOServicecom.apple.kpi.iokit,而不是com.apple.iokit.IOUSBFamily,尽管我怀疑这不应该是一个问题。
  • 您的无代码 kext 是否已正确签名并安装?(我遇到过 /Library/Extensions/ 中的 kext 在启动时无法工作的情况,至少在 OSX 10.9.x 上,与 /System/Library/Extensions 不同,尽管它对于任何热插拔设备都应该可以正常工作。)确保 kext/personality 缓存是最新的,换句话说,touch每当您更新 kext 时,扩展目录都是最新的。
  • 说什么kextutil -n
  • 您是否尝试过设置IOKitDebug个性属性来查看您的 kext 是否有机会匹配设备?
  • 根据固件更新命令的实现方式,您也许可以ioctl在设备节点上使用 s。您可以通过 ioctl 向 SCSI 设备发送原始 SCSI 请求。我不确定这是否适用于 USB 海量存储类,但它肯定适用于 USB 连接的 SCSI (UAS) 或任何其他“真正的”SCSI 设备。显然,只有当您的固件更新命令通过 SCSI 公开时,这才有用。

如果完成所有这些之后,您仍然遇到困难,请提供与上述建议相关的更多信息!