You also need to prepare yourself for a probably very long and enduring polishing process. Yes, you only have to do it once, in the future you can use already prepared and patched DSDT and other files, but you still will probably reboot a hundred times and will see a hundred of kernel panics before your have your own perfect DSDT and other fixes.
I base this guide on my ThinkPad T60p, but I suppose most of my DSDT examples will work on any ThinkPad 60/61-series machine, because their DSDT should be very similar (I've compared T60p to T61 DSDT-wise, and they were almost identical). Anything older or newer should be double checked before applying any patches. But in general this guide should help owners of any laptops.
The goal of this guide is not to keep /System/Library/Extensions 100% vanilla, but also to reduce the amount of custom kexts to a bare minimum making as many things work "out of the box" as possible.
Updates
I will update this guide with new techniques and fixes as long as I keep finding the ones worth using, and I will list here any updates I've made so that you don't have to read this entire thing again to find out what's new.
- Feb 27, 2010 - Added chapter with some general information on bootloaders, updated Restart and UUID fixes with AsereBLN Booter related information, uploaded fresh version of my /Extra folder.
- Apr 05, 2010 - Reuploaded /Extra and DSDT files to MediaFire, removed deprecated links to patched bootloader and PS2 kexts.
Basic glossary
- Kext - kernel extension or a driver in the world of OSX. Essentially every kext is a folder with .kext "extension" containing xml and binary files.
- /System/Library/Extensions (further /S/L/E) - system folder with all OSX kexts.
- /Extra/Extensions (further /E/E) - a separate folder for custom kexts to separate them from vanilla kexts.
- Patched kext - original system driver that is modified to work for us. You can either modify some xml settings or patch the binary code. Usually stored in /S/L/E replacing original kext.
- Custom kext - a kext that is not a part of original OSX package. It can be stored in both /E/E and /S/L/E, but in the latter case it doesn't replace anything.
So, let me start with a brief explanation why should you bother with that DSDT patching and entirely 100% vanilla /S/L/E folder when there's a bunch of guides with patched kexts available, which work without too much hassle.
The problem with patched kexts is that they are not upgrade-proof. Yes, they work in a given OSX version, but when Apple releases an upgrade, all patched kexts in /S/L/E are overwritten and some kexts in /E/E might stop working or even raise kernel panics. And you will then need to look for newer versions of those kexts, and also need to remember what you have to patch in /S/L/E. And if you put a custom kext to /S/L/E it's hard to find it later if you suddenly need to remove it or change (our memory is a tricky thing).
As an example, current patched version of IOATAFamily.kext that works well with 10.6.2 is reported to raise kernel panic in 10.6.3 beta, so there you go, already a problem.
DSDT patching makes your system look to OSX more Mac-like. Of course, since you are not using original Mac, there's no 100% guarantee that any future system updates won't break your setup. With hackintoshes one always has to read what other people saying about a fresh system update before proceeding. But vanilla /S/L/E and minimal amount of custom kexts in /E/E significantly raise your chances of successful update.
Overview
I've mentioned that DSDT patching is only a part of what we are going to do to achieve as vanilla OSX as possible. Some other things that I'm going to cover here:
- Latest/patched Chameleon bootloader
- Custom Mac model in SMBIOS and other information there
- EFI strings injection
- Legacy kext creation
Before you continue with full scale DSDT patching (and all other things) you need to do the following:
- Upgrade your BIOS to the latest version if you haven't already. Often BIOS upgrades contain fresh version of DSDT, because it is a part of BIOS. For T60p the latest version (the one I use as reference) is 2.25, but it's not very different from 2.23, DSDT is the same for both versions.
- Change BIOS options to make them as final as possible for you. With some laptops/motherboards changes in BIOS enable or disable parts of code in DSDT (DSDT tables are regenerated when you make changes). It doesn't look to be the case with ThinkPads, but still.
- It's better to have a couple of other systems you can boot into. I have Windows Vista and Leopard 10.5.6 on an internal drive and I was installing Snow Leopard to external USB drive. Booting to Leopard can solve some of your problems when you can't boot to SnowLeo after some nasty changes you've made.
- Some guides about installation of Snow Leopard on PC using vanilla installer. There's a bunch of those guides in your Google, I've used that one, but feel free to look for more detailed guides.
My configuration
I have ThinkPad T60p which I've upgraded over the years, so the model number is irrelevant.
- CPU: Intel Core 2 Duo 2.33GHz
- RAM: 4GB
- Video: ATI Mobility FireGL V5200 256MB, screen resolution is 1400x1050
- Wireless: Atheros a/b/g/n
As the result of everything that is described in this guide I have the following:
- /System/Library/Extensions 100% vanilla - no kexts touched, deleted or added.
- /Extra/Extensions contains only the following kexts: FakeSMC.kext, AppleACPIPS2Nub.kext, ApplePS2Controller.kext, AppleACPIBatteryManager.kext, VoodooHDA.kext, LegacyT60p.kext, ATINDRV.kext, VoodooTSCSync.kext.
- In /Extra I have additional files supporting my fixes: dsdt.aml, fadt.aml, com.apple.Boot.plist, SMBIOS.plist.
The following is working:
- Video works (QE/CI and resolution change) with ATI EFI strings injected through com.apple.Boot.plist and legacy ATI framebuffers in ATINDRV.kext.
- Brightness slider in Display preferences with DSTD patch, but uneven brightness control.
- Vanilla SpeedStep works (P-states and C-states) with custom Mac model in SMBIOS.plist, patch to DSDT and LegacyT60p.kext.
- Vanilla IOATAFamily.kext - DSDT patch.
- Native AHCI driver - DSDT patch.
- No need to remove /S/L/E/AppleHDA.kext to allow VoodooHDA.kext to work - DSDT patch.
- Restart works with AsereBLN Booter 1.1.9 with embedded restart fix.
- UUID fix is applied automatically by AsereBLN Booter 1.1.9.
- Going to Sleep on lid close - DSDT patch.
- Shutdown works OOB.
- Bluetooth works OOB with some minor quirks.
- AHCI and ATA injectors not needed on ThinkPads, everything works OOB.
- Atheros wireless drivers load automatically in x64 mode with LegacyT60p.kext fix.
- Both 32-bit and 64-bit modes work fine (with Core2Duo CPU), but proper ATI framebuffer is not available for x64. Shame.
- Sleep. I've spent two weeks chasing this one, but no luck. If I have more news, I will update this post.
- Firewire. Do not have it, so can't check. Post your solution here if you find it.
- External display. Didn't check, but I expect it to be broken/buggy, need to play with ATI EFI strings to make it 100% functional.
Here's my BIOS configuration:
- SATA is set to AHCI mode.
- In Power settings Intel Speed Step is enabled with both AC and Battery set to Automatic.
- Thermal settings are all set to Maximize Performance.
- CPU Power Management is set to Automatic.
- Display brightness is set to Normal.
- And Memory Protection (under Security) is enabled.
- Disabled InfraRed, Serial Port and COM port.
Before patching you need to prepare your own ACPI tables (DSDT is only a part of entire ACPI tables list, and you will need to have all of them). I strongly advise against blindly using someone else's DSDT, even if they have the same ThinkPad model as you.
To extract ACPI tables (including DSDT) I suggest to use Everest Lavalys utility which is shareware and works in Windows. After you install it and run, right click on the bottom status bar, select "ACPI Tool" and then "Extract table". There's a large list of tables, you need to extract them all one by one. Then put them on a USB drive or somewhere you can access from your OSX. They will be in the binary form (not readable in text editor), but you shouldn't worry.
Snow Leopard installation
You can install Snow Leopard any way you prefer, but it's important to use vanilla installation DVD image and not a pre-packaged (hacked) one. You can either install SnowLeo from Leopard to an external USB drive, or you can prepare a USB drive with an installer and then boot to this USB drive to install.
Most of the guides include some custom and patched kexts to put to /S/L/E, which we want to keep vanilla. Not to worry, you can make a copy of either entire /S/L/E or only of those kexts you are overwriting. I use the following commands to do that:
Code: Select all
cd /System/Libary/Extensions
mv SomeKextToPatch.kext SomeKextToPatch.kext.original
cp -r /Volumes/YourUSBDrive/SomeKextToPatch.kext /System/Library/Extensions/
You can also start patching from existing Leopard installation or from Windows, but in this guide I'm relying on OSX tools, so you need to download some tools for Windows yourself. Patching from Leopard also works fine, but the problem is that it's difficult to test if your changes work, you need to apply many patches all together before trying to boot, and if it doesn't work you will not understand which of the applied patches failed. So I suggest to have a SnowLeo installation you can boot into and then proceed with experiments.
Bootloader
Many people, who decide to jump into the wonderful world of hackintoshes, underestimate the importance of a bootloader they choose. Now it seems that Chameleon v2 is the bootloader of choice. At the moment of writing its latest version is RC4. But there are a lot of people who use Chameleon source code to create their own patches and fixes. And since Chameleon has a lot of bugs on its own, some people also decide to fix Chameleon bugs to make it more stable and reliable.
I've come across a brilliant new bootloader that is based on Chameleon code. A man named AsereBLN did a great job fixing original code and introduced some great automatic fixes, like restart fix and SMBIOS values automatic detection. Follow the link below to the original forum thread with a full description of what has been done.
I know that some of us prefer to have better control of what is happening during boot and don't trust a bootloader to do something automatically. I'm on the other side, and the less things I have in my /Extra the better, because it means the less things I have to change/check if something is wrong.
Get the latest version of AsereBLN Booter (1.1.9 at the time of writing) here. Unpack it somewhere and then install from your Terminal with the commands below. Make sure you don't type my comments into terminal, they are only for your better understanding of the process.
Code: Select all
/* grant yourself a superuser access for this session */
sudo -s (to gran)
cd /folder_where_you_have_your_bootloader_unpacked/
/* now find out what is the system location for the drive and partition you installed OSX to */
df /
/* let's assume it's /dev/disk1s2 */
/* install boot0 to the MBR */
fdisk -f boot0 -u -y /dev/rdisk1
/* install boot1h to the partition's bootsector */
dd if=boot1h of=/dev/rdisk1s2
/* Install boot to the partition's root directory */
cp boot /
By default AsereBLN Booter doesn't include any GUI theme inside its code to make it lighter. If you want to use a theme, place it into your /Extra/Themes and then update your com.apple.Boot.plist to include that theme's name:
Code: Select all
<key>Theme</key>
<string>Bullet</string>
AsereBLN Booter also allows you to set the system type. By default all Chameleon versions assume that you have a desktop computer, which means Energy Saver preferences won't contain any trace of your Battery settings. SO you need to set your system type to laptop by adding the following parameter to your com.apple.Boot.plist:
Code: Select all
<key>system-type</key>
<string>2</string>
Tools to use
- DSDTSE - this is a brilliant tool for DSDT compilation/decompilation. It contains a small database of fixes, an editor with syntax highlighting and a comparison tool. It doesn't patch DSDT automatically. The editor is a bit slow, so I use it only for minor fixes, but I use DSDTSE for easy DSDT compilation. There's now a Windows version available, but I haven't tried it yet. For all the latest updates check www.osx86.es.
- Any advanced text editor with syntax coloring, I use TextMate. I've mentioned DSDTSE is a bit slow, so what I do is I open a DSDT.dsl (decompiled) file in TextMate, make changes, save it, then double click on DSDT.dsl and DSDTSE opens. I then click "Compile", and DSDT.aml (compiled) file is produced in the same folder I have DSDT.dsl in. I then copy it to /Extra and reboot.
- IORegistryExplorer - this is part of Xcode, but you can download it separately (for example here). I use this tool to analyze if the changes to DSDT worked and to see if I need to make any other changes. I also use it to analyze original Macs' IOReg dumps.
- PlistEdit Pro - essential tool for plist files editing. Download, install and forget about original plist editor. Download it here.
- pfix - this is great little utility for generation of kext caches and fixing permission. The way OSX works with drivers it doesn't read them one by one during boot. It loads single Extensions.mkext file. System usually generates this file automatically for /S/L/E if you touch it, but it's not generated for /E/E. A lot of custom and patched kexts, if placed in /E/E, can only be loaded as a part of pre-generated Extensions.mkext file for /E/E, but you need to do it yourself manually. Simply run pfix from your Terminal and follow simple instructions. Download pfix from here.
- 1. Boot to SnowLeo for the first time.
- 2. Copy provided custom Chameleon bootloader to the root of your SnowLeo drive.
- 3. Install DSDTSE.
- 4. Double click on your previously extracted DSDT.aml (or DSDT.dsl if it's already decompiled). DSDTSE should open.
- 5. Click "Compile" button. DSDSE will tell you that DSDT needs to be saved first. Decompiled version will be saved to ~/Library/Application Support/EvOSoftware/DSDT/DSDTFiles.
- 6. After compilation Finder window with that folder will open, two files will be there - DSDT.aml and DSDT.dsl. I suggest you to save this folder location to Places on your left sidebar or make an alias on Desktop (it's a pain locating it every time).
- 7. Make a copy of DSDT.dsl to have a backup. Simply Alt-drag it somewhere within the same folder.
- 8. Make a desired patch/fix to DSDT.dsl with your favorite text editor (DSDTSE is not the best option here).
- 9. Open DSTD.dsl with DSDTSE and click "Compile" again. Proceed if there are no compilation errors.
- 10. Move resulting DSDT.aml to /Extra. You can place /Extra on your Finder sidebar as well to make this move with a single drag and drop.
- 11. If you've made ANY changes to kexts in either /S/L/E or /E/E - run pfix!
- 12. Reboot.
- 13. If you booted to SnowLeo successfully, go to /Extra and copy DSDT.aml to DSDT_stable.aml. If your further patches raise kernel panic during boot, you can type the following command in Chameleon: DSTD=/Extra/DSDT_stable.aml and it will use that older and stable version of DSDT. Lifesaver!
- 14. Repeat steps 7-13 as many times as you need to apply all patches.
Before you actually make your own patches I suggest you to study my DSDT. I've commented all my fixes there, just search for "fix " and you will find them.
General DSDT information
DSDT is the part of ACPI which in turn is the essential part of your BIOS. It contains some basic information about devices in your ThinkPad, defines their start-up sequences and provides basic means for their communication between each other. This is very high level of course.
All ACPI tables are written in AML machine language with is decompiled into something that looks very similar to C++. Only very basic and simple commands are supported.
DSDT is the biggest ACPI table and it contains the main devices tree and standard methods. For example, method _PTS (prepare to sleep) is called by the operating system before going to sleep so that proper sleep commands can be issued to all devices, and method _WAK is called upon waking.
The device tree in DSDT can be imagined through the folders analogy. You have a PCI0 bus device which has video, audio and other devices inside. In DSDT they are defined inside PCI0 device scope, the result is folder-like structure (e.g. PCI0->LPC->LDRC).
Some methods in DSTD are global, some methods are defined for particular devices.
Most devices names are only 4 letters and they are not universal (names depend on manufacturer of hardware), but most of them have universal IDs defined inside as a property (Name (_HID, EisaId ("PNP0C0E")), you can google "PNP0C0E" to find out what it is).
We are not patching BIOS itself, but using patched DSDT.aml. Chameleon is feeding this fake DSDT table to OSX on the fly. It's very difficult to harm your hardware with this method, and you are guaranteed that you will be able to boot later no matter what (just need to delete broken DSDT.aml).
Common patches
The following patches are common for everyone and you can safely apply them.
DTGP method. You need to have it in your DSDT for many other fixes that inject some custom parameters for your devices. I put it above _WAK method, but it can defined be anywhere on the highest scope level (not inside any devices).
Code: Select all
Method (DTGP, 5, NotSerialized)
{
If (LEqual (Arg0, Buffer (0x10)
{
/* 0000 */ 0xC6, 0xB7, 0xB5, 0xA0, 0x18, 0x13, 0x1C, 0x44,
/* 0008 */ 0xB0, 0xC9, 0xFE, 0x69, 0x5E, 0xAF, 0x94, 0x9B
}))
{
If (LEqual (Arg1, One))
{
If (LEqual (Arg2, Zero))
{
Store (Buffer (One)
{
0x03
}, Arg4)
Return (One)
}
If (LEqual (Arg2, One))
{
Return (One)
}
}
}
Store (Buffer (One)
{
0x00
}, Arg4)
Return (Zero)
}
Code: Select all
Device (RTC)
{
Name (_HID, EisaId ("PNP0B00"))
Name (_CRS, ResourceTemplate ()
{
IO (Decode16,
0x0070, // Range Minimum
0x0070, // Range Maximum
0x01, // Alignment
0x02, // Length
)
/* Fix - RTC fix
IRQNoFlags ()
{8}
Fix End */
})
}
Code: Select all
Device (HPET)
{
Name (_HID, EisaId ("PNP0103"))
Name (_CID, EisaId ("PNP0C01"))
Name (_STA, 0x0F)
Name (_CRS, ResourceTemplate ()
{
IRQNoFlags ()
{0}
IRQNoFlags ()
{8}
Memory32Fixed (ReadOnly,
0xFED00000, // Address Base
0x00000400, // Address Length
)
})
}
IOATAFamily.kext kernel panic fix
In both your SATA and IDE0 devices insert the following code above GPCT method
Code: Select all
Field (IDCS, DWordAcc, NoLock, Preserve)
{
Offset (0x40),
PRIT, 16,
SECT, 16
}
Method (_INI, 0, NotSerialized)
{
Store (0xE307, PRIT)
Store (0xC000, SECT)
}
Code: Select all
\_SB.PCI0.PATA._INI ()
\_SB.PCI0.SATA._INI ()
Insert the following above GPCT method. Notice how we are using DTGP method defined before.
Code: Select all
Method (_DSM, 4, NotSerialized)
{
Store (Package (0x02)
{
"device-id",
Buffer (0x04)
{
0xC5, 0x27, 0x00, 0x00
}
}, Local0)
DTGP (Arg0, Arg1, Arg2, Arg3, RefOf (Local0))
Return (Local0)
}
Many DSDT versions including the one on ThinkPad have different checks in the code for different operating systems. OSX (Darwin) of course is not there, so we need to make sure some advanced ACPI code is enabled for OSX as well.
Insert the following right underneath the block that has all the operating system names checks and above the line If (LGreaterEqual (_REV, 0x02)).
Code: Select all
Store (One, WNTF)
Store (One, WXPF)
Store (0x02, WSPV)
Store (One, WVIS)
The following device needs to be added above LNKA device right after _INI method within Scope (_SB) block.
Code: Select all
Device (PNLF)
{
Name (_HID, EisaId ("APP0002"))
Name (_CID, "backlight")
Name (_UID, 0x0A)
Name (_STA, 0x0B)
}
Insert the following code after Name (_UID, Zero) line inside AC device.
Code: Select all
Name (_PRW, Package (0x02)
{
0x18,
0x03
})
Just comment out or delete your HDEF device:
Code: Select all
/* Fix - Disable AppleHDA.kext auto loading to use VoodooHDA.kext
Device (HDEF)
{
Name (_ADR, 0x001B0000)
Name (_S3D, 0x03)
Name (RID, Zero)
Name (_PRW, Package (0x02)
{
0x05,
0x04
})
Method (_PSW, 1, NotSerialized)
{
Noop
}
}
Fix End */
The following information is outdated. I'm now using brilliant AsereBLN Booter instead of the old Chameleon RC4 which was patched for the restart to work with the below fix.
AsereBLN Booter is based on Chameleon RC code, but it improves it a lot, fixes a number of bugs and introduces some additional automatic fixes, such as this restart fix. You don't have to do anything now, but I leave that part of the guide unchanged for your information. It will help you to better understand what happens behind the scenes when the booter does its trick.
===============
This is a little bit trickier than simple DSDT patching. It is possible that it will be automatically fixed in the next Chameleon, but at the moment you need to use patched Chameleon RC4 that I've provided. I don't remember the source of it, so please point me to the latest version if you know where it is.
Then you need to add the following to your /Extra/com.apple.Boot.plist:
Code: Select all
<key>RestartFix</key>
<string>yes</string>
We are interested in "Reset Register Supported (V2)" and for restart to work it needs to be set to 1, but this is a single bit inside a mentioned block. You cannot make this change in DSDTSE, you need to open your favorite Hex editor (I use 0xED) and find that particular bit. So, in my case I had hex code 0000C2AD inside facp.aml and with the needed bit flipped this part changed to 0000C6AD. Saved facp.aml I renamed to fadt.aml and moved it to /Extra. That's it.[/color]
SMBIOS fix
Before you had to use patched AppleSMBIOS.kext to see proper CPU/Memory information in System Profiler. Latest Chameleon (and all other bootloaders that are based on Chameleon) can do this on the fly by feeding vanilla AppleSMBIOS.kext with fake information which it either automatically guesses for you or takes from SMBIOS.plist in /Extra. Use mine as the reference and update it to match your config. There's a good guide on SMBIOS.plist creation here.
AsereBLN Booter 1.1.9 does wonderful job of guessing most of the SMBIOS information for you. I've removed SMUUID, SMcputype, SMmemspeed and SMmemtype from my SMBIOS.plist after moving to that bootloader. I believe that SMbusspeed might be removed as well with some later version of it, but for now you need to have it set to 0 to see proper bus speed in your Profiler.
Most important parts in SMBIOS.plist are SMbiosversion and SMproductname which are essential for some other fixes and some software proper functionality (more on that later). Other fields should be populated with the right information for your particular hardware (CPU type and clock, bus speed, memory speed and type, etc.), but those are mostly cosmetic.
UUID fix
This is an interesting one. The fix to have proper UUID and to get rid of UUID-related errors in your log has evolved over time. At first you had to use PlatformUUID.kext, then a couple of patches for Chameleon allowed to set UUID from either com.apple.Boot.plist or SMBIOS.plist.
Now you can forget about all the hassle and simply use AsereBLN Booter 1.1.9 or anything that comes out later. It automatically detects proper UUID for you and injects it into SMBIOS, so that OSX feels "safe". Just kidding here.
You still can set UUID manually, if you need. To do so, put it into your com.apple.Boot.plist in /Extra
Code: Select all
<key>SystemID</key>
<string>xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx</string>
Legacy kext
So called "legacy kext" is a great trick to replace any Info.plist in /S/L/E without actually touching /S/L/E. This kext is placed in /E/E and it contains only Info.plist overrides.
Inside legacy kext (in my case it is named LegacyT60p.kext, but you can name it anything you like) there's only single Info.plist. Inside, under IOKitPersonalities sections you can have as many subsections as you like. Let's start with ATIRadeonX1000.kext. As most of you know, to enable proper video we need to patch that kext's Info.plist to inlclude our device id. Here's how it's done via legacy kext.
Empty legacy kext looks like this.
Code: Select all
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleIdentifier</key>
<string>com.silencer.driver.LegacyT60p</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>Legacy fixes for T60p</string>
<key>CFBundlePackageType</key>
<string>KEXT</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>999.9.9</string>
<key>IOKitPersonalities</key>
<dict>
[====this is the part we are going to fill with overrides====]
</dict>
<key>OSBundleLibraries</key>
<dict>
<key>com.apple.iokit.IOGraphicsFamily</key>
<string>1.1</string>
<key>com.apple.iokit.IOPCIFamily</key>
<string>1.0</string>
<key>com.apple.kpi.iokit</key>
<string>8.3.1</string>
<key>com.apple.kpi.libkern</key>
<string>8.3.1</string>
<key>com.apple.kpi.mach</key>
<string>8.3.1</string>
</dict>
<key>OSBundleRequired</key>
<string>Local-Root</string>
</dict>
</plist>
Code: Select all
<key>ATIRadeonX1000</key>
<dict>
<key>ATIEnableWideBlitSupport</key>
<true/>
<key>CFBundleIdentifier</key>
<string>com.apple.ATIRadeonX1000</string>
<key>IOPCIMatch</key>
<string>0x71c41002</string>
[====other fields skipped====]
</dict>
Now if you regenarate mkext caches with pfix and reboot you will see that ATIRadeonX1000.kext loaded fine even though you haven't changed it's Info.plist directly to include your device id.
Here's the fix for Atheros x64 drivers (they are included only in 10.6.2), it goes right after ATI fix. So, as you can see, we can have as many different overrides as we like inside our single legacy kext.
Code: Select all
<key>Atheros Wireless LAN PCI</key>
<dict>
<key>CFBundleIdentifier</key>
<string>com.apple.driver.AirPort.Atheros21</string>
<key>IOClass</key>
<string>AirPort_AthrFusion21</string>
<key>IOMatchCategory</key>
<string>IODefaultMatchCategory</string>
<key>IONameMatch</key>
<array>
<string>pci168c,24</string>
</array>
<key>IOProviderClass</key>
<string>IOPCIDevice</string>
</dict>
Vanilla Speed Step
This is by far the trickiest of all DSDT related fixes. If you are unsure of what you are doing you can use VoodooPowerMini.kext, and it would do the trick for you. But it will not be as effective as vanilla solution, because it doesn't enable C-states.
There are three different CPU states defined in ACPI - P-states, C-states and T-states. We don't care about the latter.
P-states - are actual speed steps, various frequencies/voltages combinations are defined, so that CPU can use less power when it's not under heavy load. You can even adjust those states for undervoltage (Google it) to make your CPU eat less power at the highest frequency.
C-states - are the states of CPU deep sleep, when it almost shuts off its entire core parts when idle. In modern CPUs there are tens of C-states. In Core 2 Duo on mobile platform (different on desktops) four C-states are defined, but only three C-states can work simultaneously (C1, C2, C3 or C1, C2, C4). But it's still more than enough to save a lot of power/temperature. With C-states enabled my CPU core temperature dropped 10-15 degrees Celcius!
SpeedStep functionality in OSX depends on a combination of parameters - DSTD configuration and Mac model. First of all you need to study http://www.everymac.com to find a MacBook or MacBookPro model that is the closest to your ThinkPad in configuration. ThinkPad T60p is using ICH7M platform and with Core 2 Duo 2.33GHz and FireGL V5200 it is almost identical to MacBookPro2,1. If you don't have ATI, and have Intel, your safe choice will be MacBook2,1.
But you cannot use chosen model directly, you need to make your own fake model based on that MacBook family. I've decided that I will use MacBookPro2,3 (there was actual MacBookPro2,2) and I've updated my SMBIOS.plist accordingly:
Code: Select all
<key>SMbiosversion</key>
<string>MBP23.88Z.00A5.B01.0611031449</string>
<key>SMproductname</key>
<string>MacBookPro2,3</string>
This is the kext that restricts or allows SpeedStep and C-states for particular Mac models. Before 10.6.2 all models configuration was stored in Info.plist inside that kext. Now in 10.6.2 there's another folder named Resources with separate configuration plists for each Mac that is supported by SnowLeo.
We are not going to change that kext contents, since we need to keep /S/L/E 100% vanilla. But, we are going to use the information that is stored in MacBookPro2_1.plist.
So, again, the path to the plist is:
/S/L/E/IOPlatformPluginFamily.kext/Contents/PlugIns/ACPI_SMC_PlatformPlugin.kext/Contents/Resources/
We now need to put this information into our legacy kext from above and update it to enable SpeedStep for our custom fake Mac model. But first put into legacy kext the following template inside IOKitPersonalities section (check screenshot above):
Code: Select all
<key>ACPI_SMC_PlatformPlugin</key>
<dict>
<key>CFBundleIdentifier</key>
<string>com.apple.driver.ACPI_SMC_PlatformPlugin</string>
<key>IOClass</key>
<string>ACPI_SMC_PlatformPlugin</string>
<key>IOPlatformThermalProfile</key>
<dict>
[====Here we'll place info from MacBookPro2_1.plist====]
</dict>
<key>IOProbeScore</key>
<integer>1200</integer>
<key>IOPropertyMatch</key>
<dict>
<key>IOCPUNumber</key>
<integer>0</integer>
</dict>
<key>IOProviderClass</key>
<string>AppleACPICPU</string>
<key>IOResourceMatch</key>
<string>ACPI</string>
</dict>
Next we need to enable P-states and C-states. For P-states, edit copied plist configuration to include the following:
Code: Select all
...
<key>ConfigArray</key>
<array>
<dict>
<key>model</key>
<string>MacBookPro2,3</string>
<key>restart-actions</key>
<dict>
<key>cpu-p-state</key>
<integer>0</integer>
</dict>
</dict>
</array>
<key>ControlArray</key>
...
<key>PLimitDict</key>
<dict>
<key>MacBookPro2,3</key>
<integer>0</integer>
</dict>
<key>StepDataDict</key>
....
In IORegistryExplorer you will spot the following. With IOService selected when you open info for CPU0@0->AppleACPICPI->ACPI_SMC_PlatformPlugin on right handside you should see that CPUPlimit is 0x0 and PerformanceStateArray contains 5 values. This means you're golden.
Most of vanilla speed step guides tell you that you also need to put P-states definition in your DSDT. On ThinkPads (at least on T60p) you don't need to do that, P-states definition is picked up by OSX automatically from SSDT tables, so you need to put P-states into DSDT only if you want override them to enable undervoltage for example.
With C-states it is a bit different, but I'm not sure why. To enable C-states you need to find in one of previously extracted SSDT tables the following block Name (C1M4, Package (0x04). This block defines three C-states - C1, C2 and C4. You can also use C1M3 or C1M2 or C1M1 (different combinations of C-states) which are defined within the same SSDT. You should then put it into your DSDT like this:
Code: Select all
Scope (_PR)
{
Processor (CPU0, 0x00, 0x00001010, 0x06) {}
Processor (CPU1, 0x01, 0x00001010, 0x06) {}
}
Scope (\_PR.CPU0)
{
Name (C1M4, Package (0x04)
{
0x03,
Package (0x04)
{
ResourceTemplate ()
{
Register (FFixedHW,
0x01, // Bit Width
0x02, // Bit Offset
0x0000000000000000, // Address
0x01, // Access Size
)
},
0x01, 0x01, 0x03E8
},
Package (0x04)
{
ResourceTemplate ()
{
Register (SystemIO,
0x08, // Bit Width
0x00, // Bit Offset
0x0000000000001014, // Address
,)
},
0x02, 0x01, 0x01F4
},
Package (0x04)
{
ResourceTemplate ()
{
Register (SystemIO,
0x08, // Bit Width
0x00, // Bit Offset
0x0000000000001016, // Address
,)
},
0x03, 0x39, 0x64
}
})
Method (_CST, 0, NotSerialized)
{
Return (C1M4)
}
}
Scope (\_PR.CPU1)
{
Method (_CST, 0, NotSerialized)
{
Return (\_PR.CPU0._CST)
}
}
The last step for C-states is to add a couple of new sub-sections to legacy kext inside IOPlatformThermalProfile section:
Code: Select all
<string>ACPI_SMC_PlatformPlugin</string>
<key>IOPlatformThermalProfile</key>
<dict>
<key>CStateDemotionDict</key>
<dict>
[====skipped, check attached Extra.zip for reference====]
</dict>
<key>CStateDict</key>
<dict>
[====skipped, check attached Extra.zip for reference====]
</dict>
.....
Once you've done all of this and regenerated mkext caches with pfix, reboot and check IORegistryExplorer (see the screenshot above). If you have successfully enabled C-states, you will see CSTInfo parameter. If you don't see it, that means you have no C-states enabled.
That's it, you're done with vanilla speed step. Check CPU temperature (google iStat) and compare it to what you have in Windows or what you've had before your vanilla speed step. You will be surprised.
Clamshell fix
Locate method _LID of the device LID and change it as shown. The idea is to check the Lid register and then if it is closed we notify the Sleep button that it was "pushed".
Code: Select all
Name (LIDS, One)
Method (_LID, 0, NotSerialized)
{
Store (^^PCI0.LPC.EC.HPLD, LIDS)
XOr (LIDS, One, Local0)
If (Local0)
{
Notify (SLPB, 0x80)
}
Return (LIDS)
}
We don't need ATIinject.kext, it's easier to use EFI strings to inject the same information. First, create a simple plist file using the template below.
Code: Select all
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PciRoot(0x0)/Pci(0x1,0x0)/Pci(0x0,0x0)</key>
<dict>
</dict>
</dict>
</plist>
Code: Select all
./gfxutil -i xml -o hex atistrings.plist output.hex
Code: Select all
<key>device-properties</key>
<string>ef1b00.....8c6400</string>
Code: Select all
./gfxutil -f display
Cosmetic DSDT fixes
Some DSDT fixes are meant to be sort of cosmetic. For example, I've renamed all devices in my DSDT to have the same names that are found in original MacBookPro2,1. Theoretically it might be helpful, but there's no proof that it actually does anything. But anyways, here's the rename map:
Code: Select all
LID -> LID0
AGP -> PEGP
VID -> GFX0
EXP0 -> RP01
EXP1 -> RP02
EXP2 -> RP03
EXP3 -> RP04
USB0 -> USB1
USB1 -> USB2
USB2 -> USB3
USB3 -> USB4
PCI1 -> PCIB
PIC -> IPIC
FPU -> MATH
SIO -> LDRC
IDE0 -> PATA
PRIM -> PRID
MSRT -> P_D0
Tips and Tricks
The DSDT is a pain to debug. One of the tricks is to make Sleep led blink for a brief moment when a part of code is being executed. You can insert the following piece of code anywhere (or maybe create your own method similar to DTGP) and then whenever that part of code is executed, you will see Sleep led blink.
Code: Select all
\_SB.PCI0.LPC.EC.LED (0x07, 0x80)
Sleep(0x64)
\_SB.PCI0.LPC.EC.LED (0x07, 0x00)
You can assign some fan speed control commands to some hotkeys, for example brightness control hotkeys. Method _Q14 in DSDT is for brightness up (Fn+Home) and method _Q15 is for brightness down (Fn+End). Just replace the code there (or comment original code out) with any of the following:
Code: Select all
Store (0x80, \_SB.PCI0.LPC.EC.HFSP) - fan set to automatic mode (in OSX it will work at full speed), this is what happens in _WAK method to make fan go full speed after waking
Store (0x00, \_SB.PCI0.LPC.EC.HFSP) - fan is off
Store (0x01, \_SB.PCI0.LPC.EC.HFSP) - slowest manual speed
....
Store (0x05, \_SB.PCI0.LPC.EC.HFSP) - highest manual speed
Questionable fixes
If you go through OSx86 related forums you will find other interesting DSDT fixes, but some of them should not be used with ThinkPad T60p (not sure about other models).
SBUS fix. Very simple and allows OSX to load native SBUS drivers. I've checked original MacBookPro2,1 DSDT and IORegistryExplorer dump, and those drivers are not loaded on that MacBook model. Considering the fact that this Mac is based on the same Intel chipset as our T60p (ICH7M) we don't need this fix.
USB/EHCI fix. Another fix that is related to USB/EHCI and its idea is to inject some "proper" device ids to all USB devices so that OSX recognizes them as vanilla. With T60p we already have proper device ids, they are identical to MacBookPro2,1 USB device ids, so you shouldn't apply this fix, it won't do anything good.
Current location for most essential kexts
It's always better to look for the latest version of a kext before using it. Here are some important kexts' locations:
- FakeSMS.kext. Always check netkas' site for the fresh version: http://netkas.org
- VoodooHDA.kext. This is your best friend for your audio (works from /E/E only with generated mkext!). The version 0.2.35 allows me to use microphone, but there are newer versions available. So always check this forum thread.
- VoodooPowerMini.kext and VoodooBattery.kext. I don't use them, but if you do check Superhai's site for updates: http://www.superhai.com
- AsereBLN Booter. I'm using this bootloader instead of Chameleon, because it has a lot of great advantages (restart fix, for example). Until Chameleon moves forward, I suggest you to use AsereBLN's version. Get the latest version and full description here.
Finally, here are all the links to the files I use:
- My full /Extra folder copy (15.01.2011).
- Decompiled latest version of my DSDT with comments inside (not the latest version for now).