omni's minimalistic web site

Project Titan

I have decied to release my findings in hope that they will encourage others to investigate further and dissemenate the knowledge. I was really split on whether I should be releasing any info, but I figured Apple might one way or the other try to fix their drivers in the next release to prevent us from using PC cards. And this hack is pretty simple onto itself, so onwards with it...

Introduction

For some time np_ and I have suspected that this EFI business is all a smoke-screen and really serves no real purpose except as yet another way to prevent running OS X on PCs, through use of proprietary hardware.

You can't blame Apple for doing that, they need to protect their product and market share, but at the same time they have severely limited their users on what can be plugged into the computers. This kind of "spoon feeding" at the mercy of Apple is something customers should not have to put up with, especially when you are paying a top dollar for an overglorified PC (oops did I say that outloud?).

Even though this solution applies to NVidia cards, I believe that similar solution can be made for ATI as well. Actually I did test a few things with regards to X1000 series and there was progress there, but more time needs to be spent on it. If there is demand for it I could write an addendum to this essay detailing some of the ATI keys and values to further the effort.

Discussion

I'll cut to the chase right away, the EFI Driver for graphics (UGA) in the Apple NVidia cards (7300GT and FX4500) is present in the ROM image of the card. It's the half of the image, the other half is the BIOS. That driver gets loaded, decompressed and initalized upon power up.
I am not going into detail how EFI works, you can read that elsewhere, what's important is that the UGA does quite a few things, DDC/I2C, gets the clock and memory, identifies framebuffer range/offset etc.

Through other processes (which again I won't bother detailing, go do your homework) the above card information ends up in the IOReg plane, under the display@ sub-tree. Below is the ioreg dump of a real Mac from a shell in single (-s) mode, system has not been loaded yet.

IOReg dump (single-user mode)

The important bits here are what the IONDRV and NVidia Resman match against, which is "device_type" set to "NVDA,Parent" and "@x,compatible" where x is 0 or 1 (corresponding to screen 0 or 1) set to "NVDA,NVMac". That's our first clue, we need to provide that to the IONDRV and Resman and the driver in order for anything to match with our card.
Without the above the NVidia HAL will match agains a set number of device id's (different graphics cards) and will load, but that is only good to inject certain methods into the kernel space. The actual Resman and IOAccelerator will not load and subsequently there will be no screen resolution and refresh control or acceleration.

Next I have found to be of importance are individual screen's device_type keys, "@x,device_type" where x is 0 or 1 which sets to "display", and "@x,name" which sets to "NVDA,Display-y", y is A or B.

Very important key that has to be there is "@x,fboffset" which sets the aperture offset of the screen. In most cases it should be 0 but some cards that have shared memory have that offset set to 0x20000 (like the 7300GT in the Mac Pro). Your card might need something like this set, if you do not get the GUI to work upon loading or the system freezes before loginWindow loads. I have set the value for this key to 0x20000 (131072) as a new default after talking to np_ who suggested that framebuffer offset is never really 0. Although, with value 0 GUI seems to load faster, so either will work on most cards...

There are other keys that are present in the IOReg dump that might need to be set, but the above is the absolute minimum to get things working. The rest is left as an exercise for the reader to try and figure out what each does and how it should be set. I must assert that quite a lot of code would be needed to get everything set automatically by querying the card, etc.
Contrary to that, we are here setting some of the values that are "generic" (in a sense except for the fboffset) and apply to all NVidia cards.

Putting it all together

So, let's re-cap from the above, we need to set a few registry keys to get our cherished GeForce cards to (mostly) work with all the bells and whistles. I say mostly because I am sure someone will not get it working or some feature might be broken but hey, you know the saying about a gifted horse...

The keys under the display@ sub-tree that need to be set BEFORE NVidia kexts load are:

"device_type" to "NVDA,Parent"

"@0,fboffset" to 0 or 0x20000 ("@1,fboffset" would probably need to be set in order to get dual screens working. I did test this, but could not get it to work (have dual screens) so something else must be missing. I need an ioreg dump from a dual head Mac Pro to do further study...)

"@0,compatible" to "NVDA,NVMac"
"@1,compatible" to "NVDA,NVMac"

"@0,device_type" to "display""
"@1,device_type" to "display"

"@0,name" to "NVDA,Display-A"
"@1,name" to "NVDA,Display-B"


I am not going to teach you here how to make an IOKit driver, I am just providing you with a solution - the missing pieces to the puzzle. It is up to you, the reader to put this together into a working kext. Suffice to say you have to isolate the display@ sub-tree then set the keys to it. You can either traverse the IOReg plane looking for it or some part of it, or use some other method.

Pre-compiled binary

This is my version of the solution, called Titan, distributed as a binary only. Please note that I have tested in OS X 10.4.8 Intel SSE3 with semthex kernel. You must use original KEXTs that come with 10.4.8! Other people report that Titan works on other combinations, even with the old 10.4.4 kernel, in which case you should use the old kernel but new 10.4.8 KEXTs to get it (partially) working.

Instructions
- Put Titan kext in your /System/Library/Extensions/ folder
- Correct the file premissions: sudo chown -R root:wheel Titan.kext ; sudo chmod -R 755 Titan.kext
- Remove the cached and packed extensions: sudo rm -f /System/Library/Extensions.mkext /System/Library/Extensions.kextcache
- sync and reboot.

Options in the Info.plist file
There are three keys presently:
- FBOFFSET which is an INTEGER value, default to 0 but can be 131072 (equals 0x20000) that is set on Mac Pros, or any larger number. Be careful with this, I will not be responsible if you break something!
- EDID0 and EDID1 co-relate to your card's ports 0 and 1 (which could be either DVI, VGA, DVI+VGA, VGA+DVI or DVI+DVI). The value of the EDID is a 128 byte sequence that's obtained from the monitor itself via DDC/I2C. Just look on the Web how to get your EDID, there are several programs out there.

You must use Property List Editor to insert the 128 byte sequence (it begins with 00ffff...). You CANNOT paste this into Info.plist directly because the sequence is encoded by the Property List Editor into a string of characters.

If all goes well your computer will still be in one piece after the system boots back up.

Titan kext: November 4, 2006

By downloading these files you agree that you will not hold me responsible if anything happens to you, your OS X installation, your computer, your neighbour's pet, your friends, countrymen, and/or planet Earth, while using the same files or otherwise.
To best of my knowledge the files present here do not contain any spyware, trojans, virus code or malware. You have been warned...

Last update: 02-Nov-06


Links

MacVidia Project
Free NVidia driver for OS X x86, done by my friend np_

Hackintosh forum
The peeps I know, most from the old Win2OSX.net forum are here

Victor's Internet Junk
Here you'll find some ported software and emulators for OS X

R-Type IRC network
That's the place where you can find me most of the time, in #Hackintosh

MacSpeak IRC network
Another cyber place where you can find me, check in #MacVidia

Semthex's blog
Another friend, the guru of the new 10.4.8 kernel