2011 MacBook Pro & OSX

A few years ago my MBP got a second life due a class action brought on Apple. Things were working just fine for a couple of years and then late last year GPU went belly up again. Display was all green or red depending on how GPU behaved.

Now the funny thing is that I have no way of controlling which GPU to choose from, that is true with other laptops with such configuration.

Searching online i found plenty of complaints and some industrious folks have found a way around. So i went about trying out a few things, given current COVID19 situation needed something better to do to make myself feel better and distracted. Various reference links below.

Approaches to fix discrete GPU issues:

  1. recycle laptop
  2. have gmux flashed
  3. hack hardware
  4. remove resistor
  5. reapply thermal paste
  6. jump thru hoops for OSX - this one
  7. use linux instead

1-4 are out of question as i might lose this machine and all of them cost quite a bit to get right. Overall 4 seemed more practical, but i am no electronics engineer and it has been a while since i held a solder gun in hand. That made 5 & 6 attractive. Now I wanted to go with (5) first and then try (6) after all the look and feel of OSX is much better and I have a few software licenses that i can use readily.

 

Steps of fixing (YMMV):

  1. reset SMC & NVRAM
  2. ensure to disable discrete GPU (dGPU) in NVRAM
  3. disable csrutil
  4. backup AMD kexts
  5. on login disable dGPU in OSX
  6. disable turbo boost

 

(1) reset SMC & NVRAM

This one is well documented. Here is documentation on Apple’s site for resetting SMC and NVRAM. Note, this might cause interesting side effects. Particularly it might lead MBP to boot with dGPU and start rendering thru it. It might make display unusable. From there you are on your own. The funny thing is DisplayPort is driven thru dGPU, so you cannot even connect an external monitor to get the job done.

 

(2) ensure to disable dGPU in NVRAM

This is where things are a bit hazy. You have two options to do this:

https://gist.github.com/0xbb/974999591da4b1b2635c above links some information about how gpu-power-prefs guid was found

  1. boot OSX in single user mode to boot in single user mode: power on laptop and hold Command+s button. Apple doc. Once on the cmd shell enter following command to set the gpu-prefs:
1
2
# %01 (iGPU) is the key here, %00 would have been dGPU
sudo nvram fa4ce28d-b62f-4c99-9cc3-6815686e30f9:gpu-power-prefs=%01%00%00%00
  1. boot thru linux and access efi variables i chose to install from arch linux, found a few steps to create a bootable usb. Once i booted press e on the boot menu and just add nomodeset at the beginning of the command.

efivars will be mounted, but readonly.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# check if the filesystem is mounted or not, if not mounted something is wrong
cd /sys/firmware/efi/efivars

cd /
umount /sys/firmware/efi/efivars

# note we are mounting as efivarfs not efivars
mount -t efivarfs rw /sys/firmware/efi/efivars

cd /sys/firmware/efi/efivars

# well technically you don't need to delete it, but clean slate
chattr -i gpu-power-prefs-fa4ce28d-b62f-4c99-9cc3-6815686e30f9
rm gpu-power-prefs-fa4ce28d-b62f-4c99-9cc3-6815686e30f9

# now we are going to set gpu-prefs to be 1 (iGPU) and not 0 (dGPU)
# x01 is the key here
printf "\x07\x00\x00\x00\x01\x00\x00\x00" > gpu-power-prefs-fa4ce28d-b62f-4c99-9cc3-6815686e30f9

# set it to read-only again
chattr +i gpu-power-prefs-fa4ce28d-b62f-4c99-9cc3-6815686e30f9

# unmount efivars, so that changes are flushed
cd /
umount /sys/firmware/efi/efivars

reboot

 

(3) disable csrutil

Hopefully this time you display should be fine, now that you have set iGPU to be used to boot.

Apple added System Integrity Protection o help prevent potentially malicious software from modifying protected files and folders. Before SIP, the root user had no permission restrictions, so it could access any system folder or app on your Mac. Which now means that you cannot move/backup AMD kexts even as root.

To do this need to boot in recovery mode. Once you boot go to Utilities and terminal and enter commands

1
2
csrutil disable
reboot

 

(4) backup AMD kexts

Initially I did not backup any AMD kexts, and found that OSX after booting up loaded those anyway. Where it started getting funny is when I opened chrome browser.

So i quickly checked what kexts are loaded and these messed up my next boot. Again i could have experimented a bit with backing up exactly the kexts that affect- but it was just grunt work and on every update (security or os), these are brought all over again..

1
2
3
4
5
MBP:~ admin$ sudo kextstat | grep AMD
  130    2 0xffffff7f82aa5000 0x122000   0x122000   com.apple.kext.AMDLegacySupport (1.6.8) 69C5152C-0305-3914-AD56-6601DD449AF4 <106 12 11 7 5 4 3 1>
  147    0 0xffffff7f82e79000 0x12e000   0x12e000   com.apple.kext.AMD6000Controller (1.6.8) F08FE763-26A1-312E-B690-CB8FDBF8EC31 <130 106 12 11 5 4 3 1>
  164    0 0xffffff7f834fc000 0x568000   0x568000   com.apple.kext.AMDRadeonX3000 (1.6.8) 8559CEFE-85B8-3FB7-B20A-9346E5A7986A <163 162 106 12 7 5 4 3 1>
  166    0 0xffffff7f83a69000 0x22000    0x22000    com.apple.kext.AMDLegacyFramebuffer (1.6.8) 13E3BF67-6700-37F0-82EE-E87F8B71A033 <130 106 12 11 7 5 4 3 1>

boot in single user mode again by pressing Command+s keys. On terminal enter following commands:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# check disk in case anything is wrong
fsck -fy 

# mount root filesystem read/write
mount -uw /

# AMD kexts are located in /System/Library/Extensions
# create a temp backup directory for AMD kexts
sudo mkdir /System/Library/Extensions-bkp

# move all AMD kexts to bkp dir
sudo mv /System/Library/Extensions/AMD* /System/Library/Extensions-bkp/

# now that we have moved all kexts, invalidate kext caches, so they
# are rebuilt again on next boot
sudo rm -rf /System/Library/Caches/com.apple.kext.caches/
sudo mkdir /System/Library/Caches/com.apple.kext.caches/

# technically you don't have to do this, but update timestamp on directory
# as it's contents were modified
sudo touch /System/Library/Extensions/

sudo umount /
reboot

At this point one can enable crsutil again, but I chose to let it be like that.

 

(5) on login disable dGPU in OSX

At this stage i was able to login sensibly just with iGPU. However at times dGPU got kicked in (this was due me not doing previous step properly).

It seemed prudent to ensure that I have control to switch to iGPU, if needed. Now i found two tools to do the job:

  1. gpu-switch, https://github.com/0xbb/gpu-switch
  2. gfxCardStatus, https://github.com/steveschow/gfxCardStatus

gpu-switch uses login-hooks to launch itself everytime user logs-in or logs-out. I like the approach as a RAII C++ style pattern :), leave the slate clean after yourself. The idea is pretty simple as documented here at Apple’s site and here

Apple mentions that this is not a preferred technology and may be removed in future releases, but where things stand today they are not allowing me to update to 10.14 and onwards- so it doesn’t really matter. :)

Now, SteveChow went about customizing gfxCardStatus to just force iGPU. So this sounded perfect: braces and girders for my hooks. So had it installed and it launches on login and sets iGPU by default.

At this point i have a fairly functional laptop. I just had to reset gpu-prefs a couple of times after installing cmdline tools and so on- but I am really worried about security upgrades.

 

(6) disable turbo boost

2011 MacBook Pro 8,2 was fitted with Intel Core i7 2635QM processor. This processor was built on 32nm process node and is the first CoreProcessor with iGPU (hurray). This processors TDP (Thermal Power Design) is 45W!!. The way Intel measures TDP is not max but what is practical in day to day life. [It does not account TurboBoost] (https://www.anandtech.com/show/14582/talking-tdp-turbo-and-overclocking-an-interview-with-intel-fellow-guy-therien).

This makes life a lot more interesting for me now. The biggest issue with this model has been heat. And That MacBook Pros don’t have a grill makes it even interesting to disperse ~65W of heat on medium loads.

Intel’s documentation about TurboBoost here

Anyway, with above changes dGPU consumes power and generates some heat (earlier approaches #2, #3 and #4 could address it), but the biggest culprit now is TurboBoost. Suddenly the frequency jumps to 2.9GHz and laptop heats up even on single threaded workflows. Disabling TurboBoost has a good impact of battery life as well as powerdraw source.

Peering thru Intel Manuals I found that one can disable Intel TurboBoost by setting Model Specific Register, but it a privileged instruction. That means one needs a kext to do that. :)

This is just what i found online at: http://tbswitcher.rugarciap.com/, I set it up to launch on login and it does pretty good job.

More on how to disable TurboBoost here

The other thing I tried was to disable hyperthreading completely, but that didn’t help either. Apple has some instructions on how to do that here, courtesy Spectre/Meltdown.

 

So after all of this, I have a stable MacBook Pro, one that I can’t update/upgrade now. However, it has been a fun ride trying to repurpose this laptop to be used for home schooling for my daughter.

Here are the things that don’t work:

  1. Screen Brightness buttons, had to install a software to control that
  2. Sleep, if MBP sleeps display won’t turn on, have to force reboot. Had to install caffenaite to help with it
  3. Updates/Upgrades, well technically I can still update/upgrade. But i risk the stability of my current scaffolding and might have to go thru this all over again

I did manage to read thru a lot on Apple Documentation:

  1. Kernel Programming Guide
  2. Boot Process
  3. Login related stuff

Following articles and books were helpful as well:

  1. https://arstechnica.com/tag/macos/, esp the ones by John Siracusa
  2. Mac OS X Internals - Amit Singh (https://www.amazon.com/Mac-OS-Internals-Approach-paperback/dp/0134426541)
  3. Mac OS X and IOS Internals - Jonathan Levin (https://www.amazon.com/Mac-OS-iOS-Internals-Apples/dp/8126540427/)

 

A few links that I found helpful in general (click to expand..)

Link#1 is a long thread and quite interesting read. A lot of people have shared their thoughts, experiments and frustations..

  1. https://forums.macrumors.com/threads/force-2011-macbook-pro-8-2-with-failed-amd-gpu-to-always-use-intel-integrated-gpu-efi-variable-fix.2037591/
  2. https://apple.stackexchange.com/questions/166876/macbook-pro-how-to-disable-discrete-gpu-permanently-from-efi
  3. http://dosdude1.com/gpudisable/
  4. https://apple.stackexchange.com/q/166876/34806
  5. https://discussions.apple.com/thread/8614311
  6. https://gist.github.com/fubarhouse/7208217257e20276fdfab4a4ed139e7c
  7. https://matthew-brett.github.io/docosx/booting_macs.html