Jump to content

Understanding and patching FrameBuffer (HASWELL)

Recommended Posts

Hey folks,


This post is meant to be used as a knowledge base on patching and understanding AppleIntelFramebuffers 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 Bytes, Framebuffer value.


This guide will cover most of them.


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


Haswell Framebuffer (AppleIntelFramebufferAzul):

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


You will get a result like:

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

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

Note: Framebuffer Value + Cursor Bytes 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 LVDS
  • 01050900 00040000 87000000 --> Port 0105 
  • 02040900 00040000 87000000 --> Port 0204
  • 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:

  • 02 for LVDS
  • 04 for DP
  • 08 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 Bytes, Framebuffer Value 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 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 0080 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 08


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.
  • Like 1

Share this post

Link to post
Share on other sites

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):






0600 260A 0103 0303 0000 0002 0000 3001          layout id (usual layout for mobile HD4600 Hackintosh)
0000 6000 0000 0060 D90A 0000 D90A 0000          VRAM allocation
0000 0000 0000 0000 0000 0800 0200 0000          framebuffer index / port number

3000 0000 0105 0900 0004 0000 8700 0000          ??? (priority?)
0204 0900 0004 0000 8700 0000 FF00 0000          connector-type
0100 0000 4000 0000 0F00 0000 0101 0000          activation delay

0400 0000 0000 0000 0E00 0000 0000 0000


0600260A -> layout-id

01 03 03 03 -> ? + nb of ports + nb of pipes + 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 -> fBacklightMax



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

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

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


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 and so on.


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, SKL for Sklylake, etc.)
  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

Share this post

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Create New...