Memory management in KExts

One of the first challenges I faced when programming KExt is how to
allocate and manage memory in Kernel Extensions on Mac OS X. IO Kit
memory management is quite different from regular standard C++
management. Here are a couple of differences you should bear in mind all
the time as you program your Kernel Extension:

  • The stack is very limited, avoid recursion and using many variables
    in your functions
  • All classes inheriting from OSObject does reference counting and
    prohibits using delete to deallocate a class, instead you should
    use release
  • You don’t use constructors when allocating a class inheriting
    OSObject, instead you have to use init
  • To allocate a buffer of memory, don’t use new, delete, malloc
    or free, but instead use IOMalloc and IOFree

Here is how you would proceed to create a OSObject inherited class
(IOKit class):

[cpp]
IOClassType * aClassInstance = new IOClassType; // increments
reference counter
if (!aClassInstance) {
// Code handling error
}

if (!aClassInstance->init(/* params */)) {
// Code handling error
}
[/cpp]

Replace params with either NULL or a valid OSDictionary instance (which
is a lookup table) containing the arguments for the init method.
Occasionally you might see code the following type of code

[cpp]
IOClassType * aClassInstance = IOClassType::withParams(…);
[/cpp]

Whether you see this type of code or not depends on IOClassType.
Essentially the withParams-like static methods does behind the seems
the allocation of memory, the initialisation and the error checking. A
good example can be found in
IOMemoryDescriptor
which is an IOKit class represents non-contiguous memory.
IOMemoryDescriptor offers several withParams type methods for
instance:

[cpp]
static IOMemoryDescriptor * withPhysicalAddress(
IOPhysicalAddressaddress, IOByteCountwithLength,
IODirectionwithDirection );
[/cpp]

Whenever you allocate an OSObject inherited class, you must remember the
instance increases the reference count and to decrease the reference
count you must do:

[cpp]
aClassInstance->release();
[/cpp]

which is equivalent to freeing the object if the reference count goes to
zero.

If you want to allocate dynamically a buffer or an array of memory you
proceed as follows:

[cpp]
#include \

// Some code in between
char * buffer = IOMalloc(bufferSize);
[/cpp]

Similarly to deallocate a dynamically allocated buffer

[cpp]
#include \

// Some code in between
IOMalloc(buffer, bufferSize);
[/cpp]