OSX kext Stuff

Loading and Unloading

From gist. Shows how to unload/load USB kexts, but can be applied to anything.

sudo kextunload -b org.virtualbox.kext.VBoxUSB
sudo kextunload -b org.virtualbox.kext.VBoxNetFlt
sudo kextunload -b org.virtualbox.kext.VBoxNetAdp
sudo kextunload -b org.virtualbox.kext.VBoxDrv

sudo kextload /Library/Extensions/VBoxDrv.kext -r /Library/Extensions/
sudo kextload /Library/Extensions/VBoxNetFlt.kext -r /Library/Extensions/
sudo kextload /Library/Extensions/VBoxNetAdp.kext -r /Library/Extensions/
sudo kextload /Library/Extensions/VBoxUSB.kext -r /Library/Extensions/

When a kext won’t unload

$ sudo kextunload -bundle com.FTDI.driver.FTDIUSBSerialDriver
(kernel) Can't unload kext com.FTDI.driver.FTDIUSBSerialDriver; classes have instances:
(kernel)     Kext com.FTDI.driver.FTDIUSBSerialDriver class FTDIUSBSerialDriver has 3 instances.
Failed to unload com.FTDI.driver.FTDIUSBSerialDriver - (libkern/kext) kext is in use or retained (cannot unload).

Use kextstat to see if something’s using the driver:

$ kextstat | grep -i ftdi
  281    0 0xffffff7f82ded000 0x8000     0x8000     com.FTDI.driver.FTDIUSBSerialDriver (2.2.18) <122 39 5 4 3 1>

The header for kextstat will not be shown since we’re grepping, but the first number is the kext’s ID and the second number is the number of references to this kext that are being held. In this case you can see that there are no references, so why is it not unloading? The answer was found in this stackoverflow question. Answer text copied for posterity:

Running kextunload for an IOKit kext will (if no other kexts depend on it) cause the kernel to attempt to terminate() any instances of classes in that kext which are in the I/O Kit registry. It will then wait a bit and check if any of that kext’s classes still have instances. If not, it will unload the kext. If instances remain, kextunload fails (the terminated instances stay terminated, though).

So somehow, you’re still ending up with live instances.

One possibility is that your objects are refusing to terminate(). This can happen if they have clients that won’t give up control, e.g. you can’t unload the driver for a disk with a mounted file system on top. Userspace clients that don’t respond to termination messages are another example.

Otherwise, the instances terminate, but are not freed. Since they seem to be of two of your main driver classes, if you don’t have any user clients that won’t give up their claim, I’m going to go out on a limb and suggest that you might have a circular reference. If that’s not it, you’ll just have to hunt for retain()s which are not matched by a release(). I give some tips on how to track these down in this answer.

If the instances terminate and are deregistered, they will no longer appear in the output of the ioreg commandline tool, so that’s an easy way of checking which of the two cases applies here.

So basically the FTDI driver is refusing to unload, probably because it’s a little buggy. Crap.

Add picture from clipboard (Maximum size: 1 GB)