Using an existing driver with a USB serial chip with custom VID/PID

I am using a Silicon labs CP2102 chip. I have configured a custom USB VID and PID on the chip, and want to create a MacOs driver (or rather map this custom VID/PID to an existing driver) to make it accessible as a USB serial device from my Mac.

Preferably I'd like to map my device to the com.apple.DriverKit-AppleUSBSLCOM.dext driver, but I think the generic USB serial driver (com.apple.DriverKit-AppleUSBSerial.dext) should work too. Silabs also has their own driver (com.silabs.cp210x.dext, downloadable from their web page), if for some reason it is easier to map to that than to one of the native drivers that could also work.

Based on https://developer.apple.com/documentation/kernel/implementing_drivers_system_extensions_and_kexts#3616855

and https://developer.apple.com/documentation/driverkit/creating_a_driver_using_the_driverkit_sdk

it should be possible to create a codeless dext, which just inherits from e.g. IOUserUSBSerial.

I've tried both creating just a DriverKit driver and putting it under /Library/DriverExtensions/ and creating a (default) app and adding a DriverKit driver to it, and putting the app in my /Applications/ folder, but neither works for me.

My driver implementation is just this:

#include <USBSerialDriverKit/IOUserUSBSerial.iig>

class MyDriver: public IOUserUSBSerial
{
};

and my IOKitPersonalities looks like this:

<key>IOKitPersonalities</key>
<dict>
	<key>MyDriver</key>
	<dict>
		<key>CFBundleIdentifier</key>
		<string>com.mydriver.MyDriverApp.MyDriver</string>
		<key>IOClass</key>
		<string>IOUserUSBSerial</string>
		<key>IOMatchCategory</key>
		<string>com.mydriver.MyDriverApp.MyDriver</string>
		<key>IOProviderClass</key>
		<string>IOUSBHostInterface</string>
		<key>IOUserClass</key>
		<string>MyDriver</string>
		<key>IOUserServerName</key>
		<string>com.mydriver.MyDriverApp.MyDriver</string>
		<key>bConfigurationValue</key>
		<integer>1</integer>
		<key>bInterfaceNumber</key>
		<integer>0</integer>
		<key>idProduct</key>
		<integer>(my custom PID, decimal value)</integer>
		<key>idVendor</key>
		<integer>(my custom VID, decimal value)</integer>
	</dict>
</dict>

I've disabled SIP and enabled developer mode (systemextensionsctl developer on), though I'm not sure if it's needed. I've scanned through the system logs and looked at the ioreg output. When I connect a CP2102 chip with default VID and PID, I can see that it maps to the native com.apple.DriverKit-AppleUSBSLCOM.dext driver. When I connect the same chip with my custom VID and PID, I don't see any trace of my driver being used. I can see it in the System Information app, but it doesn't map to my driver.

I'm currently suspecting it is an Entitlements issue. In my app I have an Entitlements file, where I've added DriverKit USB Transport and DriverKit Serial Family. Do I need something like this for the driver target? There is no default Entitlements file there, but maybe I should create one? Or is there something else I'm missing?

I've also noted one odd thing: When I install my app I can see a system log entry, complaining that "package type not SYSX" (for my driver). But I don't think it should be a SYSX package? It's currently specified as a DEXT package.

Post not yet marked as solved Up vote post of robin9003 Down vote post of robin9003
385 views

Replies

My first question is "why?"

If you're only changing the vid/pid to make the product appear different to anyone else's which is based on a CP2102, do you really need to? Can you figure out whether it is yours by probing the serial interface? Could you just change the vendor and product strings, instead of the IDs? How much user confusion is likely to arise if you just stick with Silicon Lab's vid/pid?

All of this dext scaffolding is quite painful to get right. The user is burdened with approval of the dext, but if you didn't change the vid/pid of the CP2102, they would not be, because the Apple dext is pre-approved.

I don't know if you can use the recommended approach here, of subclassing from a known DriverKit class, but overriding nothing. This is because AppleUSBSLCOM is specific to the Silicon Labs CP2102, its interface isn't in the DriverKit headers. You can't simply inherit from IOUserUSBSerial, because that driver doesn't know about CP2102, and I don't think you can inherit from AppleUSBSLCOM, because you have no header file for it.

I'd try two things:

  1. go to /System/Library/DriverExtensions/com.apple.DriverKit-AppleUSBSLCOM.dext and copy the DriverKit-AppleUSBSLCOM-CP2102 IOKitPersonality from it, change the idProduct and idVendor and put that modified dictionary into your driver's plist.

Your personality is now referring to an executable which isn't present in your bundle, I don't know if that will work. You may need to ensure that your dext contains some executable code, but this personality won't refer to it. Your code should already generate a do-nothing dext.

  1. ensure that your app actually tries to activate your extension using

what does systemextensionsctl list tell you? I use log collect --last 20 immediately after activation to give me a workable log archive that isn't too huge and isn't constantly changing where I can read messages which my be pertinent to my dext.

I don't use systemextensionsctl developer on any more. Its laughingly poorly documented - what is developer mode, for example (FB7656761) ?

As for entitlements, your hosting app needs the System Extension entitlement. Your driver needs DriverKit (a boolean YES), DriverKit USB transport (a dictionary containing an array of idVendors, usually just one), and DriverKit serial family