I own two new Mac Book Pro’s. One IGPU only (MacBookPro13,1) and one with a Radeon Pro 460 with 4GB (MacBookPro13,3). Both of them use device-properties to inject saved-config. The injected data is related to the display hardware and I like to find out what that data is and where that it is used. Let’s start with a grep:
grep -r saved-config /System/Library/Extensions
Here is the output:
AMDFramebuffer.kext
AMDSupport.kext
AppleIntelBDWGraphicsFramebuffer.kext
AppleIntelFramebufferAzul.kext
AppleIntelFramebufferCapri.kext
AppleIntelHDGraphicsFB.kext
AppleIntelSKLGraphicsFramebuffer.kext
AppleIntelSNBGraphicsFB.kext
NVDAResman.kext
NVDAResmanTesla.kext
NVDAResmanWeb.kext
This basically tells us the names of the kexts that are using the data, but now we have to find out what the data is. Here is the data that gets injected on the MacBookPro13,3:
47 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 03 00 06 00 1b 19 00 6c 05
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 01 01 00 06 10 30 a0 02
03 40 00 00 00 00 00 00 00 00 02 c0 eb 9a 13 40 0b 08 07 50 00 00 00 34 00 00 00
08 00 20 00 26 00 08 00 20 0d 34 08 69 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00
And here the data that is injected on the MacBookPro13,1
47 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 03 00 02 00 26 19 00 6c 05
69 05 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 01 01 01 00 06 10 34 a0 02
03 40 00 00 00 00 00 00 00 00 02 90 6c 8a 0f 00 0a 40 06 50 00 00 00 2e 00 00 00
08 00 20 00 20 00 08 00 40 0b 08 07 5a 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00
I could not find anything, not a single Apple document nor source code/header file that explains it, but I may have missed it. In which case I would love to hear from you.
Ok. So assuming that there is no documentation, we have to dig into other resources to get an idea what it may be. And this is what I figured out so far:
47 00 00 00 (unknown)
00 00 00 00 (_reservedA[10])
00 00 00 00
00 00 00 00
00 00 03 00 (version?)
06 00 1b 19 (AAPL,ig-platform-id)
00 (unknown)
6c 05 (BCL frequency/maximum?)
00 00 (BCL frequency/minimum)
00 00 (unknown)
00 00 00 00 (_reservedB[10])
00 00 00 00
00 00 00 00
00 00 00 00
00 00 00 00
00 00 00 00
00 00 00 00
00 00 00 00
00 00 00 00
00 00 00 00
01 01 01 01 (standard timing related info?)
00 (unknown)
06 10 (DisplayVendor)
30 a0 (DisplayProductID)
02 03 40 00 00 00 00 00 00 00 00 02 (unknown)
c0 eb 9a 13 (IOFBCurrentPixelClock)
40 0b (horizontalActive = 2880 pixels)
08 07 (verticalActive = 1800 pixels)
50 00 (horizontalBlanking in pixels)
00 (horizontalBorderLeft in pixels)
00 (horizontalBorderRight in pixels)
34 00 (verticalBlanking in pixels)
00 (verticalBorderTop in pixels)
00 (verticalBorderBottom in pixels)
08 00 (horizontalSyncOffset in pixels)
20 00 (horizontalSyncPulseWidth/Sync Width)
26 00 (verticalSyncOffset in pixels)
08 00 (verticalSyncPulseWidth/Sync Width)
20 0d (horizontalScaled = 3360)
34 08 (verticalScaled = 2100)
69 00 (bytes per row == ( (horizontalActive * depth) >> 3) )
00 00 00 00 (_reservedC[25])
00 00 00 00
00 00 00 00
00 00 00 00
00 00 00 00
00 00 00 00
00 00 00 00
00 00 00 00
00 00 00 00
00 00 00 00
00 00 00 00
00 00 00 00
00 00 00 00
00 00 00 00
00 00 00 00
00 00 00 00
00 00 00 00
00 00 00 00
00 00 00 00
00 00 00 00
00 00 00 00
00 00 00 00
00 00 00 00
00 00 00 00
00 00 00 00
Mostly basic stuff. Things that you could have come up yourself, but since I like to document things, and let other people confirm my findings.
Edit: I changed the border info. It’s now broken up into two horizontal and vertical border settings. I also figured out the unknown value at the bottom (row bytes).
The red unknown values are my next targets and I think that one of them is used for screen rotation. This is something I will test later today on my MacBook Pro.
Ok. Let me add the EDID data that gets injected:
00 ff ff ff ff ff ff 00 06 10 30 a0 00 00 00 00 26 19 01 04 b5 21 15 78 02 0f 55
ae 52 43 b0 26 0d 4f 54 00 00 00 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01
7c 80 40 50 b0 08 34 70 08 20 68 08 4b cf 10 00 00 1a 00 00 00 10 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 fc 00 43 6f 6c 6f 72 20 4c 43 44 0a 20 20 20
00 00 00 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 fe
And here the EDID data from the MacBookPro13,1
00 ff ff ff ff ff ff 00 06 10 34 a0 00 00 00 00 25 19 01 04 b5 1d 12 78 02 0f 41
ae 52 43 b0 26 0e 50 54 00 00 00 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01
d9 65 00 50 a0 40 2e 60 08 20 08 08 1e b3 10 00 00 1a 7c 80 40 50 b0 08 34 70 08
20 68 08 1e b3 10 00 00 1a 00 00 00 fc 00 43 6f 6c 6f 72 20 4c 43 44 0a 20 20 20
00 00 00 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 3e
I also used SwitchResX to dump the EDID and one particular part of that output is this:
EDID Detailed mode
Clock 328.920 MHz, 331 mm x 207 mm
2880 2888 2920 2960 hborder 0
1800 1838 1846 1852 vborder 0
+hsync -vsync
I also used DarwinDumper and this is what I got:
Mode = 2880 x 1800 @ 60.001Hz
Pixel Clock............. 328.92 MHz Non-Interlaced
Horizontal Vertical
Active.................. 2880 pixels 1800 lines
Front Porch............. 8 pixels 38 lines
Sync Width.............. 32 pixels 8 lines
Back Porch.............. 40 pixels 6 lines
Blanking................ 80 pixels 52 lines
Total................... 2960 pixels 1852 lines
Scan Rate............... 111.122 kHz 60.001 Hz
Image Size.............. 331 mm 207 mm
Border.................. 0 pixels 0 lines
Sync: Digital separate with
* Negative vertical polarity
* Positive horizontal polarity
The above data is the technical description of the 15-inch display panel. And I used it, along with the saved-config data, to get this:
First column
2880 = horizontalActive
1800 = verticalActive
Second column
2880 = 2880 (horizontalActive) + 8 (horizontalSyncOffset)
1838 = 1800 (verticalActive) + 0x26/38 (verticalSyncOffset)
Third column
2920 = 2880 (horizontalActive) + 8 (horizontalSyncOffset) + 0x20/32 (horizontalSyncPulseWidth)
1846 = 1800 (verticalActive) + 0x26/38 (verticalSyncOffset) + 8 (verticalSyncPulseWidth)
Fourth column
2960 = 2880 (horizontalActive) + 0x50/80 (horizontalBlanking)
1852 = 1800 (verticalActive) + 0x34/52 (verticalBlanking)
Most of it can be extracted from IODisplayEDID, but I like to see it confirmed by others first. There is also unknown data. I have no idea, yet, what it may be. For example: 69 00
is 5a 00
on my MacBookPro13,1 and I have no idea what it is or how to get this value for my external monitor.
Injecting the wrong data is not what we want. I tried that and it failed to boot. The monitor of my hack went nuts, so the data obviously did something.
In short. We need a script or app that does most, if not all, of the work for us. We can use struct IODetailedTimingInformationV2 from IOGraphicsTypes.h to get (most of the) data. After that we can try to figure out what it does or if it helps us. Now the question is; who here is interested in this, and who can write that script and/or app?
Note: Some people may say that we don’t need it. Sure. We have been booting OS X for many years without this data. True. But now answer this question: Why does Apple inject the device-properties, when they don’t need it?