Installing Arch Linux on a Macbook Pro (mid-2009) (and a Thinkpad T470)

Initial Install

Installation process follows that outlined in Arch Installation Guide, with the following additions/exceptions.

Boot Arch install ISO CD by holding ALT key on poweron. Select EFI boot (other choice is Windows which gives MBR boot). Be prepared to wait for a few minutes until Arch starts.

Using the mac-uk keyboard map i.e. loadkeys mac-uk kills the keyboard. No character prints what is inscribed on the key. This has been reported a couple of times, but there seems to be no reaction/fix available. I suspect this keymap is not for the Macbook Pro.

Best option for UK/International Macbook Pro keyboard seems to be to use the US keyboard layout.

The only keys not mapped correctly are (1) the section (§) key, which produces the grave character (`), (2) the grave key, which generates < and >, and (3) the £ key (shift 3), which generates a #.

I suggest a fix for this later.

Contents of /etc/vconsole.conf:

  # Closest match for Macbook Pro keyboard in console mode
  KEYMAP=us

Decided to use btrfs (for a change).

Originally had /usr as a separate partition. This caused grub to fail to find /sbin/init on reboot. There is a way of supporting a /usr partition by configuration in mkinitcpio (see /etc/mkinitcpio.conf, HOOKS), but I decided to go with the flow and just have a bigger root partition, forgetting /usr.

Partition sizing

Device Mount Point Size
/dev/sda1 EFI System 256MB
/dev/sda2 Swap 8GB
/dev/sda3 Root 30GB
/dev/sda4 var 10GB
/dev/sda5 tmp 2GB
/dev/sda6 home 172GB (the rest)

Initial set of packages

When using pacstrap, add the following packages, in addition to base, linux and linux-firmware:

  grub efibootmgr mg btrfs-progs man-db man-pages texinfo iwd binutils
  fakeroot b43-fwcutter wget iwd

NB b42-fwcutter, binutils and fakeroot are required to build the Wifi Broadcom firmware. See below.

After using arch-chroot to the /mnt directory, and following the install guide, the next step can be performed.

Setting up grub

First, install grub on the boot partition:

  # grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=GRUB

Then create the grub configuration file:

  # grub-mkconfig -o /boot/grub/grub.cfg

You can reboot now, or carry on with the next steps and then reboot.

Enabling Macbook Broadcom WiFi

The firmware for the Macbook Broadcom adapter can be downloaded from here. Use the "Download snapshot" on the left-hand menu.

This will download b43-firmware.tar.gz. Untar and cd into the resulting directory. Then issue the command:

  makepkg

If that works (it will download the firmware), the generated package can then be installed with:

  pacman -U b43-firmware-6.30.163.46-1-any.pkg.tar.zst

By the way, there's more Arch Linux Mac stuff

systemd network setup

First, enable the daemons:

  systemctl enable systemd-networkd
  systemctl enable systemd-resolved

Then, create the configuration files.

Configuration

/etc/systemd/network/20-wired.network

  [Match]
  Name=enp0s10

  [Network]
  DHCP=yes

  [DHCP]
  RouteMetric=10
  UseDomains=yes

/etc/systemd/network/25-wireless.network

  [Match]
  Name=wlan0

  [Network]
  DHCP=yes

  [DHCP]
  RouteMetric=20
  UseDomains=yes

Now the configuration files exist, start the daemons.

  systemctl start systemd-networkd
  systemctl start systemd-resolved

This setup causes a DHCP IP address to be assigned to each network adapter. See below for a different way of handling the two adapters with bonding.

Setup Wifi with iwd

  systemctl enable iwd
  systemctl start iwd

Control / set-up wireless with iwctl.

  # iwctl
  [iwd]# station wlan0 connect <station_id>

You'll be prompted for the password. NB: If this doesn't work, scan for networks first:

  [iwd]# station wlan0 scan

Note, scanning will not work if wlan0 is part of a bond (see below).

Useful ip commands

  ip addr   # shows interfaces with address
  ip link   # shows network adapters
  ip link set 'device' [up | down]

Bonding wired and wireless interfaces

Setting this up requires adding new configuraton files in /etc/systemd/network. The first two setup the virtual bond device, to which the physical network devices will be slaved:

  [mark@albino:/etc/systemd/network]$ cat 10-bond0.netdev
  [NetDev]
  Name=bond0
  Kind=bond

  [Bond]
  Mode=active-backup
  PrimaryReselectPolicy=always
  MIIMonitorSec=1s
  FailOverMACPolicy=active

  [mark@albino:/etc/systemd/network]$ cat 10-bond0.network
  [Match]
  Name=bond0

  [Network]
  DHCP=yes

  [DHCP]
  UseDomains=yes

The physical device configuration files must be modified as follows:

  [mark@albino:/etc/systemd/network]$ cat 20-wired.network
  [Match]
  Name=enp0s10

  [Network]
  RouteMetric=10
  Bond=bond0
  PrimarySlave=true

  [mark@albino:/etc/systemd/network]$ cat 25-wirelss.network
  [Match]
  Name=wlan0

  [Network]
  RouteMetric=20
  Bond=bond0

This configuration sets up the wired network as the master and preferred route. Restart systemd-networkd to pick up the configuration changes.

The state of the bond can be viewed as follows:

  [mark@albino:/etc/systemd/network]$ networkctl
  IDX LINK    TYPE     OPERATIONAL SETUP
    1 lo      loopback carrier     unmanaged
    2 bond0   bond     routable    configured
    3 enp0s10 ether    enslaved    configured
    5 wlan0   wlan     enslaved    configured

    4 links listed.
  [mark@albino:/etc/systemd/network]$ cat /proc/net/bonding/bond0
  Ethernet Channel Bonding Driver: v6.7.4-arch1-1

  Bonding Mode: fault-tolerance (active-backup) (fail_over_mac active)
  Primary Slave: enp0s10 (primary_reselect always)
  Currently Active Slave: enp0s10
  MII Status: up
  MII Polling Interval (ms): 1000
  Up Delay (ms): 0
  Down Delay (ms): 0
  Peer Notification Delay (ms): 0

  Slave Interface: enp0s10
  MII Status: up
  Speed: 1000 Mbps
  Duplex: full
  Link Failure Count: 1
  Permanent HW addr: 60:fb:42:f0:70:36
  Slave queue ID: 0

  Slave Interface: wlan0
  MII Status: up
  Speed: Unknown
  Duplex: Unknown
  Link Failure Count: 0
  Permanent HW addr: 00:26:bb:15:3c:67
  Slave queue ID: 0

NB: systemd-networkd conflicts with NetworkManager and the NetworkManager-wait-online services, which must be disabled if active.

Thanks to this link.

Setting up X

  # pacman -S lxde xorg xorg-xinit
  # Allow non-root users to run startx
  # chmod 4755 /usr/bin/startx
  $ echo "exec startlxde" >~/.xinitrc

Wallpapers

  pacman -S archlinux-wallpaper

Images are installed in /usr/share/backgrounds/archlinux.

Fonts

Microsoft fonts have to be downloaded, the package made with makepkg, and then installed via pacman:

  # pacman -U ttf-ms-fonts-2.0-12-any.pkg.tar.zst

Inconsolata is in the main packages:

  # pacman -S ttf-inconsolata

Screen brightness and keyboard backlights

The hard way ...

  # echo 100 > >/sys/class/backlight/nv_backlight/brightness
  # echo 220 > /sys/class/leds/smc::kbd_backlight/brightness

I installed acpilight, which replaces xbacklight. I followed the instructions to add my user to the video group and then added the following udev rules to /etc/udev/rules.d:

90-brightness.rules

  SUBSYSTEM=="backlight", ACTION=="add", \
    RUN+="/bin/chgrp video /sys/class/backlight/%k/brightness", \
    RUN+="/bin/chmod g+w /sys/class/backlight/%k/brightness"

95-led.rules

  SUBSYSTEM=="leds", ACTION=="add", KERNEL=="*::kbd_backlight", \
    RUN+="/bin/chgrp video /sys/class/leds/%k/brightness", \
    RUN+="/bin/chmod g+w /sys/class/leds/%k/brightness"

Then, connect xbacklight to the Macbook media keys by adding the following lines to the ~/.config/openbox/lxde-rc.xml file:

  <!-- Keybindings for Mac media keys -->
  <keybind key="XF86MonBrightnessDown">
    <action name="Execute">
      <command>xbacklight -ctrl nv_backlight -dec 5</command>
    </action>
  </keybind>
  <keybind key="XF86MonBrightnessUp">
    <action name="Execute">
            <command>xbacklight -ctrl nv_backlight -inc 5</command>
    </action>
  </keybind>
  <keybind key="XF86KbdBrightnessDown">
    <action name="Execute">
      <command>xbacklight -ctrl smc::kbd_backlight -dec 5</command>
    </action>
  </keybind>
  <keybind key="XF86KbdBrightnessUp">
    <action name="Execute">
      <command>xbacklight -ctrl smc::kbd_backlight -inc 5</command>
    </action>
  </keybind>

NFS Client

Need to install nfs-utils.

The first mount after boot takes an age (maybe systemd related?):

  # mount -t nfs opal:/home/mark /mnt
  Created symlink /run/systemd/system/remote-fs.target.wants/rpc-statd.service → /usr/lib/systemd/system/rpc-statd.service.

Subsequent mounts were fast.

After much investigation, to little effect, the slowdown was caused by:

  systectl start rpc-statd

invoked when the mount command is issued. This took about 60 seconds to complete. Starting /usr/sbin/rpc-statd manually was fast, as was a subsquent mount command. I could not figure out the real problem, but added an [Install] section to the /usr/lib/systemd/system/rpc-statd.service file:

  [Install]
  Wantedby=multi-user.target

and then enabled with

  # systemctl daemon-reload

This meant I could start rpc-statd.service at boot time. Doing this doesn't cause any boot delay, as far as I can tell.

After some more investigation, the rpc-statd hang was actually caused by sm-notify (/usr/lib/systemd/system/rpc-statd-notify.service), which is required by the rpc-statd.service. The sm-notify hang occurs when the wired ethernet is disconnected. If the Match name in 20-wired.network is changed to something that will not match, the hang does not occur. Caused by systemd-networkd trying to get a DHCP address on the wired network?

Running a bonded network (slaves wired and wireless) still has an approx 90s delay in mounting NFS.

If the wired ethernet is connected at boot, no delay in mounting.

The kludge I used above (making rpc-statd run at boot time) didn't help with a BOND.

Found this thread on askubuntu forum. The answer is to edit /usr/lib/systemd/system/systemd-networkd-wait-online.service, remove the existing ExecStart= line and replace it with the following lines:

  ExecStart=
  ExecStart=/usr/lib/systemd/systemd-networkd-wait-online --ignore enp0s10

where enp0s10 is the wired ethernet interface. This causes wait-online to succeed, irrespective of the state of the wired adapter.

Could also try the --any switch (which waits until at least one interface is online). This works and has the advantage of not needing the interface name.

The use of a bond is a bit academic. If the laptop is mobile and must connect to other wifi points, then much manual editting is required. Easier just to leave unbonded and use the wireless adapter all the time.

Sound

For sound, install alsa-utils, pulseaudio, and pulseaudio-alsa. Lxmusic doesn't want to play mp3 files (they disappear as soon as you open them in lxaudio), so installed audacious. That works fine.

Turns out lxmusic needs pacman -S libmad to play mp3 files.

Updating Arch packages

pacman -Syu: updates package list and upgrades all packages.

Aka pacman --sync --refresh --sysupgrade.

For a list of installed packages:

pacman -Qett.

Aka packman --query --explicit --unrequired --unrequired

Macbook Pro keyboard on console

To overcome the missing/transposed keys, I had to create a new keyboard map file, based on the us.map file. Files are in this location: /usr/share/kbd/keymaps/i386/qwerty. The following changes were made:

  [mark&albino:~]$ diff -u us.map uk-macbook-pro.map
  --- us.map      2021-05-15 14:44:08.311357071 +0100
  +++ uk-macbook-pro.map  2021-05-15 14:45:32.094363649 +0100
  && -1,4 +1,4 &&
  -# us.map
  +# uk-macbook-pro.map
   keymaps 0-2,4-6,8-9,12
   alt_is_meta
   include "qwerty-layout"
  && -10,8 +10,9 &&
   keycode   1 = Escape
   keycode   2 = one              exclam
   keycode   3 = two              at               at               nul              nul
  -keycode   4 = three            numbersign
  +keycode   4 = three            sterling
          control keycode   4 = Escape
  +       altgr keycode     4 = numbersign
   keycode   5 = four             dollar           dollar           Control_backslash
   keycode   6 = five             percent
          control keycode   6 = Control_bracketright
  && -50,5 +51,7 &&
   keycode  57 = space
          control keycode  57 = nul
   keycode  58 = Caps_Lock
  -keycode  86 = less             greater          bar
  +keycode  41 = section  plusminus
  +keycode  86 = grave tilde
   keycode  97 = Control

Note the map file has to be gzipped before placing in the keymaps directory.

Macbook Pro keyboard under X11

My first attempt (after much research) at getting the keyboard working properly (i.e. what is printed is the same as the key is labelled) led to this configuration file (/etc/X11/xorg.conf.d/00-keyboard.conf):

  Section "InputClass"
        Identifier "Generic Keyboard"
        MatchIsKeyboard "on"
        Driver  "kbd"
        Option  "CoreKeyboard"
        Option  "XkbRules"      "xorg"
        Option  "XkbLayout"     "gb"
        Option  "XkbModel"      "pc105"
        Option  "XkbVariant"    "mac"
        Option  "XkbOptions"    "lv3:rwin_switch"
  EndSection

I believe the lv3:rwin_switch option emits the #hash; symbol when the AltGR key (right-hand Alt alt key) is pressed with the 3 key.

Everything seemed to work except the section and grave keys were switched. I could find no options (e.g. Option XkbOptions "apple:badmap") which would fix this. Then I found (even worse) the arrow keys weren't being recognised.

Yet more research ...

Testing combinations keyboard setup is made easier by using setxkbmap. For example, this is the closest I could get to matching the keyboard:

  setxkbmap -layout gb -variant mac

This xorg configuration is correct, apart from the § and grave (`) keys being swapped. This can be fixed by modifing /usr/share/X11/xkb/symbols/gb:

  [mark@albino:/usr/share/X11/xkb/symbols]$ diff -u gb~ gb
  --- gb~ 2021-05-14 19:55:48.024452514 +0100
  +++ gb  2021-05-15 14:22:28.911999295 +0100
  && -188,8 +188,8 &&

       key <AE02> { [ 2,              at,         EuroSign    ]       };
       key <AE03> { [ 3,        sterling,       numbersign    ]       };
  -    key <LSGT> { [ section,       plusminus ]    };
  -    key <TLDE> { [ grave,      asciitilde ]    };
  +    key <TLDE> { [ section,       plusminus ]    };
  +    key <LSGT> { [ grave,      asciitilde ]    };

       include "level3(ralt_switch)"
       include "level3(enter_switch)"

This vital change was found from this article.

Then I could create an X11 keyboard configuration file using localectl:

  doas localectl set-x11-keymap gb "" mac

This produces a /etc/X11/xorg.conf.d/00-keyboard.conf with the following contents:

  # Written by systemd-localed(8), read by systemd-localed and Xorg. It's
  # probably wise not to edit this file manually. Use localectl(1) to
  # instruct systemd-localed to update it.
  Section "InputClass"
          Identifier "system-keyboard"
          MatchIsKeyboard "on"
          Option "XkbLayout" "gb"
          Option "XkbVariant" "mac"
  EndSection

LX Terminal - Dracula colour scheme settings

This is a manual exercise; create a custom Palette, selecting the appropriate Dracula colour for each of the standard LXTerminal colours. Once configured, the setup is in ~/.config/lxde/lxterminal/lx-terminal.conf. This can be copied into a new configuration, if necessary.

Issues

The one remaining problem is that on rsync'ing large datasets, the rsync process stalls after a period of time. Test case is copying around 60GB of mp3 files with both wired and wireless interfaces active.

What's the cause? Could be the ethernet driver, the use of bonding, btrfs ... Hard to say. There are a couple of reports of ssh stalling over a bonded network, but no helpful solutions.

First start: forcedeth. Added these options to /etc/modprobe.d/forcedeth.conf:

  options forcedeth msix=0 msx=0

Didn't help. Disconnecting the wire and reconnecting didn't make the rsync start again. Then tried without the bond, just the wired interface. No stalls. Seems that it is the bond that triggers the issue. Well, this is a rare operation, so I shall not worry about it.

Modifications for a Thinkpad T470

Networking

  /etc/systemd/network/20-wired.network

  [Match]
  Name = enp0s31f6

  [Network]
  DHCP=yes

  [DHCP]
  RouteMetric=10

Keyboard led lights

On the Thinkpad T470, the FN-Space combination works to control the led brightness.

Keyboard settings

/etc/X11/xorg.conf.d/00-keyboard.conf:

  Section "InputClass"
        Identifier "system-keyboard"
        MatchIsKeyboard "on"
        Option "XkbLayout" "gb"
        Option "XkbModel" "pc105"
  EndSection

For Thinkpad T470 console keyboard, enter the following into /etc/vconsole.conf:

  KEYMAP=uk

Screen brightness

Set via ACPI:

  # echo 1515 /sys/class/backlight/intel_backlight/brightness

T470 Wireless - Intel Dual Band Wireless AC 8260

Stalls a lot. Placed these options in /etc/modprobe.d/iwlwifi.conf:

  options iwlwifi power_save=0
  options iwlmvm power_scheme=0
  options iwlwifi 11n_disable=1 swcrypto=1

These options turn off power saving, use of 11n and software crypto (I think). Stalls stopped..

Later...

The danger of blindly following instructions on the internet. In an attempt to figure out why the volume media keys weren't generating the codes I expected, I tried holding down control, alt, R and P keys, while pressing power button. Woe. This stopped the macbook finding the boot disk on restart. A flashing folder with a question mark was all that was displayed.

I suspected the grub boot had been clobbered. To fix, boot from the Arch installed DVD, mount the filesystems from the SSD (as stated in the install instructions, and then re-install grub on /boot/efi. This fixed the boot issue.

The volume keys still don't work as I expect.