I am migrating a codeless KEXT to a codeless DEXT. I have watched the WWDC video and read much of the information on the Apple Developer site. The difficulty I am having is
I was banging my head hard against getting the same thing to work. In the end I managed to get a working DEXT that disables the Apple HID driver for specific vendor ID/product ID combinations. We have obtained the DriverKit entitlement for our vendor ID.
- It looks like the default subclass of IOService is OK for USB - that is the same as the IOClass from the KEXT. Is that true?
This worked for me. I tried removing the .iig
and .cpp
files completely, but unlike KEXTs, it seems that there needs to be some code compiled in order for signing to work properly. So I ended up with just an empty subclass of IOService
.
- Is IOUSBHostInterface in DEXT-world equivalent to IOUSBInterface in KEXT-world?
I believe so. I used IOUSBHostInterface
and we had IOUSBInterface
in our KEXT.
- Is IOUSBHostDevice equivalent to IOUSBDevice?
I don't know, but I believe so.
- Do I need to do anything to the .cpp or .iig for codeless DEXT? Isn't most of my work to be done in the plist and entitlements files?
I did not need to change anything in the .cpp
and .iig
files. You might want to delete the os_log(OS_LOG_DEFAULT, "Hello World");
line in the .cpp
file before you release it. But while debugging, it was useful for me to tell whether the DEXT was actually loading or not. You can run log stream --source | grep 'HELLO'
in a terminal to look for the log.
- Do I need the USBDriverKit.framework in my Frameworks and Libraries of MyUsbDriver target?
My DEXT links against DriverKit.framework
. I don't know if it's needed or not.
- Where can I find a decent example of how to complete this migration?
Maybe these can help:
During development of a DriverKit extension (dext), do the following:
Disable system integrity protection (SIP): https://apple.stackexchange.com/a/208481/21491. (Reboot in recovery mode, run csrutil disable
). Remember to enable it again!
Enable system extension development mode by running systemextensionsctl developer on
Make sure you don't have your old codeless KEXT installed. (Delete it from /Library/Extensions
and/or /System/Library/Extensions
. Make sure to reboot afterwards)
You might need a manual provisioning profile that contains the DriverKit entitlements. I think my problem was that I got the DriverKit entitlement on an enterprise developer team instead of a team for public development.
The app that loads the extension needs the "System Extension" entitlement, but does not need a manual provisining profile.
Be ware of a stupid bug in System Preferences. You need to consent to loading the dext every time it gets loaded. However, if the "Security & Privacy" pane is already open, it will not show the button to give the consent. You need to restart System Preferences for it to show up. I've been using the command pkill -9 "System Preferences"; open /System/Library/PreferencePanes/Security.prefPane
from Terminal generously to workaround this.
You can use systemextensionsctl
to uninstall the dext or reset the system state. However, this does not actually change the driver matching, so you need to reboot. Generously. I used this Terminal command because I'm lazy: osascript -e 'tell app "System Events" to restart'
.
You can use ioreg
to check whether devices are being matched to the extension or not: ioreg -lirc IOUSBHostInterface
.
The key to getting the extension to work is to set the IOProviderClass
to
IOUSBHostInterface
instead of IOResources
in the Info.plist file. (For
reference, the KEXT uses IOUSBInterface
which is one of the classes that
Apple has deprecated)
You might want to bump the version in Info.plist
every time you make changes to your DEXT to make sure that you are actually using the correct one. (systemextensionsctl
will show the version it has loaded).