Retired Document
Important: Retired Document: This document may not represent best practices for current development. Links to downloads and other resources may no longer be valid.
Building Universal I/O Kit Drivers
Describes the steps for configuring an Xcode I/O Kit kernel driver project to produce a universal driver. Also discusses common problems when loading universal drivers.
Introduction
Building universal I/O Kit drivers is very similar to building universal applications, but there are critical differences that can affect a driver's binary compatibility. This technical note describes the steps for configuring an Xcode I/O Kit kernel driver project to produce a universal driver and discusses common binary compatibility problems with universal drivers.
Which Xcode and Mac OS X SDK Versions to Use
Xcode 2.2.1 is the oldest version of Xcode that can be used to build universal I/O Kit drivers.
Building for Intel-based Mac computers
The Intel side of your I/O Kit KEXT must be built using GCC 4.0 and the Mac OS X 10.4u (Universal) SDK or later. Use the SDK representing the oldest version of Mac OS X you wish to support, keeping in mind that the first version of Mac OS X to be shipped on Intel-based systems was Mac OS X 10.4.4.
Building for PowerPC-based Mac computers
The PowerPC side of your KEXT should be built using the Mac OS X SDK representing the oldest version of Mac OS X you wish to support.
Building for PowerPC-based Mac computers: Targeting Versions of Mac OS X Earlier than 10.4
Building for versions of Mac OS X prior to 10.4 also requires you to build using GCC 3.3.
Building for PowerPC-based Mac computers: Targeting Mac OS X 10.4.x Using Xcode 2.2.x or Xcode 2.3
When using Xcode 2.2.x or 2.3, I/O Kit drivers targeting Mac OS X 10.4.x on PowerPC-based systems must be built using the Mac OS X 10.4.0 (not Universal) SDK. This is different from universal applications where the 10.4u (Universal) SDK can be used on both architectures.
The 10.4.0 SDK is available as a stand-alone installer from the Apple Developer Connection web site. A read me file is available for the SDK installer.
The 10.4.0 SDK can also be installed from the Xcode 2.0 installer, located on the Mac OS X 10.4 install DVD. It can be found in the Xcode custom installs under Cross Development.
Building for PowerPC-based Mac computers: Targeting Mac OS X 10.4.x Using Xcode 2.4 or Later
Beginning with Xcode 2.4 there is another option, which is to define the preprocessor symbol KPI_10_4_0_PPC_COMPAT when building for the PowerPC architecture. When this preprocessor symbol is defined, the 10.4u (Universal) SDK will give the same results as using the 10.4.0 SDK. The same SDK can then be used for both PowerPC and Intel architectures.
If your project is not configured properly you will see the error described later in Common Problems with Universal I/O Kit Drivers when you try to load your driver.
Preparing Your Project to Build an Universal Driver
To convert a PowerPC-only Xcode I/O Kit driver project to a universal project, first make sure that all targets in your project are native Xcode targets. You can check this by opening your project in Xcode, then select the Project menu and see if the command Upgrade All Targets in Project to Native is enabled. If it is, make a backup copy of your project, then use that command to convert all of your legacy targets to native.
Then, make the following changes to the Project or Target Build settings depending on which version of Xcode you're using. Modify the Project settings if you want the settings to apply to all targets in the project. Modify the Target settings if you want just a particular target to produce a universal KEXT.
Xcode 2.x Build Settings
Using the proper SDK and compiler versions is easily accomplished using Xcode's per-architecture build settings.
Set
Architecturestoppc i386. This can be done by double-clicking the wordArchitecturesand then selecting both thePowerPCandIntelcheckboxes.Remove any setting for
SDK PathandVALID_ARCHSby selecting the option and then clicking the-button at the bottom of the window.Add the custom settings
SDKROOT_i386andSDKROOT_ppc. Set the value of each to the path of the SDK to use to build on each architecture.SDKROOT_i386should be set to/Developer/SDKs/MacOSX10.4u.sdkandSDKROOT_ppcshould point to the SDK matching the oldest major Mac OS X release you wish to support, such as/Developer/SDKs/MacOSX10.2.8.sdk.Add the settings
GCC_VERSION_i386andGCC_VERSION_ppcthat specify the compiler version to use when building for each architecture.GCC_VERSION_i386must be set to4.0or greater. If you want to support versions of Mac OS X prior to 10.4,GCC_VERSION_ppcmust be set to3.3.If you are using Xcode 2.4, 2.4.1, or 2.5, and the PowerPC side of your KEXT is targeting Mac OS X 10.4.x, add the setting
PER_ARCH_CFLAGS_ppcthat specifies compiler flags to pass to GCC only when building for the PowerPC architecture. Set the value ofPER_ARCH_CFLAGS_ppcto-DKPI_10_4_0_PPC_COMPAT.Set
Mac OS X Deployment TargettoCompiler Default.Add the settings
MACOSX_DEPLOYMENT_TARGET_i386andMACOSX_DEPLOYMENT_TARGET_ppc. These settings must have the value of a major Mac OS X release version number such as10.2or10.4. Do not specify software update versions such as 10.3.9.MACOSX_DEPLOYMENT_TARGET_i386must be set to10.4or later, andMACOSX_DEPLOYMENT_TARGET_ppcshould be set to the oldest major Mac OS X release you wish to support.
Xcode 3.0 Build Settings
Xcode 3.0 provides an improved user interface for per-architecture build settings over Xcode 2.x.
Set the
Configurationmenu at the top of the window toAll Configurations.Single click the value of the build setting
Architecturesand change it toi386 ppc.Set
Base SDKto/Developer/SDKs/MacOSX10.4u.sdkif the Intel side of your KEXT is targeting Mac OS X 10.4 or/Developer/SDKs/MacOSX10.5.sdkif targeting Mac OS X 10.5.If you want to use a different SDK when building for the PowerPC architecture, select the
Base SDKbuild setting, then selectAdd Per-Architecture Setting Forfrom the action menu at the lower left corner of the window and selectPowerPCfrom the submenu. Change the value of thePowerPCsetting just added to the path of the desired SDK for the PowerPC architecture, such as/Developer/SDKs/MacOSX10.3.9.sdk.Set
Debug Information FormattoDWARF with dSYM File.If you need to use GCC 3.3 when building for the PowerPC architecture, select the
Debug Information Formatbuild setting, then selectAdd Per-Architecture Setting Forfrom the action menu at the lower left corner of the window and selectPowerPCfrom the submenu. Change thePowerPCsetting just added toStabsusing the popup menu to the right.Add the user-defined setting
GCC_VERSIONand set its value to4.0.If you want to support versions of Mac OS X prior to 10.4 when building for the PowerPC architecture, select the
GCC_VERSIONbuild setting, then selectAdd Per-Architecture Setting Forfrom the action menu at the lower left corner of the window and selectPowerPCfrom the submenu. Change the value of thePowerPCsetting just added to3.3.Set
Mac OS X Deployment TargettoMac OS X 10.4or later.If you want to support versions of Mac OS X prior to 10.4 when building for the PowerPC architecture, select the
Mac OS X Deployment Targetbuild setting, then selectAdd Per-Architecture Setting Forfrom the action menu at the lower left corner of the window and selectPowerPCfrom the submenu. Change the value of thePowerPCsetting just added to the oldest major Mac OS X release you wish to support using the popup menu to the right.If the PowerPC side of your KEXT is targeting Mac OS X 10.4.x, select the
Other C Flagsbuild setting, then selectAdd Per-Architecture Setting Forfrom the action menu at the lower left corner of the window and selectPowerPCfrom the submenu. Change the value of thePowerPCsetting just added to-DKPI_10_4_0_PPC_COMPAT.
Xcode 3.1 Build Settings
Xcode 3.1 uses conditional build settings in place of the per-architecture build settings used by Xcode 2.x and 3.0.
To convert a PowerPC-only Xcode I/O Kit driver project to a universal project, first make sure that all targets in your project are native Xcode targets. You can check this by opening your project in Xcode, then select the Project menu and see if the command Upgrade All Targets in Project to Native is enabled. If it is, make a backup copy of your project, then use that command to convert all of your legacy targets to native.
Then, make the following changes to the Project or Target Build settings. Modify the Project settings if you want the settings to apply to all targets in the project. Modify the Target settings if you want just a particular target to produce a universal KEXT.
Set the
Configurationmenu at the top of the window toAll Configurations.Set
ArchitecturestoStandard (32-bit Universal).Set
Base SDKto10.4or later.If you want to use a different SDK when building for the PowerPC architecture, select the
Base SDKbuild setting, then selectAdd Build Setting Conditionfrom the action menu at the lower left corner of the window. Change theAny Architecturesetting toPowerPCand select the desired SDK for the PowerPC architecture from the popup menu to the right.Uncheck the
Build Active Architecture Onlycheckbox.Set
Debug Information FormattoDWARF with dSYM File.If you need to use GCC 3.3 when building for the PowerPC architecture, select the
Debug Information Formatbuild setting, then selectAdd Build Setting Conditionfrom the action menu at the lower left corner of the window. Change theAny Architecturesetting toPowerPCand selectStabsfrom the popup menu to the right.Set
C/C++ Compiler VersiontoGCC System Version (4.0).If you want to support versions of Mac OS X prior to 10.4 when building for the PowerPC architecture, select the
C/C++ Compiler Versionbuild setting, then selectAdd Build Setting Conditionfrom the action menu at the lower left corner of the window. Change theAny Architecturesetting toPowerPCand selectGCC 3.3from the popup menu to the right.Set
Deployment TargettoMac OS X 10.4or later.If you want to support versions of Mac OS X prior to 10.4 when building for the PowerPC architecture, select the
Deployment Targetbuild setting, then selectAdd Build Setting Conditionfrom the action menu at the lower left corner of the window. Change theAny Architecturesetting toPowerPCand select the oldest major Mac OS X release you wish to support from the popup menu to the right.Check the
Kernel Development Modecheckbox.If the PowerPC side of your KEXT is targeting Mac OS X 10.4.x, select the
Other C Flagsbuild setting, then selectAdd Build Setting Conditionfrom the action menu at the lower left corner of the window. Change theAny Architecturesetting toPowerPCand set the value to the right to-DKPI_10_4_0_PPC_COMPAT.
Common Problems with Universal I/O Kit Drivers
Most problems you'll encounter after building a universal driver will appear when loading it. For example, kextload might report the error
com.mycompany.driver.MyDriverClass is not compatible with its superclass, <superclass name> superclass changed? |
The reason for most load-time errors is that the wrong SDK was used when building the driver. For example, the PowerPC side of the driver is targeting Mac OS X 10.3.x but was built using the 10.4u SDK. Refer to the SDK version information shown earlier in Which Xcode and Mac OS X SDK Versions to Use. Then verify that your Xcode project is set up as described earlier in Xcode 2.x Build Settings, Xcode 3.0 Build Settings, or Xcode 3.1 Build Settings.
Document Revision History
| Date | Notes |
|---|---|
| 2018-05-17 | Moved to Retired Documents Library. |
| 2008-08-18 | Updated for Xcode 3.x. |
| 2006-11-10 | Added note about binary compatibility of IOSCSIParallelInterfaceController. |
| 2006-08-25 | Updated for Xcode 2.4. |
| 2006-02-02 | New document that how to build a universal I/O Kit kernel driver while avoiding common pitfalls. |
Copyright © 2018 Apple Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2018-06-04