DEV Community

Cover image for ArchLinux Setup Guide For Intel MacBook Pro
Denis Sedchenko
Denis Sedchenko

Posted on

ArchLinux Setup Guide For Intel MacBook Pro

Intro

This article is a collection of caveats necessary to get Arch Linux up and running on old Intel MacBooks with AMD GPUs.

In my case, it's old MacBookPro11,5

Steps here are based on various articles and hours of painful debugging.

Article skips full Arch setup process, focusing only on MacBook-specific steps.

This article assumes that you’re using:

  • PipeWire as audio server.
  • Wayland with Hyprland as a compositor.

Sources

Information in this article is based on following sources:

Table Of Contents

Bootloader

Apple introduces certain limitations for non-macOS systems, such as inability to use Intel GPU.

The most convenient way to bypass them is using rEFInd bootloader.
rEFInd handles MacOS version spoofing, SIP and other stuff out of the box.

rEFInd Installation

Install rEFInd by following instructions from ArchWiki.

⚠️ Important
Don’t forget to add Linux boot configuration into rEFInd config file /boot/EFI/refind/refind.conf

Set Apple OS

Apple blocks access to integrated Intel GPU for any non-macOS operating system.

rEFInd provides a way to workaround this with spoof_osx_version config parameter.

Open /boot/EFI/refind/refind.conf and add a following parameter:

spoof_osx_version 12.7
Enter fullscreen mode Exit fullscreen mode

Extra Boot Arguments

Add following options to your Arch Linux menu entry in rEFInd config:

data=writeback libata.force=1:noncq acpi_mask_gpe=0x06 acpi_osi=Darwin i915.modeset=1 amdgpu.modeset=0 amdgpu.runpm=1
Enter fullscreen mode Exit fullscreen mode

Setting rEFInd as default bootloader

Unlike Grub or systemd-boot, rEFInd places itself into a non-standard directory inside EFI partition.

Use efibootmgr to add rEFInd as boot entry:

efibootmgr -c -L 'rEFInd Boot Manager' -l '\EFI\refind\refind_x64.efi'
Enter fullscreen mode Exit fullscreen mode
⚠️ Important
Remove old macOS boot entries using efibootmgr to avoid having long boot delays.

Network

Network Manager

NetworkManager won’t let you to connect to a WiFI without a proper dbus session and keychain provider.

The simplest and most reliable way is to use iwd instead:

pacman -S iwd
systemctl disable --now NetworkManager
systemctl enable --now systemd-resolved
systemctl enable --now systemd-networkd
systemctl enable --now iwd
Enter fullscreen mode Exit fullscreen mode
💡 Tip
Check this ArchWiki page for instructions how to connect to a WiFi network.

Broadcom

You might encounter issues related to missing Broadcom firmware.

In that case, installing broadcom-wl might help:

paru broadcom-wl-dmks
Enter fullscreen mode Exit fullscreen mode

Then, create /etc/modprobe.d/broadcom-wl-dkms.conf:

blacklist brcm80211
Enter fullscreen mode Exit fullscreen mode

GPU Power Management

Unfortunately AMD Cape-Verde gGPUs don’t support dynamic power management. This means, dGPU has to be shut down manually in order to save battery.

Udev Rules

Create /etc/udev/rules.d/30-amdgpu-pm.rules

ACTION=="add", SUBSYSTEM=="drm", DRIVERS=="amdgpu", ATTR{device/power/control}="auto"
ACTION=="add", SUBSYSTEM=="drm", DRIVERS=="amdgpu", ATTR{device/power_dpm_force_performance_level}="low"
Enter fullscreen mode Exit fullscreen mode

Kernel Modules

Go to /etc/modprobe.d and create a couple of files.

amdgpu.conf

options amdgpu modeset=0
options amdgpu enable_psr=1
options amdgpu si_support=1
options amdgpu cik_support=1
options amdgpu runpm=1
Enter fullscreen mode Exit fullscreen mode

radeon.conf

options radeon si_support=0
options radeon cik_support=0
options radeon runpm=1
Enter fullscreen mode Exit fullscreen mode

Then run sudo mkinitcpio -P to apply changes.

Use Integrated GPU On Boot Using gpu-switch

Install gpu-switch tool from AUR using Paru.

Then, use a following command to set iGPU as a primary GPU to drive display:

sudo gpu-switch -i
Enter fullscreen mode Exit fullscreen mode
ℹ️ Note
Operation takes affect only after reboot.

Disable AMDGPU HDMI Audio

WirePlumber is using /dev/snd/controlC2 which is AMD GPU's HDMI Audio.

This prevents AMDGPU to put a device into D3 cold state.

Make ~/.config/wireplumber/wireplumber.conf.d/50-disable-dgpu-hdmi.conf:

# disable the HDA function on the Radeon R9 M370X (PCI 01:00.1)
monitor.alsa.rules = [
  {
    matches = [
      { "device.name" = "alsa_card.pci-0000_01_00.1" }
    ]
    actions = { update-props = { device.disabled = true } }
  }
]
Enter fullscreen mode Exit fullscreen mode

After:

  • restart wireplumber: systemctl --user restart wireplumber
  • check if DIS-Audio is DynOff: sudo cat /sys/kernel/debug/vgaswitcheroo/switch

Turn Off Discrete AMD GPU

Both GPUs are controlled using Apple's GMUX. It is responsible for turning on and off discrete AMD GPU.

The vga-switcheroo kernel module is responsible for controlling a mux.

# set to integrated
sudo sh -c 'echo IDG > /sys/kernel/debug/vgaswitcheroo/switch'

# turn off dGPU
sudo sh -c 'echo OFF > /sys/kernel/debug/vgaswitcheroo/switch'

# print mux state.
# ensure that "DIS" is "OFF" and "DIS-Audio" is "DynOff"
sudo cat /sys/kernel/debug/vgaswitcheroo/switch
Enter fullscreen mode Exit fullscreen mode

Output of /sys/kernel/vgaswitcheroo/switch should look like this:

0:IGD:+:Pwr:0000:00:02.0
1:DIS: :Off:0000:01:00.0
2:DIS-Audio: :DynOff:0000:01:00.1
Enter fullscreen mode Exit fullscreen mode

Disable dGPU On Boot

Create oneshot systemd unit file /etc/systemd/system/dgpu-poweroff.service:

[Unit]
Description=Disable discrete GPU (vgaswitcheroo OFF)
Requires=sys-kernel-debug.mount
After=sys-kernel-debug.mount

[Service]
Type=oneshot
ExecStart=/bin/sh -c 'echo OFF > /sys/kernel/debug/vgaswitcheroo/switch'

[Install]
WantedBy=multi-user.target suspend.target   # run at boot *and* after resume
Enter fullscreen mode Exit fullscreen mode

Then, start the service:

sudo systemctl daemon-reload
sudo systemctl enable --now dgpu-poweroff.service
Enter fullscreen mode Exit fullscreen mode

Use iGPU for Hyprland

Find GPU PCI of integrated GPU:

$ lspci | grep VGA
00:02.0 VGA compatible controller: Intel Corporation Crystal Well Integrated Graphics Controller (rev 08)
01:00.0 VGA compatible controller: Advanced Micro Devices, Inc. [AMD/ATI] Venus XT [Radeon HD 8870M / R9 M270X/M370X] (rev 83)
Enter fullscreen mode Exit fullscreen mode

Check what DRI card maps to PCI ID:

$ ls -l /dev/dri/by-path
total 0
lrwxrwxrwx 1 root root  8 Apr 23 03:14 pci-0000:00:02.0-card -> ../card1
lrwxrwxrwx 1 root root 13 Apr 23 03:14 pci-0000:00:02.0-render -> ../renderD128
lrwxrwxrwx 1 root root  8 Apr 23 03:14 pci-0000:01:00.0-card -> ../card0
lrwxrwxrwx 1 root root 13 Apr 23 03:14 pci-0000:01:00.0-render -> ../renderD129
Enter fullscreen mode Exit fullscreen mode

In my case, card1 is Intel and card0 is AMD.

To make Intel GPU a preferred GPU for Hyprland, add following into a ~/.config/hypr/hyprland.conf:

# Prefer iGPU
env = AQ_DRM_DEVICES,/dev/dri/card1
Enter fullscreen mode Exit fullscreen mode

Power Efficiency

Even with disabled AMD GPU, MacBook still consumes about 15–20 watts (which is a lot).

Although there are a lot of things that can be tweaked, the most basic thing to address is setting a correct CPU power profile.

Battery Monitoring

I recommend using battop tool to monitor power consumption during power optimization.

iGPU Tweaks

PSR (panel self-refresh) and FBC (frame-buffer compression) save ~0.3-0.5 W when the screen shows static content.

Create /etc/modprobe.d/i915.conf:

options i915 enable_psr=1
options i915 enable_fbc=1
options i915 enable_dc=1
Enter fullscreen mode Exit fullscreen mode

Pefrormance Power Profile

Automatic Power Profiles

The auto-cpufreq daemon allows automatic CPU power profile configuration based on battery capacity and charging status.

Pros:

  • Automatic power profile management based on charging state.

Cons:

  • By default it will put CPU into a power save mode when not connected to a charger. This will cause a drastic performance decrease.
  • Written in Python and consumes 20MB of RAM which is quite a lot for a simple CPU frequency daemon.

Install auto-cpufreq daemon to automatically control CPU frequency:

paru auto-cpufreq
sudo systemctl enable --now auto-cpufreq
Enter fullscreen mode Exit fullscreen mode
⚠️ Important
Don't install auto-cpufreq-git as it's broken.

Switch Power Profiles Manually

power-profiles-deamon package provides DBus service and a tool to switch CPU profiles.

sudo pacman -S power-profiles-daemon
sudo systemctl enable --now power-profiles-daemon.service
Enter fullscreen mode Exit fullscreen mode

Later, you can change power profile to power saver, performance or balanced:

powerprofilesctl set power-saver
powerprofilesctl set balanced
Enter fullscreen mode Exit fullscreen mode

Top comments (0)

OSZAR »