强制特定驱动程序的无代码 kext (CDC-ACM)
Codeless kext to force a specific driver (CDC-ACM)
我想知道是否有办法以通用方式在 OS X 上使用 USB 调制解调器(华为 E1550 种类),就像通用 USB 调制解调器一样。问题是 OS 不会将其识别为合法的 CDC ACM 设备(它是合法的,但它没有宣传是这样的)。
在 Linux 上,加密狗被自动识别为 USB 串行设备。
有一些原因我不想在我的任何机器上使用 ZTE 或 Huawei 供应商驱动程序:这些人写的东西几乎无法工作(我最后一次使用 ZTE 驱动程序的经历包括向我的日志发送垃圾邮件,占用 RAM,而我无法禁用它),他们的驱动程序不向前兼容,他们忽略了将它们与较新的 OS 版本同步,并且他们通常打算将这些驱动程序与运营商过时软件一起分发。
Apple 的开发人员文档以一种模糊的方式写道,可以编写无代码的 kext 以在匹配的设备上强制使用特定的驱动程序,或者阻止为匹配的设备加载通用驱动程序。事实上,大多数对无代码 kexts 的搜索都会产生类似 "how do I prevent my serial dongle to be recognised as a modem?" 的问题,而我想要的是完全相反的!
到目前为止,我尝试编写这样一个无代码的 kext 以失败告终 — kextutil 告诉 kext 已成功加载,但它不存在,AppleCDCACM.kext 也是如此(它具有我想使用的 IOClass ).
仅供参考,从 Linux:
收集的 lsusb 信息
Bus 004 Device 005: ID 12d1:1001 Huawei Technologies Co., Ltd. E169/E620/E800 HSDPA Modem
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 0
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 64
idVendor 0x12d1 Huawei Technologies Co., Ltd.
idProduct 0x1001 E169/E620/E800 HSDPA Modem
bcdDevice 0.00
iManufacturer 2 HUAWEI Technology
iProduct 1 HUAWEI Mobile
iSerial 0
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 85
bNumInterfaces 3
bConfigurationValue 1
iConfiguration 3 Qualcomm Configuration
bmAttributes 0xe0
Self Powered
Remote Wakeup
MaxPower 500mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 3
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 255 Vendor Specific Subclass
bInterfaceProtocol 255 Vendor Specific Protocol
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 5
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x82 EP 2 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 32
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x01 EP 1 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 32
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 255 Vendor Specific Subclass
bInterfaceProtocol 255 Vendor Specific Protocol
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x83 EP 3 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 32
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x02 EP 2 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 32
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 2
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 255 Vendor Specific Subclass
bInterfaceProtocol 255 Vendor Specific Protocol
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x84 EP 4 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 32
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x03 EP 3 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 32
Device Qualifier (for other device speed):
bLength 10
bDescriptorType 6
bcdUSB 2.00
bDeviceClass 0
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 64
bNumConfigurations 1
can't get debug descriptor: Resource temporarily unavailable
Device Status: 0x0001
Self Powered
我要连接的接口是接口 0(调制解调器)。
ioreg
是这样看的:
| | | | | +-o HUAWEI Mobile@1d110000
| | | | | +-o AppleUSBHostLegacyClient
| | | | | +-o AppleUSBHostCompositeDevice
| | | | | +-o IOUSBHostInterface@0
| | | | | | {
| | | | | | "USBPortType" = 0
| | | | | | "IOCFPlugInTypes" = {"2d9786c6-9ef3-11d4-ad51-000a27052861"="IOUSBFamily.kext/Contents/PlugIns/IOUSBLib.bundle"}
| | | | | | "bcdDevice" = 0
| | | | | | "USBSpeed" = 3
| | | | | | "idProduct" = 4097
| | | | | | "bConfigurationValue" = 1
| | | | | | "bInterfaceSubClass" = 255
| | | | | | "locationID" = 487653376
| | | | | | "IOGeneralInterest" = "IOCommand is not serializable"
| | | | | | "IOClassNameOverride" = "IOUSBInterface"
| | | | | | "AppleUSBAlternateServiceRegistryID" = 4294969542
| | | | | | "idVendor" = 4817
| | | | | | "bInterfaceProtocol" = 255
| | | | | | "bAlternateSetting" = 0
| | | | | | "bInterfaceNumber" = 0
| | | | | | "bInterfaceClass" = 255
| | | | | | }
| | | | | |
| | | | | +-o IOUSBHostInterface@1
| | | | | | {
| | | | | | "USBPortType" = 0
| | | | | | "IOCFPlugInTypes" = {"2d9786c6-9ef3-11d4-ad51-000a27052861"="IOUSBFamily.kext/Contents/PlugIns/IOUSBLib.bundle"}
| | | | | | "bcdDevice" = 0
| | | | | | "USBSpeed" = 3
| | | | | | "idProduct" = 4097
| | | | | | "bConfigurationValue" = 1
| | | | | | "bInterfaceSubClass" = 255
| | | | | | "locationID" = 487653376
| | | | | | "IOGeneralInterest" = "IOCommand is not serializable"
| | | | | | "IOClassNameOverride" = "IOUSBInterface"
| | | | | | "AppleUSBAlternateServiceRegistryID" = 4294969544
| | | | | | "idVendor" = 4817
| | | | | | "bInterfaceProtocol" = 255
| | | | | | "bAlternateSetting" = 0
| | | | | | "bInterfaceNumber" = 1
| | | | | | "bInterfaceClass" = 255
| | | | | | }
| | | | | |
| | | | | +-o IOUSBHostInterface@2
| | | | | {
| | | | | "USBPortType" = 0
| | | | | "IOCFPlugInTypes" = {"2d9786c6-9ef3-11d4-ad51-000a27052861"="IOUSBFamily.kext/Contents/PlugIns/IOUSBLib.bundle"}
| | | | | "bcdDevice" = 0
| | | | | "USBSpeed" = 3
| | | | | "idProduct" = 4097
| | | | | "bConfigurationValue" = 1
| | | | | "bInterfaceSubClass" = 255
| | | | | "locationID" = 487653376
| | | | | "IOGeneralInterest" = "IOCommand is not serializable"
| | | | | "IOClassNameOverride" = "IOUSBInterface"
| | | | | "AppleUSBAlternateServiceRegistryID" = 4294969546
| | | | | "idVendor" = 4817
| | | | | "bInterfaceProtocol" = 255
| | | | | "bAlternateSetting" = 0
| | | | | "bInterfaceNumber" = 2
| | | | | "bInterfaceClass" = 255
| | | | | }
| | | | |
到目前为止,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>15C27b</string>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleIdentifier</key>
<string>name.fedevych.GenericWWAN</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>GenericWWAN</string>
<key>CFBundlePackageType</key>
<string>KEXT</string>
<key>CFBundleShortVersionString</key>
<string>99.0.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleSupportedPlatforms</key>
<array>
<string>MacOSX</string>
</array>
<key>CFBundleVersion</key>
<string>99.0.0</string>
<key>IOKitPersonalities</key>
<dict>
<key>HUAWEI_0x12d11001_Control</key>
<dict>
<key>CFBundleIdentifier</key>
<string>com.apple.driver.usb.cdc.acm</string>
<key>IOClass</key>
<string>AppleUSBACMControl</string>
<key>IOProviderClass</key>
<string>IOUSBHostInterface</string>
<key>idVendor</key>
<integer>4817</integer>
<key>idProduct</key>
<integer>4097</integer>
<key>bcdDevice</key>
<integer>0</integer>
<key>bInterfaceNumber</key>
<integer>0</integer>
<key>bConfigurationValue</key>
<integer>1</integer>
<key>IOMatchCategory</key>
<string>com.apple.driver.AppleUSBACMControl</string>
</dict>
<key>HUAWEI_0x12d11001_Data</key>
<dict>
<key>CFBundleIdentifier</key>
<string>com.apple.driver.usb.cdc.acm</string>
<key>IOClass</key>
<string>AppleUSBACMData</string>
<key>IOProviderClass</key>
<string>IOUSBHostInterface</string>
<key>idVendor</key>
<integer>4817</integer>
<key>idProduct</key>
<integer>4097</integer>
<key>bcdDevice</key>
<integer>0</integer>
<key>bInterfaceNumber</key>
<integer>0</integer>
<key>bConfigurationValue</key>
<integer>1</integer>
</dict>
</dict>
<key>OSBundleLibraries</key>
<dict/>
</dict>
</plist>
有什么指点吗?
因此,我不能保证您的项目会成功 - 我不知道您的调制解调器是否可以使用标准 CDC 驱动程序。但我希望能帮助你找出答案。这真的有 5 个部分:
- 正确的匹配字典匹配有问题的 device/interface。
- 为实际驱动程序设置正确的 class 和包 ID。
- 无代码 kextinfo.plist 中需要注意的一些额外要点
- Kext 签名。
- Loading/Debugging.
I/O 配套USB配套
Apple 的 Q&A QA1076 是关于该主题的最佳资源。我建议尽可能具体。所以在你的情况下,例如:
IOProviderClass: IOUSBInterface
idVendor: 0x12d1
idProduct: 0x1001
bInterfaceNumber: 0
bConfigurationValue: 1
希望我没听错。当设备插入时,您应该能够在终端中通过 运行 ioreg -c IOUSBInterface
进行确认。这将以 OSX 的格式向您显示系统中所有 USB 接口的属性,并且您应该能够为您的调制解调器挑选一个,并确保这些属性与我提供的相匹配。
驱动程序 class 和包 ID
除了匹配条件之外,info.plist 中的 I/O 套件个性字典还需要指定 (C++) class 应为其创建实例以驱动匹配的设备,以及包含它的 kext 的包 ID。
现在的问题是,用什么驱动。我不太了解 CDC-ACM 设备,但据我所知,它们由一个控件和一个数据接口组成。这个的驱动程序似乎是
/System/Library/Extensions/IOUSBFamily.kext/Contents/PlugIns/AppleUSBCDCACMControl.kext
/System/Library/Extensions/IOUSBFamily.kext/Contents/PlugIns/AppleUSBCDCACMData.kext
分别在 OSX。其中每一个似乎都假设它们可以完全控制 USB 接口——似乎大多数设备将控制和数据端点拆分为 2 个独立的接口。在你的情况下,你只有一个。从技术上讲,多个驱动程序可以通过使用不同的匹配类别来匹配一项服务。但我不能保证 CDC-ACM 数据和控制驱动程序会对此感到满意。你可以试试…
为此,您实际上需要两个 I/O 套件个性词典,具有相同的匹配标准,但其中一个应该有一个非默认的 IOMatchCategory
,例如相关的驱动程序包 ID。
所以尝试这样的事情:
<key>IOKitPersonalities</key>
<dict>
<key>AppleUSBCDCACMControl</key>
<dict>
<key>CFBundleIdentifier</key>
<string>com.apple.driver.AppleUSBCDCACMControl</string>
<key>IOClass</key>
<string>AppleUSBCDCACMControl</string>
<key>IOProviderClass</key>
<string>IOUSBInterface</string>
<key>idVendor</key>
<integer>4817</integer>
<key>idProduct</key>
<integer>4097</integer>
<key>bInterfaceNumber</key>
<integer>0</integer>
<key>bConfigurationValue</key>
<integer>1</integer>
<key>IOMatchCategory</key>
<string>com.apple.driver.AppleUSBCDCACMControl</string>
</dict>
<key>AppleUSBCDCACMData</key>
<dict>
<key>CFBundleIdentifier</key>
<string>com.apple.driver.AppleUSBCDCACMData</string>
<key>IOClass</key>
<string>AppleUSBCDCACMData</string>
<key>IOProviderClass</key>
<string>IOUSBInterface</string>
<key>IOUserClientClass</key>
<string>AppleUSBCDCACMDataUserClient</string>
<key>InputBuffers</key>
<integer>8</integer>
<key>OutputBuffers</key>
<integer>16</integer>
<key>idVendor</key>
<integer>4817</integer>
<key>idProduct</key>
<integer>4097</integer>
<key>bInterfaceNumber</key>
<integer>0</integer>
<key>bConfigurationValue</key>
<integer>1</integer>
</dict>
</dict>
无代码kext info.plist
因为您已经拥有 kextutil 似乎喜欢的 kext,您可能已经做对了:无代码 kexts 必须:
- 有空
OSBundleLibraries
属性.
- 没有
CFBundleExecutable
属性。
Kext 签名
在 OSX 10.10 和 10.11 上,所有 kexts,包括无代码的,都必须签名。在 10.9 上,如果它们驻留在 /System/Library/Extensions
中,则它们可以是无符号的;在 10.10 上,如果设置了内核选项 kext-dev-mode=1
,则它们可以是无符号的。您需要一个特殊的 kext 签名附加到 Apple 的 Developer Id 证书才能签署 kexts。
加载和调试
/System/Library/Extensions(10.10 之前可写)或/Library/Extensions(10.9+)中的 Kexts 将在启动或设备热插拔时自动匹配。也可以使用 kextutil
.
从这些位置之外手动加载它们
加载的 kext 二进制文件列在 kextstat
的输出中。无代码 kexts 没有二进制文件,因此不会出现。但是,如果 I/O Kit Personality 的 CFBundleIdentifier 处于活动状态,则包含驱动程序代码的包将显示。
要查看您的特定设备发生了什么,请使用 ioreg
命令行工具或 GUI 工具 IORegistryExplorer(来自 Apple 的硬件 I/O 工具包)或 IOJones(开源)。
最后的想法
考虑到 CDC-ACM Control/Data 拆分,您可能无法仅使用无代码 kext 来完成工作。您可能需要更深入地了解 Apple 的驱动程序是如何工作的,并可能在您自己的 kext 中覆盖他们的某些行为,以便他们找到正确的端点。祝你好运!
我想知道是否有办法以通用方式在 OS X 上使用 USB 调制解调器(华为 E1550 种类),就像通用 USB 调制解调器一样。问题是 OS 不会将其识别为合法的 CDC ACM 设备(它是合法的,但它没有宣传是这样的)。
在 Linux 上,加密狗被自动识别为 USB 串行设备。
有一些原因我不想在我的任何机器上使用 ZTE 或 Huawei 供应商驱动程序:这些人写的东西几乎无法工作(我最后一次使用 ZTE 驱动程序的经历包括向我的日志发送垃圾邮件,占用 RAM,而我无法禁用它),他们的驱动程序不向前兼容,他们忽略了将它们与较新的 OS 版本同步,并且他们通常打算将这些驱动程序与运营商过时软件一起分发。
Apple 的开发人员文档以一种模糊的方式写道,可以编写无代码的 kext 以在匹配的设备上强制使用特定的驱动程序,或者阻止为匹配的设备加载通用驱动程序。事实上,大多数对无代码 kexts 的搜索都会产生类似 "how do I prevent my serial dongle to be recognised as a modem?" 的问题,而我想要的是完全相反的!
到目前为止,我尝试编写这样一个无代码的 kext 以失败告终 — kextutil 告诉 kext 已成功加载,但它不存在,AppleCDCACM.kext 也是如此(它具有我想使用的 IOClass ).
仅供参考,从 Linux:
收集的 lsusb 信息Bus 004 Device 005: ID 12d1:1001 Huawei Technologies Co., Ltd. E169/E620/E800 HSDPA Modem Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 2.00 bDeviceClass 0 bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 64 idVendor 0x12d1 Huawei Technologies Co., Ltd. idProduct 0x1001 E169/E620/E800 HSDPA Modem bcdDevice 0.00 iManufacturer 2 HUAWEI Technology iProduct 1 HUAWEI Mobile iSerial 0 bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 85 bNumInterfaces 3 bConfigurationValue 1 iConfiguration 3 Qualcomm Configuration bmAttributes 0xe0 Self Powered Remote Wakeup MaxPower 500mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 3 bInterfaceClass 255 Vendor Specific Class bInterfaceSubClass 255 Vendor Specific Subclass bInterfaceProtocol 255 Vendor Specific Protocol iInterface 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x81 EP 1 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 5 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x82 EP 2 IN bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 32 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x01 EP 1 OUT bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 32 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 1 bAlternateSetting 0 bNumEndpoints 2 bInterfaceClass 255 Vendor Specific Class bInterfaceSubClass 255 Vendor Specific Subclass bInterfaceProtocol 255 Vendor Specific Protocol iInterface 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x83 EP 3 IN bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 32 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x02 EP 2 OUT bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 32 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 2 bAlternateSetting 0 bNumEndpoints 2 bInterfaceClass 255 Vendor Specific Class bInterfaceSubClass 255 Vendor Specific Subclass bInterfaceProtocol 255 Vendor Specific Protocol iInterface 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x84 EP 4 IN bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 32 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x03 EP 3 OUT bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 32 Device Qualifier (for other device speed): bLength 10 bDescriptorType 6 bcdUSB 2.00 bDeviceClass 0 bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 64 bNumConfigurations 1 can't get debug descriptor: Resource temporarily unavailable Device Status: 0x0001 Self Powered
我要连接的接口是接口 0(调制解调器)。
ioreg
是这样看的:
| | | | | +-o HUAWEI Mobile@1d110000 | | | | | +-o AppleUSBHostLegacyClient | | | | | +-o AppleUSBHostCompositeDevice | | | | | +-o IOUSBHostInterface@0 | | | | | | { | | | | | | "USBPortType" = 0 | | | | | | "IOCFPlugInTypes" = {"2d9786c6-9ef3-11d4-ad51-000a27052861"="IOUSBFamily.kext/Contents/PlugIns/IOUSBLib.bundle"} | | | | | | "bcdDevice" = 0 | | | | | | "USBSpeed" = 3 | | | | | | "idProduct" = 4097 | | | | | | "bConfigurationValue" = 1 | | | | | | "bInterfaceSubClass" = 255 | | | | | | "locationID" = 487653376 | | | | | | "IOGeneralInterest" = "IOCommand is not serializable" | | | | | | "IOClassNameOverride" = "IOUSBInterface" | | | | | | "AppleUSBAlternateServiceRegistryID" = 4294969542 | | | | | | "idVendor" = 4817 | | | | | | "bInterfaceProtocol" = 255 | | | | | | "bAlternateSetting" = 0 | | | | | | "bInterfaceNumber" = 0 | | | | | | "bInterfaceClass" = 255 | | | | | | } | | | | | | | | | | | +-o IOUSBHostInterface@1 | | | | | | { | | | | | | "USBPortType" = 0 | | | | | | "IOCFPlugInTypes" = {"2d9786c6-9ef3-11d4-ad51-000a27052861"="IOUSBFamily.kext/Contents/PlugIns/IOUSBLib.bundle"} | | | | | | "bcdDevice" = 0 | | | | | | "USBSpeed" = 3 | | | | | | "idProduct" = 4097 | | | | | | "bConfigurationValue" = 1 | | | | | | "bInterfaceSubClass" = 255 | | | | | | "locationID" = 487653376 | | | | | | "IOGeneralInterest" = "IOCommand is not serializable" | | | | | | "IOClassNameOverride" = "IOUSBInterface" | | | | | | "AppleUSBAlternateServiceRegistryID" = 4294969544 | | | | | | "idVendor" = 4817 | | | | | | "bInterfaceProtocol" = 255 | | | | | | "bAlternateSetting" = 0 | | | | | | "bInterfaceNumber" = 1 | | | | | | "bInterfaceClass" = 255 | | | | | | } | | | | | | | | | | | +-o IOUSBHostInterface@2 | | | | | { | | | | | "USBPortType" = 0 | | | | | "IOCFPlugInTypes" = {"2d9786c6-9ef3-11d4-ad51-000a27052861"="IOUSBFamily.kext/Contents/PlugIns/IOUSBLib.bundle"} | | | | | "bcdDevice" = 0 | | | | | "USBSpeed" = 3 | | | | | "idProduct" = 4097 | | | | | "bConfigurationValue" = 1 | | | | | "bInterfaceSubClass" = 255 | | | | | "locationID" = 487653376 | | | | | "IOGeneralInterest" = "IOCommand is not serializable" | | | | | "IOClassNameOverride" = "IOUSBInterface" | | | | | "AppleUSBAlternateServiceRegistryID" = 4294969546 | | | | | "idVendor" = 4817 | | | | | "bInterfaceProtocol" = 255 | | | | | "bAlternateSetting" = 0 | | | | | "bInterfaceNumber" = 2 | | | | | "bInterfaceClass" = 255 | | | | | } | | | | |
到目前为止,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>15C27b</string>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleIdentifier</key>
<string>name.fedevych.GenericWWAN</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>GenericWWAN</string>
<key>CFBundlePackageType</key>
<string>KEXT</string>
<key>CFBundleShortVersionString</key>
<string>99.0.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleSupportedPlatforms</key>
<array>
<string>MacOSX</string>
</array>
<key>CFBundleVersion</key>
<string>99.0.0</string>
<key>IOKitPersonalities</key>
<dict>
<key>HUAWEI_0x12d11001_Control</key>
<dict>
<key>CFBundleIdentifier</key>
<string>com.apple.driver.usb.cdc.acm</string>
<key>IOClass</key>
<string>AppleUSBACMControl</string>
<key>IOProviderClass</key>
<string>IOUSBHostInterface</string>
<key>idVendor</key>
<integer>4817</integer>
<key>idProduct</key>
<integer>4097</integer>
<key>bcdDevice</key>
<integer>0</integer>
<key>bInterfaceNumber</key>
<integer>0</integer>
<key>bConfigurationValue</key>
<integer>1</integer>
<key>IOMatchCategory</key>
<string>com.apple.driver.AppleUSBACMControl</string>
</dict>
<key>HUAWEI_0x12d11001_Data</key>
<dict>
<key>CFBundleIdentifier</key>
<string>com.apple.driver.usb.cdc.acm</string>
<key>IOClass</key>
<string>AppleUSBACMData</string>
<key>IOProviderClass</key>
<string>IOUSBHostInterface</string>
<key>idVendor</key>
<integer>4817</integer>
<key>idProduct</key>
<integer>4097</integer>
<key>bcdDevice</key>
<integer>0</integer>
<key>bInterfaceNumber</key>
<integer>0</integer>
<key>bConfigurationValue</key>
<integer>1</integer>
</dict>
</dict>
<key>OSBundleLibraries</key>
<dict/>
</dict>
</plist>
有什么指点吗?
因此,我不能保证您的项目会成功 - 我不知道您的调制解调器是否可以使用标准 CDC 驱动程序。但我希望能帮助你找出答案。这真的有 5 个部分:
- 正确的匹配字典匹配有问题的 device/interface。
- 为实际驱动程序设置正确的 class 和包 ID。
- 无代码 kextinfo.plist 中需要注意的一些额外要点
- Kext 签名。
- Loading/Debugging.
I/O 配套USB配套
Apple 的 Q&A QA1076 是关于该主题的最佳资源。我建议尽可能具体。所以在你的情况下,例如:
IOProviderClass: IOUSBInterface
idVendor: 0x12d1
idProduct: 0x1001
bInterfaceNumber: 0
bConfigurationValue: 1
希望我没听错。当设备插入时,您应该能够在终端中通过 运行 ioreg -c IOUSBInterface
进行确认。这将以 OSX 的格式向您显示系统中所有 USB 接口的属性,并且您应该能够为您的调制解调器挑选一个,并确保这些属性与我提供的相匹配。
驱动程序 class 和包 ID
除了匹配条件之外,info.plist 中的 I/O 套件个性字典还需要指定 (C++) class 应为其创建实例以驱动匹配的设备,以及包含它的 kext 的包 ID。
现在的问题是,用什么驱动。我不太了解 CDC-ACM 设备,但据我所知,它们由一个控件和一个数据接口组成。这个的驱动程序似乎是
/System/Library/Extensions/IOUSBFamily.kext/Contents/PlugIns/AppleUSBCDCACMControl.kext
/System/Library/Extensions/IOUSBFamily.kext/Contents/PlugIns/AppleUSBCDCACMData.kext
分别在 OSX。其中每一个似乎都假设它们可以完全控制 USB 接口——似乎大多数设备将控制和数据端点拆分为 2 个独立的接口。在你的情况下,你只有一个。从技术上讲,多个驱动程序可以通过使用不同的匹配类别来匹配一项服务。但我不能保证 CDC-ACM 数据和控制驱动程序会对此感到满意。你可以试试…
为此,您实际上需要两个 I/O 套件个性词典,具有相同的匹配标准,但其中一个应该有一个非默认的 IOMatchCategory
,例如相关的驱动程序包 ID。
所以尝试这样的事情:
<key>IOKitPersonalities</key>
<dict>
<key>AppleUSBCDCACMControl</key>
<dict>
<key>CFBundleIdentifier</key>
<string>com.apple.driver.AppleUSBCDCACMControl</string>
<key>IOClass</key>
<string>AppleUSBCDCACMControl</string>
<key>IOProviderClass</key>
<string>IOUSBInterface</string>
<key>idVendor</key>
<integer>4817</integer>
<key>idProduct</key>
<integer>4097</integer>
<key>bInterfaceNumber</key>
<integer>0</integer>
<key>bConfigurationValue</key>
<integer>1</integer>
<key>IOMatchCategory</key>
<string>com.apple.driver.AppleUSBCDCACMControl</string>
</dict>
<key>AppleUSBCDCACMData</key>
<dict>
<key>CFBundleIdentifier</key>
<string>com.apple.driver.AppleUSBCDCACMData</string>
<key>IOClass</key>
<string>AppleUSBCDCACMData</string>
<key>IOProviderClass</key>
<string>IOUSBInterface</string>
<key>IOUserClientClass</key>
<string>AppleUSBCDCACMDataUserClient</string>
<key>InputBuffers</key>
<integer>8</integer>
<key>OutputBuffers</key>
<integer>16</integer>
<key>idVendor</key>
<integer>4817</integer>
<key>idProduct</key>
<integer>4097</integer>
<key>bInterfaceNumber</key>
<integer>0</integer>
<key>bConfigurationValue</key>
<integer>1</integer>
</dict>
</dict>
无代码kext info.plist
因为您已经拥有 kextutil 似乎喜欢的 kext,您可能已经做对了:无代码 kexts 必须:
- 有空
OSBundleLibraries
属性. - 没有
CFBundleExecutable
属性。
Kext 签名
在 OSX 10.10 和 10.11 上,所有 kexts,包括无代码的,都必须签名。在 10.9 上,如果它们驻留在 /System/Library/Extensions
中,则它们可以是无符号的;在 10.10 上,如果设置了内核选项 kext-dev-mode=1
,则它们可以是无符号的。您需要一个特殊的 kext 签名附加到 Apple 的 Developer Id 证书才能签署 kexts。
加载和调试
/System/Library/Extensions(10.10 之前可写)或/Library/Extensions(10.9+)中的 Kexts 将在启动或设备热插拔时自动匹配。也可以使用 kextutil
.
加载的 kext 二进制文件列在 kextstat
的输出中。无代码 kexts 没有二进制文件,因此不会出现。但是,如果 I/O Kit Personality 的 CFBundleIdentifier 处于活动状态,则包含驱动程序代码的包将显示。
要查看您的特定设备发生了什么,请使用 ioreg
命令行工具或 GUI 工具 IORegistryExplorer(来自 Apple 的硬件 I/O 工具包)或 IOJones(开源)。
最后的想法
考虑到 CDC-ACM Control/Data 拆分,您可能无法仅使用无代码 kext 来完成工作。您可能需要更深入地了解 Apple 的驱动程序是如何工作的,并可能在您自己的 kext 中覆盖他们的某些行为,以便他们找到正确的端点。祝你好运!