Read Me.txt

Read Me About IOKitWithLibrary
 
1.0
 
IOKitWithLibrary is a trivial I/O Kit sample that shows how an I/O Kit driver can link with a C library that resides in a separate kernel extension. Some developers find this technique useful because it allows them to share some core functionality between many different I/O Kit drivers.
 
The sample should work on all versions of Mac OS X, but has only been tested on Mac OS X 10.2.x.
 
Packing List
 
The sample contains the following items:
 
¥ Read Me About IOKitWithLibrary Ñ This document.
¥ IOKitWithLibrary.pbproj Ñ A Project Builder project for the sample.
¥ build Ñ A folder containing pre-built versions of the I/O Kit driver and, embedded within it, the library KEXT.
¥ English.lproj Ñ Localised resources.
¥ IOKitPart.h Ñ Interface to the I/O Kit driver.
¥ IOKitPart.cpp Ñ Implementation of the I/O Kit driver.
¥ LibraryPart.h Ñ Interface to the library KEXT.
¥ LibraryPart.c Ñ Implementation of the library KEXT.
 
Using the Sample
 
To use the sample, you have to first install the I/O Kit driver. To start, change into the directory containing the sampleÉ
 
[guy-smiley:~] quinn% cd PathToSample
 
É then change into the build directory.
 
[guy-smiley:IOKitWithLibrary] quinn% cd build
 
You can now copy the I/O Kit driver into the Extensions folder.
 
[guy-smiley:build] quinn% sudo cp -r IOKitWithLibrary.kext /System/Library/Extensions
Password: ********
 
At this point, it's possible to load the I/O Kit driver and have the system automatically load the library it depends on.  The -t flag causes kextload to validate the KEXT before it loads it.
 
[guy-smiley:build] quinn% sudo kextload -t /System/Library/Extensions/IOKitWithLibrary.kext
kextload: extension /System/Library/Extensions/IOKitWithLibrary.kext appears to be valid
kextload: notice: extension /System/Library/Extensions/IOKitWithLibrary.kext has debug properties set
kextload: /System/Library/Extensions/IOKitWithLibrary.kext loaded successfully
 
If you look at the end of the system log file, you'll see that the I/O Kit driver is actually linked to the library and can call functions within the library (for example, the log entry "LibraryFunction" is printed by code in the library).
 
[guy-smiley:build] quinn% tail /var/log/system.log
Aug  7 16:56:45 mr-hoots sshd[439]: Accepted password for quinn from 10.0.40.2 port 56692 ssh2
Aug  7 16:57:09 mr-hoots sudo:    quinn : TTY=ttyp1 ; PWD=/Users/quinn ; USER=root ; COMMAND=/bin/cp -r IOKitPart.kext /System/Library/Extensions
Aug  7 16:57:19 mr-hoots sudo:    quinn : TTY=ttyp1 ; PWD=/Users/quinn ; USER=root ; COMMAND=/bin/cp -r IOKitWithLibrary.kext /System/Library/Extensions
Aug  7 16:57:44 mr-hoots sudo:    quinn : TTY=ttyp1 ; PWD=/Users/quinn ; USER=root ; COMMAND=/sbin/kextload -t /System/Library/Extensions/IOKitWithLibrary.kext
Aug  7 16:57:48 mr-hoots mach_kernel: Matching service count = 1
Aug  7 16:57:48 mr-hoots mach_kernel: Calling library function
Aug  7 16:57:48 mr-hoots mach_kernel: LibraryFunction
Aug  7 16:57:48 mr-hoots mach_kernel: Returned from library
Aug  7 16:57:48 mr-hoots mach_kernel: com_apple_dts_driver_IOKitWithLibrary::probe(IOResources)
Aug  7 16:57:48 mr-hoots mach_kernel: com_apple_dts_driver_IOKitWithLibrary::start(IOResources) <1>
 
Finally, you can unload the I/O Kit driver and the library KEXTÉ
 
[guy-smiley:build] quinn% sudo kextunload /System/Library/Extensions/IOKitWithLibrary.kext
unload kext /System/Library/Extensions/IOKitWithLibrary.kext succeeded (any personalities also unloaded)
 
[guy-smiley:build] quinn% sudo kextunload -b com.apple.dts.library.IOKitWithLibrary
unload id com.apple.dts.library.IOKitWithLibrary succeeded (any personalities also unloaded)
 
É and delete the I/O Kit driver from the Extensions folder.
 
[guy-smiley:build] quinn% sudo rm -r /System/Library/Extensions/IOKitWithLibrary.kext
 
Building the Sample
 
The sample was built on Mac OS X version 10.2.6 using Project Builder 2.1 from the Dec 2002 developer tools.  To build the project, open the project, make sure that the "IOKitWithLibrary" target is selected, and choose Build from the Build menu.
 
The project contains two targets, "IOKitLibrary" and "LibraryPart". Building the first target also builds the second and runs a "copy" build phase to copy the "LibraryPart.kext" KEXT into the "PlugIns" folder within "IOKitWithLibrary.kext". The end result is that the library KEXT is embedded within the driver KEXT. This guarantees that the driver and library will never be separated, which has a number of advantages.
 
¥ It guarantees that the library will never be missing when the driver is loaded.
¥ It guarantees that the library and driver will always be in sync.
¥ It makes the KEXT easier to install and remove.
 
This technique may not be approach for all projects, but we encourage you to use it when it is.
 
How it Works
 
The kernel has a single level namespace, so the process of linking between one KEXT and another is very simple: just declare a function in a common header, defined the function in one KEXT, and call it in another.
 
On the other hand, setting up the KEXT packaging so that one KEXT declares a dependency on another can be tricky.  The following is a list of items that I had to get right in order for IOKitLibrary to work properly.
 
Source Code
 
Check that I/O Kit driver header and source have the correct class name (com_apple_dts_driver_IOKitWithLibrary), and that it matches the class name in the IOKitPersonalities entry within the plist.
 
Check that functions exported from the library aren't going to collide with other kernel symbols. In this example I used the name com_apple_dts_library_IOKitWithLibrary_LibraryFunction.  Remember that the kernel has a single-level namespace, so if you export a function and the kernel or some other KEXT exports a function of the same name, bad things will happen. The best way to avoid this problem is to use reverse DNS notation for your function names, as shown in this example. For more information about this issue, see the "Standard C Naming Conventions" section of "Inside Mac OS X: Kernel Programming".
 
<http://developer.apple.com/documentation/Darwin/Conceptual/KernelProgramming/index.html>
 
Check that the library start and stop routines are uniquely named (com_apple_dts_library_IOKitWithLibrary_start, com_apple_dts_library_IOKitWithLibrary_stop).
 
For C exports, make sure the exports are bracketed with the following guards, otherwise C++ code won't be able to access the symbols because the C++ compiler will mangle the names.
 
#ifdef __cplusplus
    extern "C" {
#endif
 
// your declarations here
 
#ifdef __cplusplus
    }
#endif
 
LibraryPart target, Settings, Expert View
 
Check that KERNEL_MODULE is defined to YES.
 
Check that MODULE_IOKIT is not defined.
 
Check that MODULE_NAME matches the name in CFBundleIdentifier in the plist (com.apple.dts.library.IOKitWithLibrary).
 
Check that MODULE_START and MODULE_STOP match the names used in the source (com_apple_dts_library_IOKitWithLibrary_start, com_apple_dts_library_IOKitWithLibrary_stop).
 
Check that MODULE_VERSION matches CFBundleVersion in plist (1.0).
 
Check that PRODUCT_NAME reflects the name of the bundle in the file system and that it matches CFBundleExecutable in the plist (LibraryPart).
 
Check that WRAPPER_EXTENSION is kext.
 
LibraryPart target, Info.plist, Expert View
 
Check that CFBundleExecutable matches PRODUCT_NAME in settings (LibraryPart).
 
Check that CFBundleIdentifier matches MODULE_NAME in settings (com.apple.dts.library.IOKitWithLibrary).
 
Check that CFBundlePackageType is KEXT.
 
Check that CFBundleVersion matches MODULE_VERSION in settings (1.0).
 
Check that OSBundleCompatibleVersion is present and correct (1.0).
 
Check that OSBundleLibraries reflects correct dependencies.
 
  com.apple.kernel.iokit   = 1.1
  com.apple.kernel.libkern = 1.1
  com.apple.kernel.mach    = 1.1
 
IOKitWithLibrary target, Settings, Expert View
 
Check that KERNEL_MODULE is defined to YES.
 
Check that MODULE_IOKIT is defined to YES.
 
Check that MODULE_NAME matches the name in CFBundleIdentifier in the plist (com.apple.dts.driver.IOKitWithLibrary).
 
Check that MODULE_START and MODULE_STOP are not defined.
 
Check that MODULE_VERSION matches CFBundleVersion in plist (1.0).
 
Check that PRODUCT_NAME reflects name of the bundle in the file system and that it matches CFBundleExecutable in plist (IOKitWithLibrary).
 
Check that WRAPPER_EXTENSION is kext.
 
IOKitWithLibrary target, Info.plist, Expert View
 
Check that CFBundleExecutable matches PRODUCT_NAME in settings (IOKitWithLibrary).
 
Check that CFBundleIdentifier matches MODULE_NAME in settings (com.apple.dts.driver.IOKitWithLibrary).
 
Check that CFBundlePackageType is KEXT.
 
Check that CFBundleVersion matches MODULE_VERSION in settings (1.0).
 
Check that IOKitPersonalities is set correctly.  There should be at least one entry, named by a suitably mnemonic key.  Check the following within that entry.
 
¥ Check that CFBundleIdentifier matches identifier in plist (com.apple.dts.driver.IOKitWithLibrary).
 
¥ÊCheck that IOClass matches class name in source (com_apple_dts_driver_IOKitWithLibrary).
 
¥ If debugging, set IOKitDebug to the number 65535.
 
¥ Set IOProviderClass to class of your provider (IOResources).
 
¥ÊSet other matching properties.
 
    IOMatchCategory = IOKitWithLibrary
    IOResourceMatch = IOKit
 
Check that OSBundleLibraries reflects correct dependencies.
 
  com.apple.dts.library.IOKitWithLibrary = 1.0
  com.apple.kernel.iokit                 = 1.1
  com.apple.kernel.libkern               = 1.1
  com.apple.kernel.mach                  = 1.1
 
Clean All Targets and Rebuild
 
Project Builder does not correctly update all dependencies when you change the above settings, so make sure that you clean all targets and rebuild after you change them.
 
Credits and Version History
 
If you find any problems with this sample, mail <DTS@apple.com> and IÕll try to fix them up.
 
1.0 (Aug 2003) was the first shipping version.
 
Share and Enjoy.
 
Apple Developer Technical Support
Networking, Communications, Hardware
 
14 Aug 2003