【问题标题】:USBInterfaceOpen always report kIOReturnExclusiveAccess errorUSBInterfaceOpen总是报kIOReturnExclusiveAccess错误
【发布时间】:2015-07-29 11:21:58
【问题描述】:

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

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

我也尝试写一个codeless 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>    

以下是我的存储设备的 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>

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

【问题讨论】:

    标签: kernel usb iokit kernel-extension


    【解决方案1】:

    几点:

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

    如果您仍然卡在上面,请提供与上述建议相关的更多信息!

    【讨论】:

    • 非常感谢您提供的 FTDI 示例。它提到长期解决方案是修改应用程序以打开 BSD 层串行端口以与 FTDI 硬件通信。短期解决方案是实现无代码 kext。也许我需要研究长期解决方案。
    • 我按照您的建议尝试了,但仍然失败。我使用 kextutil -n,它说:警告:个性 CFBundleIdentifier 与包含 kext 不同(不一定是错误,但很少这样做):MyDriverTest3 代码签名失败:未代码签名警告:个性 CFBundleIdentifier 与包含 kext 不同(不一定是错误,但很少这样做): MyDriverTest3 /System/Library/Extensions/MyDriverTest3.kext 似乎是可加载的(包括磁盘库的链接)。我还通过以下方式禁用代码签名:sudo nvram boot-args=kext-dev-mode=1
    • 嗯,这些只是警告而不是错误,所以如果你将 kext 安装在 /Library/Extensions 中,然后插入设备,会发生什么?你有任何控制台输出吗?等等。
    • FTDI 案例明显不同,因为它是一个串行端口。我对您的设备了解不多,无法知道哪种设备最适合您。
    • 我修改的kext plist是:MyTestDriver3.kext
    【解决方案2】:

    听起来您正在尝试使用IOUSBInterfaceInterface 提供的低级USB 命令连接到USB 大容量存储接口并发送一些自定义命令来更新固件。由于 Apple 大容量存储驱动程序声明了该接口,因此您可能不允许这样做。

    相反,您可以尝试在您的设备上创建第二个 USB 接口,它是供应商定义的接口。您将能够连接到该接口并将任意控制传输发送到您的设备。如果您的设备还不是复合设备,那么您的设备将是复合设备。

    或者,您也可以尝试某种黑客手段通过大容量存储接口发送信号。例如,每当将具有特殊名称的文件写入设备时,这可能是设备进入引导加载程序模式以进行固件更新的信号。

    【讨论】:

    • 嗨,David,非常感谢您的回复,但我们没有供应商定义的接口。我们的产品正在销售中,由于iOS更新,iOS无法识别设备。所以我们计划开发一个用于固件更新的mac应用程序。 windows 版本很简单,但是对于 mac,IOUSBInterfaceInterface 总是失败。我很难过。
    • 好吧,真可惜。是否没有客户可以遵循的进入引导加载程序模式的硬件程序?由于固件总是有可能被损坏或开始出现异常行为,因此设备应设计有一个特殊的引脚/按钮,在上电期间检查以确定是否进入固件更新模式。
    • 是的,你的建议很好,但是我们的固件没有这个机制。
    猜你喜欢
    • 2018-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-08
    • 1970-01-01
    • 2013-01-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多