When running non-modified retail version of Mac OS X on a generic PC, a special boot loader is needed in order to trick the vanilla Apple operating system to think it’s running on a genuine Mac[1]. One of these boot loaders is called Chameleon[2]. But Chameleon installation requires some tweaking in order to do the magic. It’s not enough just to install Chameleon on the system disk but you also need some hardware-specific configuration in order to enjoy a fully working Hackintosh system.

The configuration consists of multiple files. You could install these files directly to the system disk you’re booting from or the EFI file partition if using hard disk with GPT partition layout. But it’s also possible to bundle all the needed stuff except boot configuration inside a single disk image file which Chameleon loads on startup and reads the files inside the image. This way you only need to install this preboot image file and boot configuration file and your system disk remains less polluted. I find this approach much more appealing as it allows me to keep the system as clean as possible.

In this guide we’re going to create a Chameleon preboot image from the scratch in a generic way. It is assumed that the machine and motherboard in particular in use has good compatibility with vanilla Mac OS X Snow Leopard. In practice this means Intel Core 2 processor with Intel chipset on the motherboard. You’ll also need a working Mac OS X 10.5 or 10.6 installation running on a genuine Mac or Hackintosh with root shell access. The whole process is being done in the shell using command-line tools. Also if you’re going to patch your DSDT, you’re probably going to need a way to boot Linux on the machine if you don’t have Mac OS X already installed. Ubuntu Live CD would do it just fine[3].

Preparing the preboot image

  1. Create the preboot disk image and mount it. We’re using the file ~/Desktop/Hackintosh/Preboot.dmg in this guide.

    ~: $ hdiutil create -size 4m -layout MBRSPUD -fs HFS+ -uid 0 -gid 0 \
            -volname Preboot ~/Desktop/Hackintosh/Preboot.dmg
    ~: $ hdiutil attach -noverify ~/Desktop/Hackintosh/Preboot.dmg
  2. Write down the device name for the preboot disk. In the guide we’re using /dev/disk3.

  3. Fix the preboot mountpoint so that file can be owned by root.

    ~: $ sudo diskutil enableOwnership /dev/disk3s1
  4. Mark the file system so that fseventsd doesn’t keep any logs there.

    ~: $ sudo rm -rf /Volumes/Preboot/.fseventsd
    ~: $ sudo install -o root -g admin -m 700 -d /Volumes/Preboot/.fseventsd
    ~: $ sudo touch /Volumes/Preboot/.fseventsd/no_log
    ~: $ sudo chmod 400 /Volumes/Preboot/.fseventsd/no_log
    ~: $ sudo chown root:admin /Volumes/Preboot/.fseventsd/no_log

Kernel extensions

Chameleon needs to load some kernel extensions prior to booting the Mac OS X kernel in order to fix some issues running the Apple operating system on non-Apple hardware. Also Mac OS X may not include drivers for all of your hardware so you need to add any 3rd party drivers that your hardware needs to function. You can read this article[4] to find more about kernel extensions.

  1. Create directory to hold the kernel extensions. You must not change the path as Chameleon expects to find the kernel extensions under Extra/Extensions directory under the root of the preboot volume.

    ~: $ sudo mkdir -p /Volumes/Preboot/Extra/Extensions
  2. Download the following mendatory kernel extensions saving each .kext file under /Volumes/Preboot/Extra/Extensions.

    • fakesmc.kext [5],[6]
      • System Management Controller emulator. Mac OS X won’t boot on a Hackintosh without this.
    • OpenHaltRestart.kext [7]
      • Fixes shutdown/restart issues.
  3. You may want to include the following additional generic kernel extensions.

  4. Download any 3rd party driver kernel extensions for your hardware and place them under /Volumes/Preboot/Extra/Extensions too. Good places to find additional kernel extensios are[11] and myHack[10]. For a real-world example, you can read my posting Technical details of my Hackintosh installation.

  5. Fix permissions and ownership of the kernel extensions. Kernel extensions won’t load if the files are not owned by root:wheel[12].

    ~: $ sudo find /Volumes/Preboot/Extra/Extensions -type f -exec chmod 644 {} \;
    ~: $ sudo find /Volumes/Preboot/Extra/Extensions -type d -exec chmod 755 {} \;
    ~: $ sudo chown -R root:wheel /Volumes/Preboot/Extra/Extensions
  6. Create/update extensions cache

    ~: $ sudo kextcache -m /Volumes/Preboot/Extra/Extensions.mkext /Volumes/Preboot/Extra/Extensions

Patch DSDT

DSDT[13],[14] is an ACPI table that is stored in the BIOS. In order to work correctly, some functionality in Mac OS X depends on features of the DSDT that can be found on Macs. The DSDT in your generic PC’s BIOS might be incorrect or buggy when used with Mac OS X. Chameleon supports overriding the DSDT provided by your hardware with a version loaded prior to loading the operating system. Thus you can create a patched DSDT for your hardware based on your original DSDT that is also compatible with Mac OS X and make your Hackintosh behave well without modifying hardware or BIOS.

The plan for DSDT patching is straightforward.

  1. First you need to extract the DSDT binary code in AML format (ACPI Machine Language) wired to your BIOS.

  2. Then you decompile the AML binary to ASL (ACPI Source Language), which is source code to the AML binary in ASCII format.

  3. Edit the AML source code to patch in any desired fixes.

  4. Compile the patched AML source to get an updated DSDT AML binary file.

  5. You need to include the resulting DSDT AML binary file in the Chameleon preboot environment so Chameleon can find and load it and override the built-in DSDT with the patched one on system startup.

For decompilation and compilation of DSDT you need Intel ASL compiler/decompiler[15]. For Debian/Ubuntu, the tool is available in the package iasl[16]. Mac version[17] is also available. The iasl binary is stored in the Tools directory of the linked download.

Actual changes to the DSDT are always dependant on the combination of particular hardware and BIOS version so I’ll go through these steps here in a generic way.

Extracting the DSDT AML binary

In Linux, the DSDT extraction is a breeze as the blob available under the /proc file system[14]. Just run

    ~: $ sudo install -o `whoami` /proc/acpi/dsdt ~/dsdt-original.aml

and you have a copy of your DSDT AML binary in the file ~/dsdt-original.aml.

In Mac OS X you can extract the DSDT AML binary to the file ~/Desktop/Hackintosh/dsdt-original.aml by running the following command:

    ~: $ ioreg -lw0 | perl -pne'$_=pack"c*",map{hex}unpack"(A2)*",($_=~/"DSDT"=<([^>]+)/)[0]' \
            > ~/Desktop/Hackintosh/dsdt-original.aml

Note that if running Mac OS X, be sure that the system doesn’t have a patched currently DSDT applied or you won’t be able to extract the original DSDT in the BIOS!

Decompiling DSDT AML binary to ASL source

Use the following iasl command to decompile the DSDT AML binary ~/Desktop/Hackintosh/dsdt-original.aml and save it as ASL source file ~/Desktop/Hackintosh/dsdt.dsl:

    ~: $ iasl -d ~/Desktop/Hackintosh/dsdt-original.aml && \
            mv ~/Desktop/Hackintosh/dsdt-original.dsl ~/Desktop/Hackintosh/dsdt.dsl

Editing the DSDT ASL source

Now you can edit the file ~/Desktop/Hackintosh/dsdt.dsl and fix any hardware-specific problems with the DSDT. I’ve documented the needed DSDT patches for one of my systems in the posting Technical details of my Hackintosh installation. Many of these patches are quite generic.

Compiling ASL source to DSDT AML binary

After applying the desired set of patches, compile the ASL source back to a DSDT AML binary file ~/Desktop/Hackintosh/dsdt.aml with the following command:

    ~: $ iasl ~/Desktop/Hackintosh/dsdt.dsl

Configuring Chameleon preboot image to load the DSDT AML binary

Let’s say you have the modified DSDT AML binary saved as the file ~/Desktop/Hackintosh/dsdt.aml. In order for Chameleon to find and load the patched DSDT, the file needs to be installed as Extra/dsdt.aml under the preboot image root. So copy it like this:

    ~: $ sudo install -o root -g wheel -m 644 ~/Desktop/Hackintosh/dsdt.aml /Volumes/Preboot/Extra

Customizing SMBIOS

System Management BIOS or SMBIOS stores some details about your hardware[18],[19]. In Mac OS X you can view the current SMBIOS information with System Chameleon allows customization of the SMBIOS values. You can do this by creating the file Extra/smbios.plist under the preboot image root. You could use this feature to make your Hackintosh mimic some existing Mac model or you could provide your own values. It’s all optional, though. But If you want to do that, then read these articles[20],[21],[22] for more details and save the resulting file as /Volumes/Preboot/Extra/smbios.plist.

Here is a sample smbios.plist which gives the system a custom serial number.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "">
<plist version="1.0">

Configure Chameleon to use the preboot image

By default Chameleon tries to find DSDT and SMBIOS data from the system disk. In order to instruct Chameleon to use the preboot image, the file RAMDisk.plist needs to be added to the root directory of the preboot file system. So save the this as /Volumes/Preboot/RAMDisk.plist.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "">
<plist version="1.0">

Finalize preboot image

  1. Cleanup preboot file system

    ~: $ sudo find /Volumes/Preboot -type f -exec chmod 644 {} \;
    ~: $ sudo find /Volumes/Preboot -type d -a ! -name .fseventsd -exec chmod 755 {} \;
    ~: $ sudo chown -R root:wheel /Volumes/Preboot
    ~: $ sudo find /Volumes/Preboot -name .DS_Store -exec rm {} \;
    ~: $ sudo rm -rf /Volumes/Preboot/.Trashes
  2. Eject the preboot disk

    ~: $ hdiutil eject /dev/disk3

The preboot image ~/Desktop/Hackintosh/Preboot.dmg is now ready to be deployed in the Extra directory of a Chameleon boot disk.