Background / hardware setup
- MacBook Pro 8,2 (15", mid‑2011), 1680x1050 panel.
- gmux chip physically removed from the logic board; LVDS lines from the Intel HD 3000 are bridged directly to the panel connector with jumper wires.
- Backlight control routed through a modified hub, hand-wired.
- Linux (native EFI, no coreboot) works perfectly out of the box — correct resolution, no artifacts.
- coreboot builds also work, using a
VBT borrowed from a Lenovo ThinkPad T430, but that setup has trade-offs: sleep/resume issues, no ambient light sensor, a few other rough edges.
- Goal: run Windows natively on the
stock Apple EFI firmware (no coreboot), via Boot Camp-style Intel graphics driver.
The symptom
- Boot logo (EFI GOP framebuffer) displays correctly.
- As soon as the Intel HD 3000 graphics driver loads (both the generic Intel driver and Apple's own Boot Camp driver — same result with either), the display becomes corrupted:
- Image appears stretched, part of it doesn't fit on screen.
- Picture looks like it's drawn "every other line" (interlaced/torn look).
- Colors washed out.
- This happens on the
stock, unmodified Apple EFI firmware — not just on coreboot builds.
Diagnosis
Both firmware images (stock Apple EFI, and the coreboot build using the T430 VBT that works correctly) contain an Intel VBT (Video BIOS Table) embedded inside the legacy "Intel(R) Sandybridge Mobile PCI Accelerated SVGA BIOS" Option ROM module (this same table is also what the native GOP driver and, at runtime, ACPI OpRegion expose to the OS graphics driver).
Extracting and decoding both VBTs with
intel_vbt_decode (from
intel-gpu-tools) and diffing the LVDS Options block (BDB block 40) revealed the key difference:
| Stock Apple VBT | T430 VBT (works) |
| LVDS EDID available | no | yes |
| LVDS panel timing table (BDB 42 | 1280x800 @ 72.5 MHz (generic placeholder, unrelated to the real panel) | 1024x768 @ 65 MHz (also a placeholder, but irrelevant) |
Root cause: Apple's own VBT ships with a completely generic/unused LVDS panel timing table, because macOS never reads panel configuration from the Intel VBT at all (it comes from the EFI device tree / AppleGraphicsControl instead). Apple simply never bothered to fill in real values here.
The
LVDS EDID available flag tells the Intel driver whether to trust that internal (bogus) timing table, or ignore it and read the real timings straight from the panel via DDC/GMBUS EDID:
- Flag =
no (stock Apple) → driver blindly applies the fake
1280x800@72.5MHz mode to the real 1680x1050 panel → exactly the corruption described above.
- Flag =
yes (T430 VBT) → driver reads the real EDID from the panel (which is programmed correctly by the panel vendor) and gets correct timings → works.
The fix
Flip a single bit in the VBT's LVDS Options block (BDB block 40):
- Field:
LVDS EDID available
- Byte offset within the block:
block data + 2 (the 3rd byte of the 24-byte block, right after panel_type/panel_type2)
- Bit mask: 0x40
- Change: 0x33 → 0x73 (only bit 6 changes)
That single byte is located, in this firmware image, inside the FFS file with GUID 6A5F1EF9-C478-42BA-A4DB-C7846CC7DB57 ("Intel(R) Sandybridge Mobile PCI Accelerated SVGA BIOS"), which sits behind an LZMA-compressed, GUID-defined (certificate-wrapped) section. Inside that, at absolute offset 0x1425 within the decompressed 64 KB raw section body, is the byte to change.
Patch procedure
1. Dump the current firmware (e.g. via flashrom).
2. Open the dump in
UEFITool v0.28 (!) (
https://github.com/LongSoft/UEFITool/releases/tag/0.28.0)
3. Locate the file with GUID 6A5F1EF9-C478-42BA-A4DB-C7846CC7DB57
4. Drill down through: compressed section → GUID-defined section (certificate/preamble wrapper) → the innermost
Raw section. Its body is the 64 KB legacy VBIOS/VBT blob (you'll see the ASCII string $VBT SANDYBRIDGE-M if you inspect the hex).
5. Extract that raw section's body, and at offset 0x1425 change the byte from 0x33 to 0x73.
Note: You can try using my patched VBT that I attached to this comment
6. Back in UEFITool, on that same raw-section tree node, use "
Replace body" (not "
Replace as is" — the extracted blob is the section
body only, without a section header, so "Replace body" is what correctly matches it; UEFITool then re-handles compression/headers for you).
7. Save the image.
8. Sanity-check before flashing:
- Final file size must match the original exactly (8 MB for this board).
- The flash descriptor + Intel ME region should be byte-for-byte identical to the original (diff the two dumps — all changes should fall strictly inside the BIOS region).
- Optionally, extract the VBT again from the patched image and run it through intel_vbt_decode to confirm LVDS EDID available: yes and that nothing else in the VBT changed.
9. Flash the patched image
using a programmer. After that you can install the Intel HD 3000 graphics driver (Boot Camp or generic — both work now) in Windows.
I recommend installing Windows in Legacy mode, because the Cirrus Logic sound does not work in UEFI mode.
Result
Confirmed working: with this single-bit patch on the stock, unmodified Apple EFI firmware, the Intel HD 3000 driver in Windows now initializes the display correctly on a de-gmux'd MacBook Pro 8,2 with direct LVDS wiring and a hand-wired backlight — no stretching, no interlacing artifacts, correct colors. No coreboot needed, and therefore none of the coreboot-side trade-offs (sleep/resume quirks, missing ambient light sensor, etc.).
Caveats / things to verify on your own hardware
- The exact byte offset (0x1425 inside the raw section, block-40 field at block-offset +2) is specific to this particular firmware dump/board revision. If your dump differs, re-locate the $VBT signature and the LVDS Options block (BDB block 40) yourself — the field is the first byte after panel_type/panel_type2, bit 0x40.
- This fix worked without touching the VBT checksum byte — a naive "sum of all VBT bytes = 0" checksum did
not validate even on the untouched original dump, suggesting this checksum isn't strictly enforced by this platform's firmware/GOP. If your board behaves differently (e.g. refuses to POST after the patch), you may need to investigate/recalculate the checksum.
- This specific fix (EDID flag) worked cleanly for a 1680x1050 panel, where the LVDS channel count is unambiguous from pixel clock alone. If you're on the base 1440x900 panel, you may also need to deal with the dual-channel-LVDS-vs-clock ambiguity described above, since Windows has no equivalent of Linux's DMI-based quirk table.