iMac 9,1/10,1 (2009 Core2Duo) GPU Change Project
In this post I try to post as much information on hacking the VBIOS to work on our precious iMacs. I'm starting literally from scratch. When I learn something new I will share it with the world. I might get some things wrong initially but I try to be as accurate as I can.
This post seems to hint on the fact that these older iMacs are using LVDS instead of DP for the internal display. Indeed we find LVDS entries in the VBIOS of the iMac9,1. Adding these to the VBIOS of another card might just work.
iMac9,1 uses LVDS, iMac10,1 uses DP!
I have no idea why the vbiosses supplied here are not working on the iMac10,1. A GeForce 9400M dump of an iMac10,1 probably holds the answer, but I have not acquired it yet.
So the question to investigate is: What did Apple change between A1311 (iMac10,1) and A1312 (iMac11,1)?
iMac10,1:
iMac11,1:
Plan of attack:
Put valid DCB Table Entry #0 X3 X1 00 01 34 00 01 00 / Copypaste whole DCB Table
Put valid CCB Table Entry #X 03 00 00 05 / Copypaste whole CCB Table
Put valid Connector Table Entry #X 40 02 00 00 / Copypaste whole Connector Table
Fix Checksum
First off I gather the VBIOS from a iMac9,1 featuring a Geforce 9400M. This is done using
rEFInd. Because the firmware of these iMacs is too old we also need the EFI shell of
rEFIt. Replace the
shell.efi in the 'tools' folder. Information is gathered from
here.
Code:
- "devices -b"
E6 B - - 1 2 5 NVIDIA GPU
- "dh -b e6"
ROM Size......: EE00
ROM Location..: BE62D018
- "fs0:"
- "mem BE62D018 EE00 > 9400_output.txt"
The
DCB pointer is found at
0x36 of the UEFI rom starting with 0x55 0xAA. All pointers are relative from this location, if an IFR header is present the offset needs to be added!
Code:
55 aa 77 eb 4b 37 34 30 30 e9 4c 19 77 cc 56 49 44 45 4f 20 0d 00 00 00 98 01 9a 1c 00 00 49 42
4d 20 56 47 41 20 43 6f 6d 70 61 74 69 62 6c 65 01 00 00 00 c0 00 14 be 30 31 2f 30 38 2f 30 39
So this is 0x14 0xBE -----> pointer to
0xBE14.
This is the header found at @0xBE14:
Code:
40 1b 10 08 af be cb bd dc 4e 00 f4 be f1 bf fd bf 06 c0 1b c0 01 00 00 60 c0
Header Size (this!) = 0x1b = 27 bytes long
Entry Count = 0x10 = 16 entries
Entry Size = 0x08 = 8 bytes long
Communications Control Block @
0xBEAF.
GPIO Assignment Table @
0xBEF4.
Input Devices Table @ 0xBFF1
Personal Cinema Table @ 0xBFFD
Spread Spectrum Table @ C006
Connector Table @ C01B
??? @ C060
Directly following are the
DCB Device Entries:
DCB Device Entries
Code:
00 => 23 11 00 01 34 00 01 00 <-- TYPE = 0x3 = LVDS; EDID PORT = 0x2 = Reference to Communications Control Block?; CON INDEX = 0x1 = Connector Table Index
01 => 32 02 01 02 10 00 00 00 <-- TYPE = 0x2 = TMDS; EDID PORT = 0x3 = Reference to Communications Control Block?
02 => 86 02 01 02 10 00 22 0f <-- TYPE = 0x6 = DISPLAYPORT; EDID PORT = 0x8 = Reference to Communications Control Block?
03 => 0e 00 00 00 00 00 00 00 <-- TYPE = 0xE = EOL (End of Line)
04 => 0f 00 00 00 00 00 00 00 <-- TYPE = 0xF = SKIP
05 => 0f 00 00 00 00 00 00 00
06 => 0f 00 00 00 00 00 00 00
07 => 0f 00 00 00 00 00 00 00
08 => 0f 00 00 00 00 00 00 00
09 => 0f 00 00 00 00 00 00 00
10 => 0f 00 00 00 00 00 00 00
11 => 0f 00 00 00 00 00 00 00
12 => 0f 00 00 00 00 00 00 00
13 => 0f 00 00 00 00 00 00 00
14 => 0f 00 00 00 00 00 00 00
15 => 0f 00 00 00 00 00 00 00
Communications Control Block Header:
Entry Count = 0x10 = 16 entries
Communications Control Block Entries:
Code:
00 => 00 00 00 05
01 => 00 00 00 ff
02 => 03 00 00 05 <------ Device Entry 1 refers to this??? 0x3 = I2C
03 => 02 00 00 05 <------ Device Entry 2 refers to this??? 0x2 = DDC2
04 => 00 00 00 ff
05 => 00 00 00 ff
06 => 00 00 00 ff
07 => 00 00 00 ff
08 => 00 00 00 06 <------ Device Entry 3 refers to this??? AUXCH 00
09 => 01 00 00 06 <------ AUXCH 01
10 => 02 00 00 06 <------ AUXCH 02
11 => 03 00 00 06 <------ AUXCH 03
12 => 00 00 00 ff
13 => 00 00 00 ff
14 => 00 00 00 ff
15 => 00 00 00 ff
GPIO Assignment Table Header:
GPIO Assignment Table Entries:
Code:
00 => 0f
01 => 0f
02 => 0f
03 => 0f
04 => 0f
05 => 0f
06 => 0f
07 => 0f
Input Devices Table:
Code:
40 0c 00 00 f0 00 00 00 0f 00 00 00
Header Size = 0x0c = 12 bytes long
Entry Count = 0
Entry Size = 0
So why the long header...?
Personal Cinema Table Header
Header Size = 0x05 = 5 bytes long
Personal Cinema Table
idk lol
Spread Spectrum Table Header
Header Size = 0x05 = 5 bytes long
Entry Count = 0x04
Entry Size = 0x04
Spread Spectrum Table Entries
Code:
01 => ff 00 00 00
02 => ff 00 00 00
03 => ff 00 00 00
04 => ff 00 00 00
Connector Table Header??
Connector Table Entries??
Code:
00 => 46 a1 00 00 <-- DisplayPort External Connector
01 => 40 02 00 00 <-- LVDS-SPWG-Attached <------ Device Entry 1 refers to this???
02 => 46 52 00 00 <-- DisplayPort External Connector
03 => ff 00 00 00
04 => ff 00 00 00
05 => ff 00 00 00
06 => ff 00 00 00
07 => ff 00 00 00
08 => ff 00 00 00
09 => ff 00 00 00
10 => ff 00 00 00
11 => ff 00 00 00
12 => ff 00 00 00
13 => ff 00 00 00
14 => ff 00 00 00
15 => ff 00 00 00
??? @ C060
Checksum:
Last byte of UEFI firmware is
checksum. It should be necessary to recalculate and change this when making changes to the vbios. Attached is a small C program that calculates this. It currently only understands the raw UEFI/GOP portion of the VBIOS, which is as far as I currently know the only thing we need to work in anyway.
- Do we need the IFR section before the GOP/UEFI section for iMac to operate?
- Do we need the oldschool BIOS after the GOP/UEFI section for iMac to operate?
Attached is the original VBIOS of an iMac9,1 equipped with a GeForce 9400M. This article is based on it and it may contain the information necessary to create a VBIOS that works on iMac9,1 and iMac10,1.
Under investigation (reverse engineering the modded nikey22 vbios):
GPIO:
Code:
41 06 20 05 F7 5B
00 => 00 6C 00 00 4F
01 => 01 6D 00 00 4F
02 => 02 21 88 80 4F <--- changes 0x88 (SEL_SOR2_TMDS_OUT_PWM) to 0x84 (SEL_SOR1_TMDS_OUT_PWM)
03 => 83 01 00 00 4F
04 => 04 00 8A 00 4F <--- changes 0x8a (SEL_SOR2_TMDS_OUT_PINB) to 0x86 (SEL_SOR1_TMDS_OUT_PINB)
05 => 05 FF 00 00 EF
06 => 06 6E 00 00 4F
07 => 07 FF 4B 00 43
08 => 08 FF 00 00 EF
09 => 09 49 59 00 1F
10 => 8A 2E 00 00 1F
11 => 0B 81 5D 80 4F
12 => 0C 2B 00 17 BF
13 => 0D FF 00 00 EF
14 => 0E FF 00 00 EF
15 => 0F 51 00 01 EF
16 => 10 FF 00 00 EF
17 => 11 52 00 02 EF
18 => 12 5E 00 03 EF
19 => 13 5F 00 04 EF
20 => 14 FF 00 00 EF
21 => 00 FF 00 00 0F
22 => 00 FF 00 00 0F
23 => 00 FF 00 00 0F
24 => 00 FF 00 00 0F
25 => 00 FF 00 00 0F
26 => 00 FF 00 00 0F
27 => 00 FF 00 00 0F
28 => 00 FF 00 00 0F
29 => 00 FF 00 00 0F
30 => 00 FF 00 00 0F
31 => 00 FF 00 00 0F