These are some tools and notes on Apple's Target Display Mode for 2009-2011-era iMacs.
A few years ago during COVID lockdown I purchased a 27" 2011 iMac with a dead graphics card to use as a cheap external monitor and made a few notes along the way. Key discoveries:
- New Macs can still use these iMacs as external displays when connected via appropriate Thunderbolt cables/adapters
- Target Display Mode works on macOS 10.13 High Sierra (the latest supported by these iMacs) by copying the binary
/usr/libexec/dpdfrom a 10.9 Mavericks installer. - Target Display Mode is handled by the motherboard and doesn't need a working graphics card (handy since failure of the Radeon 6xx0M chips in these iMacs is common). Note though that brightness control does depend on the graphics card so won't work.
- Target Display Mode can be activated without a physical keyboard or mouse using the Karabiner VirtualHIDDevice kext (
cmdf2code in this repo). I alternated between toggling TDM over SSH and using an Apple Remote and BetterTouchTool.
Hopefully sharing these notes will keep a few more 27" iMacs from being thrown out.
cmdf2simulates connecting a physical keyboard and pressing Cmd-F2 to activate Target Display Mode. It uses Karabiner's VirtualHIDDevice kext and is based on this example code. Compile with the usualmakeandmake installafter installing Xcode Command Line Tools.tdm.fishcontains fish shell functions for controlling TDM over SSH and e.g. demonstrates use ofcmdf2via SSH.com.local.LimitHDDFan.plistis alaunchdjob file to limit fan speed on startup using smcFanControl.
- Install fresh macOS 10.13 High Sierra from USB
- If GPU is faulty, disable the graphics kexts to force macOS to use software graphics. The macOS interface and VNC screen sharing will be very slow, but macOS should boot.
- Connect to network and install updates, enable SSH and VNC access for admin user. Keyboard and mouse no longer required.
- Replace
/usr/libexec/dpdwith version from latest Mavericks installer - Compile or download
cmdf2and move to e.g./usr/local/bin/cmdf2 - If hard drive is missing, install smcFanControl and add
launchdjob to limit fan speed (more details below) - The iMac can now be connected via a Thunderbolt cable and run
sudo cmdf2via SSH to enter Target Display Mode.
A common issue with the 2011 27” iMac is that the graphics card will fail, which looks like the iMac hanging on a grey screen after the boot progress bar completes. One solution is to replace/upgrade the graphics card, for which there's a ridiculously long discussion about how/which cards to upgrade to here.
For Target Display Mode purposes, however, the iMac can be made to boot without using the graphics card (in software graphics mode) by moving the kernel extensions (kexts) AMDRadeonX3000.kext and AMD6000Controller.kext out of /System/Library/Extensions (and into e.g. /System/Library/DisabledExtensions) and touching the /System/Library/Extensions folder to force a rebuild of the kext cache.
The easiest way to achieve this is via Target Disk Mode: hold T as the iMac is booting, connect it to another Mac via Thunderbolt, and use Finder on that Mac to move the files.
Otherwise it can be done by disabling SIP and booting into Single User Mode.
Disabling SIP is non-trivial since the dead graphics card will block booting into Recovery Mode.
Some online sources suggest there exists a Single User Recovery mode which can be accessed by holding Option to reach the boot options screen, then immediately holding Cmd-S after selecting the recovery partition. Should this elusive mode exist, SIP could then be disabled with csrutil disable, however, I could not manage to make this work.
Instead I found it easiest to disable SIP by booting to a macOS install USB for a version that pre-dates SIP (e.g. 10.10 Yosemite) and "manually" disabling SIP by running nvram csr-active-config="w%00%00%00" from the Terminal.
After disabling SIP, boot into Single User mode by holding Cmd-S as the iMac is booting. At the command line, run:
cd /System/Library
mkdir DisabledExtensions
mv Extensions/AMDRadeonX3000.kext DisabledExtensions/
mv Extensions/AMD6000Controller.kext DisabledExtensions/
touch Extensions
reboot
Some further notes:
- Brightness control of the display is handled by the graphics card and will no longer work
dmtestcan be used to restore a missing recovery partition as per this blog post- Some sources suggest moving all ATI* or AMD* kexts but this doesn’t appear to be necessary
- Some sources suggest changing nvram
boot-argstoagc=0oragc=-1but this also doesn’t appear to do anything on an iMac (might be relevant to MBP graphics switching)
Having disabled the graphics kexts as above, Target Display Mode will not start, and the following message may appear every 10 seconds in the Console: com.apple.xpc.launchd[1] (com.apple.dpd[182]): Service exited with abnormal code: 75.
com.apple.dpd is the service responsible for listening for Cmd-F2 and enabling Target Display Mode.
The service runs the binary at /usr/libexec/dpd.
This issue seems to just affect dpd binaries from 10.10 Yosemite onwards (tested with 10.10.5, 10.11.6, and 10.13.6), and can be resolved by copying over an older dpd from a 10.9.5 Mavericks installer.
First, download the latest Mavericks installer from the Mac App Store using the link here. It can also be downloaded using mas-cli with mas install 675248567 if it has been purchased before, as per this link.
The installer package can be directly mounted by running e.g. hdiutil attach Downloads/Mavericks.pkg. Then open /Packages/BSD.pkg in e.g. Suspicious Package and copy /usr/libexec/dpd (MD5: 6355f7378348de906ad1ace46c936c8c) to the same location on the iMac (the Finder shortcut Cmd-Shift-G to navigate to /usr/libexec, which is a hidden folder, may be useful here).
A further note:
dpdhas an associated binarydpaudiothruresponsible for passing through audio which seems to work fine on High Sierra, no replacement needed.
To enter TDM without any physical devices connected at all (e.g. over the network via SSH), install Karabiner Elements v12.10.0, the latest version available for High Sierra, which includes a compiled and signed kext for Karabiner-VirtualHIDDevice.
Then, download the binary for cmdf2 from the releases page (or download the source code and compile), move it to e.g. /usr/local/bin, and run with sudo cmdf2.
To not require a password every time with sudo, try this and specify e.g. /usr/local/bin/cmdf2.
Target Display Mode can now be toggled by running sudo cmdf2 over the network via SSH, or automatically on startup using a launchd job, or by pressing a button on an Apple Remote (I used BetterTouchTool to run commands from an Apple remote I had spare).
What didn't work for me but might for others:
osascriptover SSH works on macOS 10.6.8 (apparently up to 10.9.5 according to some sources):osascript -e 'tell application "System Events" to key code 144 using command down'. Confirmed not working on 10.13.6 despite enabling Accessibility access for Terminal and Script Editor.- VirtualKVM automatically toggles TDM upon attach/detach of the Thunderbolt cable (and enable/disable of Bluetooth to transfer mouse/keyboard control), but requires an app running in the background on both devices. I couldn’t get it to work, possibly due to network issues, or possibly because I was daisy-chaining my iMac off an Apple Thunderbolt Display (Main MacBook Pro <-> Thunderbolt Display <-> iMac in Target Display Mode).
- https://github.com/BlueM/cliclick didn’t work over SSH, tried Cmd with F2, brightness, etc.
- Remapping using Karabiner as per this SE post.
- Remapping keys with
hidutilandlaunchdas per here and here
References:
cmdf2is based on this example code- https://github.com/pqrs-org/Karabiner-VirtualHIDDevice-archived/blob/master/src/include/karabiner_virtual_hid_device.hpp.tmpl
- https://opensource.apple.com/source/IOHIDFamily/IOHIDFamily-700/IOHIDFamily/AppleHIDUsageTables.h
The iMac fan will run at maximum speed if the hard drive is removed, because Apple hard drives contain a built-in temperature sensor, and removal of the sensor causes SMC to run the fan at maximum to be safe.
To solve this, install smcFanControl. This includes the command-line tool smc for controlling fans, which can be automated using a launchd script (in this repo as com.local.LimitHDDFan.plist). E.g. /Applications/smcFanControl.app/Contents/Resources/smc -k F1Mx -w 1130.
To avoid overheating, iMac temperatures can be monitored over SSH by installing HardwareMonitor. Run /Applications/HardwareMonitor.app/Contents/MacOS/hwmonitor -c.
References:
smctool info https://discussions.apple.com/thread/2554924- launchd template: https://superuser.com/questions/229773/run-command-on-startup-login-mac-os-x (Note: use RunAtLoad instead of LaunchOnlyOnce)
The iMac I was using for this project has since had its power supply fail and I don't see any further work being done here.
However, if someone wants to build on the cmdf2 code to write something that e.g. automatically enters Target Display Mode when the Thunderbolt cable is connected, let me know and I would be happy to link to it from here.
These notes and code are released under the MIT license, see LICENSE.