Jump to content
PayPal donations: [email protected] ×

Understanding and patching FrameBuffer (HASWELL)


black.dragon74

Recommended Posts

  • Moderators

Hey folks,

 

This post is meant to be used as a knowledge base on patching and understanding Apple Intel framebuffers present in our working macOS install.

 

As you might know, when you are running macOS on a hack you mostly have to patch framebuffer for various reasons, few of them being: HDMI Audio, MinStolenSize patch, Cursor mem, Framebuffer mem.

 

This guide will cover most of them.

 

Let's start by taking my favorite, Haswell as an example. I use mobile platform-id 0x0a260006.

 

Haswell Framebuffer (AppleIntelFramebufferAzul):

If you open binary file located in Contents/MacOS of AppleIntelFramebufferAzul.kext in a hex editor and search for "0600260A 01030303"

 

You will get a result like:

0600260A 01030303 00000002 00003001 00006000 in which the values are:

  • 0600260A --> Framebuffer/layout ID (0x0a260006)
  • 01030303 --> Pipe and Port count (last 4 bytes, no idea why it is repeated)
  • 00000002 --> DvMT Memory (32MB in decimal 1024*1024*32)
  • 00003001 --> Framebuffer Memory (19MB in decimal 1024*1024*19)
  • 00006000 --> Cursor Memory (6MB in decimal 1024*1024*6)

Note: Framebuffer memory + Cursor memory must be less than DvMT value else you will get kernel panic (19+6 = 25 which is less than 32MB)

 

Now we know what the values correspond to, we also know that our platform id has 3 ports in it as 0x03 = 3 in decimal. Now if you look in your hex editor just a few bytes ahead you will get the ports of framebuffer.

 

Ports of AppleIntelFramebufferAzul at 0600260A:

  • 00000800 02000000 30000000 --> Port 0000 properties (LVDS)
  • 01050900 00040000 87000000 --> Port 0105 properties (DP)
  • 02040900 00040000 87000000 --> Port 0204 properties (DP)
  • FF000000 01000000 40000000 --> End Table

Note: First 4 bytes of 1st set displays port number. Second part refers to connector type. Let's take a look at common connector types now.

 

Connector types:

  • 0200 for LVDS
  • 0004 for DP
  • 0008 for HDMI
  • VGA is not found on real macs although it works OOB for HD4400

Patching Framebuffer:

We will be covering patching for Port count, HDMI, DvMT, Cursor mem, Framebuffer mem and removing ports.

 

Patching for PortCount:

As we know that we have 3 ports in our platform-id that is denoted by 01030303 now suppose we want to change port count to 2 (it is used to remove unwanted ports from framebuffer and hence solving lag on some Haswell/Broadwell machines)

 

So, we have to change 03 to 02 (as it is repeated twice we will have to change last 4 bytes of that data). A port count changing port that changes count from 3 to 2 would be:

Name: AppleIntelFramebufferAzul

Find: 0600260A 01030303 00000002

Rep:  0600260A 01030202 00000002

 

Now as we have decreased the port count to 2 we need to remove the unused port. Using a bit of common sense you can know that we can't remove the LVDS port else we won't get any display on our laptop. Now we are left with 2 x spare ports. One of which will be used for HDMI. In my case, port 0204 is used for HDMI.

 

Please note that port number can be identified easily as they are positional wrt to FrameBufferConnector. Like, if you run:

nick@Nicks-MacBook-Air:~$ ioreg -l | grep "class AppleIntelFramebuffer"

    | |   | +-o AppleIntelFramebuffer@0  <class AppleIntelFramebuffer, id 0x100000354, registered, matched, active, busy 0 (41 ms), retain 20> //Port 1
    | |   | +-o AppleIntelFramebuffer@1  <class AppleIntelFramebuffer, id 0x100000355, registered, matched, active, busy 0 (43 ms), retain 15> //Port 2

You can see that there are only two ports at @0 and @1 (I have removed the third port as it caused lag after waking up from sleep)

 

So, logically, @0 refers to LVDS, @1 refers to port 0105, @2 refers to port 0204.

 

Patch to remove unused connector:

As we know that we are using HDMI on port 0204 and port 0000 is internal LVDS we can get rid of port 0105 which is not needed.

 

We will be replacing port 0105 by 0204 and will be nulling out port 0204. A patch for that would be:

Name: AppleIntelFramebufferAzul

Find: 01050900 00040000 87000000 02040900

Rep:  02040900 00040000 87000000 FF000000

 

Patch for HDMI:

You will have to use IOREG in order to identify which port is being used for HDMI. You will see a "AppleDisplay" like you see an "AppleBacklightDisplay" under framebuffer 0 for LVDS.

 

Once you identify which port is being used for HDMI you just need to change it's connector type to 0008

 

A patch for port 0204 for HDMI would be:

Name: AppleIntelFramebufferAzul

Find: 02040900 00040000 87000000

Rep:  02040900 00080000 87000000

 

Note now we only changed the connector type in the above patch.

 

Patch for DvMT (Only for Haswell or lower, BDW+ determine DvMT dynamically):

We know that our platform-id uses 32MB DvMT by default. On PCs we can modify this value. Suppose I set DvMT to 64MB in my BIOS, then, I would have to patch Framebuffer to take advantage of that.

 

First, we need to convert our 64MB value in Intel byte format, like:

64*1024*1024 = 67108864 (In decimal)

 

Now we need to convert it to Hex format. So:

67108864 = 0x4000000 in HEX

 

Now converting this to intel byte format:

0x4000000 = 00000004

 

Now we know that we need to replace DvMT value by 00000004. A patch for that would be:

Name: AppleIntelFramebufferAzul

Find: 0600260A 01030303 00000002

Rep:  0600260A 01030303 00000004

 

Note: Framebuffer Value + Cursor Bytes must be less than DvMT value else you will get kernel panic.

 

Patching for Cursor Bytes and FrameBuffer Size:

As you might know we have to change cursor bytes to 9MB in some cases to fix a menu bar glitch on a few machines. You can also patch framebuffer to a different size. Just keep in mind the above note, FB+CB.

 

A simple patch to change cursor bytes to 48MB and Framebuffer to 48MB would be:

Name: AppleIntelFramebufferAzul

Find: 0600260A 01030303 00000002 00003001 00006000 

Rep:  0600260A 01030303 00000002 00000003 00000003

 

But, you can see that 48+48 = 96MB which is larger than our DvMT i.e. 32MB. So, we will need to adjust the DvMT value to be equal or larger than 96MB. I am going to use 128MB as an example.

 

So, the final patch would be:

Name: AppleIntelFramebufferAzul

Find: 0600260A 01030303 00000002 00003001 00006000 

Rep:  0600260A 01030303 00000008 00000003 00000003

 

General Notes:

  1. It is a good idea to merge different patches into one as it reduces chances of conflicts.
  2. If you are changing port number in some patch then you other patches should respect that value. For example, if you set ports to 2 and then in DvMT patch you set port count to 3 that will most likely give you a panic.

 

How to merge several patches into one:

I am going to use a single patch to change port count, DvMT, Framebuffer and Cursor Bytes. Let's have a look at it:

Name: AppleIntelFramebufferAzul

Find: 0600260A 01030303 00000002 00003001 00006000 

Rep: 0600260A 01030303 00000008 00000003 00000003

 

What did I do in the above patch? As you might already know, 0x0a260006 has 3 ports with 32MB DvMT, 19MB Framebuffer and 6MB cursor bytes.

 

I changed port count to 2, DvMT to 128MB, Framebuffer and Cursor Bytes to 48MB.

 

A sample data of Broadwell:

06002616 01030303 00002002 00005001 --> Platform ID, Ports, Framebuffer, Cursor Bytes. You might note that there is no DvMT as it is determined dynamically.

 
Hint: You can see that Framebuffer + Cursor Bytes (34+21=55) which is less than 32MB. Hence proved that DvMT must be set to 64MB or larger on broadwell or above. Else, you won't be able to boot macOS Installer.
 
If you can't change DvMT in BIOS there are possibilities of doing that by EFI Shell or BIOS modding. If you can't do that, you can get around this issue by using Lilu + IntelGraphicsDvMTFixup.
 
Although, IntelGraphicsDvMTFixup might get you to installer and may also make you be able to use macOS but things will get nasty when you patch framebuffer as IntelGraphicsDvMTFixup has a heavy reliance on framebuffer data. If you change it, it won't load and hence the panic.
 
So, think of a way to fix it. Got it yet? Yes, change the FrameBuffer and Cursor Bytes values so that they are less or equal to DvMT.
 
Most PCs have DvMT set to 32MB. And if you read this guide between the lines you know that Haswell is fine with 32MB prealloc. So, the common mind would replicate the same patches for Broadwell or above. But, there is a catch. When you use default haswell data, you have 19MB as Framebuffer and 6MB as cursor bytes.
 
But, if you use the same data on Broadwell (6MB cursor bytes specifically) you will be able to boot macOS but you might get random glitches, mainly in the Menu Bar.
 
So, we will be using 9MB as cursor bytes. We can see that 19+9 = 28MB which is less than our DvMT (32MB) value as required.
 
So, a patch for this would be:
Name: AppleIntelBDWGraphicsFramebuffer
Find: 06002616 01030303 00002002 00005001
Rep:  06002616 01030303 00003001 00009000
 
Hope you get the idea and can follow this guide as per your needs. If you get stuck OSXL is here for you.
 
Thanks to Pike, RehabMan and many others for their initial research on this matter.
 
Cheers
  • Like 1
Link to comment
Share on other sites

  • Administrators

As detailed by Pike R Alpha back in his blog posts back in 2013/2014, the information of any given Azul framebuffer decodes as follows (using your Azul layout #12 for illustration):

https://pikeralpha.wordpress.com/2013/06/24/haswell-cpuigpu-power-management-with-a-ga-z87m-d3h/

https://pikeralpha.wordpress.com/2013/06/27/appleintelframebufferazul-kext/

https://pikeralpha.wordpress.com/2013/08/02/appleintelframebufferazul-kext-part-ii/

https://pikeralpha.wordpress.com/2013/09/25/appleintelframebufferazul-kext-part-iii/

 

0600260A 01030303 00000002 00003001          FB id / Mobile / Pipe|Port|FBMem-Count / StolenMem / FBMem
00006000 00000060 D90A0000 D90A0000          CursorMem / RAM / Freq / MaxFreq
00000000 00000000 00000800 02000000          fb index / port number / pipe

30000000 01050900 00040000 87000000          connector-type / flags
02040900 00040000 87000000 FF000000          
01000000 40000000 0F000000 01010000          

04000000 00000000 0E000000 00000000

 

0600260A -> layout-id

01 03 03 03 -> Mobile + nb of pipes + nb of ports + nb of framebuffers

00000002 -> fStolenMemorySize (=BIOS allocation): 0x02000000 = 32MB

00003001 -> fFramebufferMemorySize: 0x01300000 = 19MB

00006000 -> fCursorBytes: 0x00060000 = 6MB

00000060 -> Max. VRAM: 0x06000000 = 1536MB

D90A0000 -> fBacklightFrequency

D90A0000 -> fBacklightMaxFrequency

00000000

00000000

00 00 0800 02000000 30000000 -> FB index 0 + port #0 + pipe attr + LVDS connector-type + activation delay (flags)

01 05 0900 00040000 87000000 -> FB index 1 + port #5 + pipe attr + DP connector-type + activation delay (flags)

02 04 0900 00040000 87000000 -> FB index 2 + port #6 + pipe attr + DP connector-type + activation delay (flags)

 

From there on, different binary patches are possible:

  • number of display output ports
  • output port index (FB # + port #)
  • output port connector type
  • max. VRAM

 

 

Those patching principles -and I want to emphasize on the word principles- are repeatable for Ivy Bridge, Haswell, Broadwell framebuffer kexts.

 

Existing guides have already been published for:

 

Anyone wishing to patch the framebuffer kext applicable to his/her own machine should:

  1. identify the relevant framebuffer kext for the iGPU (SNB for HD3000, Capri for HD4000, Azul for Haswell, BDW for Broadwell)
  2. identify the relevant layout-id for the iGPU (Clover Configurator app lists them all, use that for reference; failing that, keen people may look up the tables in the kext's binary file using a Hex Editor)
  3. identify the output port(s) you need/want to patch (use IOReg data to determine the ports)
  4. apply the relevant patch (eg: change connector-type to 0008 0000 for HDMI)

 

Samples have been thoroughly detailed in the above threads.

  • Like 1
Link to comment
Share on other sites

Guest
This topic is now closed to further replies.
×
×
  • Create New...