Previous post Next post Back to top Share post

Reviving an old MacBook Air

I’m someone who loves new technology. But I also like to get use out of old kit that be given a new lease on life. My old MacBook Air (model A1466) is a case in point as it’s no longer supported by the latest version of MacOS. I’ve installed Arch Linux on it so I can use it with up-to-date software and this post publishes the notes and tips I captured during that journey. I also cover an approach to encrypting data at rest. I hope that this post will help others with the quirks and hardware challenges I ran into.


Prerequisites

  • A way to create the USB installer, like another Linux system or MacOS
  • Arch Linux ISO (available at https://archlinux.org)
  • A USB flash drive (8GB or larger recommended)
  • At least 2 hours for installation and initial configuration

Step 1: Creating a Bootable ISO

First, create a bootable USB drive with the Arch Linux ISO. My laptop is one of the old Intel Macs, and so I needed the x86_64 ISO.

dd bs=4M if=./archlinux-<version>-x86_64.iso of=/dev/sdX status=progress

Replace /dev/sdX with your USB drive identifier (verify with lsblk).


Step 2: Partitioning the Disk

Boot from the USB installer and start partitioning. On my old Macbook Air I need to hold down the ALT (option) key while booting to select the USB device.

I used fdisk to create the following simple partitioning scheme. For additional security you can encrypt your partitions using dm-crypt.

Partition Size Type Format Mount Point
EFI System Partition 512MB 1200 (UEFI) FAT32 /boot
Swap 8GB 8200 Swap
Root Remainder 8300 ext4 /

After partitioning, fdisk reports my disk structure as:

Disk /dev/sda: 113 GiB, 121332826112 bytes, 236978176 sectors
Disk model: APPLE SSD TS128E
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disklabel type: gpt
Disk identifier: 793881B3-6CDD-4072-A2F0-C3DDF4BC532E

Device        Start       End   Sectors   Size Type
/dev/sda1      2048   1050623   1048576   512M EFI System
/dev/sda2   1050624  17827839  16777216     8G unknown
/dev/sda3  17827840 236976127 219148288 104.5G unknown

Formatting and mounting partitions

For an unencrypted setup, use:

# Example: Creating unencrypted partitions (modify for encryption if desired)

mkfs.fat -F32 /dev/sdX1   # EFI or boot partition
mkswap /dev/sdX2          # Swap partition
mkfs.ext4 /dev/sdX3       # Root partition

swapon /dev/sdX2
mount /dev/sdX2 /mnt
mount --mkdir /dev/sdX1 /mnt/boot

If you want encrypted partitions, use:

cryptsetup -y -v luksFormat /dev/sdX2  # Swap
cryptsetup -y -v luksFormat /dev/sdX3  # Root

mkfs.fat -F32 /dev/sdX1  # EFI (not encrypted for UEFI boot)
mkswap /dev/mapper/swap
mkfs.ext4 /dev/mapper/root

swapon /dev/mapper/swap
mount /dev/mapper/root /mnt
mount --mkdir /dev/sdX1 /mnt/boot

Step 3: Installing Base System

# Install base system
pacstrap -K /mnt base linux linux-firmware vim

# Generate a fstab file
genfstab -U /mnt >> /mnt/etc/fstab

# Then chroot into the new system
arch-chroot /mnt

Step 4: Configure the Base System

Timezone and Locale

I live in Melbourne and have used that timezone in the example below. You’ll want to link the timezone file appropriate to your location.

ln -sf /usr/share/zoneinfo/Australia/Melbourne /etc/localtime
hwclock --systohc
timedatectl set-timezone Australia/Melbourne

Locale Configuration

vim /etc/locale.gen
# Uncomment: en_US.UTF-8 UTF-8

# Then re-generate the configured locales
locale-gen

# Create locale.conf and set the LANG variable accordingly
vim /etc/locale.conf
# Set LANG=en_AU.UTF-8, or a locale appropriate for you

Configure hooks to bootstrap encryption

If you’ve used cryptsetup to create encrypted partitions, you need to add hooks that map the encrypted swap partition when your system boots.

# Create /etc/initcpio/hooks/openswap with the following:
run_hook ()
{
    cryptsetup open /dev/sdX2 swap
}

# And create /etc/initcpio/install/openswap with the following:
build ()
{
    add_runscript
}
help ()
{
cat<<HELPEOF
    This opens the encrypted partition /dev/<device> in /dev/mapper/swapDevice
HELPEOF
}

Then Add the hook openswap into the HOOKS array in /etc/mkinitcpio.conf, before filesystem but after encrypt.

vim /etc/mkinitcpio.conf
HOOKS=(base udev autodetect modconf kms keyboard keymap consolefont block encrypt openswap resume filesystems fsck)

mkinitcpio -P

Step 5: Install and Configure GRUB

First, install GRUB:

pacman -S grub efibootmgr
grub-install --target=x86_64-efi --efi-directory=/boot --bootloader-id=GRUB

Configure GRUB for Encryption

If you’ve encrypted your root partition you’ll need to configure the boot loader to handle encrypted partitions.

GRUB_ENABLE_CRYPTODISK should remain commented out. GRUB needs to run in its own initramfs before you can decrypt your partitions.

Edit /etc/default/grub and ensure this line is present:

GRUB_CMDLINE_LINUX_DEFAULT="loglevel=3 cryptdevice=/dev/sdXx:root root=/dev/mapper/root resume=/dev/mapper/swap ro"

Generate the GRUB configuration:

generate-grub.cfg

Remove your installation media and reboot.


Step 6: Perform a System Upgrade

It’s a good idea to upgrade all of your packages. You can also use this step to install any essential software you need.

pacman -Syu

Step 7: X Server and Display Manager

I use the i3-wm window manager. It’s very simple and you might want to use something more feature rich.

Install Graphics Components

pacman -S xorg-server xorg-xinit xterm i3-wm

Configure Xinit

Create or edit ~/.xinitrc:

vim ~/.xinitrc
# add the line:
exec i3

Start the X window system

startx

Install SDDM for Graphical Login

Again, you might want to use a different graphical tool for login where I’ve opted for SDDM.

pacman -S sddm
systemctl enable sddm
reboot

Step 8: Fixing MacBook Air-Specific Issues

And now we’re down to quality-of-life features that need some tweaking to work on the old Mac hardware.

Keyboard and Touchpad

Enable Tap-to-Click

Create /etc/X11/xorg.conf.d/touchpad-tap.conf:

Section "InputClass"
    Identifier "libinput touchpad catchall"
    MatchIsTouchpad "on"
    MatchDevicePath "/dev/input/event*"
    Driver "libinput"
    Option "Tapping" "on"
EndSection

Enable Natural Scrolling

Create /etc/X11/xorg.conf.d/99-touchpad-natural-scroll.conf:

Section "InputClass"
    Identifier "mytouchpad"
    MatchIsTouchpad "on"
    Driver "libinput"
    Option "NaturalScrolling" "true"
EndSection

Get sound to work

Install audio packages:

pacman -S alsa-lib alsa-plugins alsa-topology-conf alsa-ucm-conf alsa-utils pulseaudio-alsa libpulse pulseaudio

Create /etc/asound.conf:

pcm.!default {
    type pulse
    fallback "sysdefault"
    hint {
        show on
        description "Default ALSA Output currently PulseAudio Server"
    }
}

ctl.!default {
    type pulse
    fallback "sysdefault"
}

Audio Shortcuts in i3

To get the hardware control buttons working, specifically volume, keyboard backlight and screen brightness, add these to ~/.config/i3/config:

# Volume control
bindsym XF86AudioRaiseVolume exec --no-startup-id pactl set-sink-volume @DEFAULT_SINK@ +1% && $refresh_i3status
bindsym XF86AudioLowerVolume exec --no-startup-id pactl set-sink-volume @DEFAULT_SINK@ -1% && $refresh_i3status
bindsym XF86AudioMute exec --no-startup-id pactl set-sink-mute @DEFAULT_SINK@ toggle && $refresh_i3status
bindsym XF86AudioMicMute exec --no-startup-id pactl set-source-mute @DEFAULT_SOURCE@ toggle && $refresh_i3status

# Keyboard backlight
bindsym XF86KbdBrightnessUp exec --no-startup-id brightnessctl --device='smc::kbd_backlight' set +10
bindsym XF86KbdBrightnessDown exec --no-startup-id brightnessctl --device='smc::kbd_backlight' set 10-

# Monitor brightness
bindsym XF86MonBrightnessUp exec --no-startup-id brightnessctl --device='acpi_video0' set +1%
bindsym XF86MonBrightnessDown exec --no-startup-id brightnessctl --device='acpi_video0'  set 1%-

WiFi Issues

Some MacBooks experience WiFi dropouts with the brcmsmac driver. Try the broadcom-wl driver instead:

pacman -S broadcom-wl

Create /etc/modprobe.d/fix-wifi.conf with the following:

blacklist b43
blacklist brcmsmac
blacklist ssb

Then reboot to load the new WiFi driver.

Bluetooth

pacman -S bluez pulseaudio-bluetooth bluez-utils

systemctl enable bluetooth
systemctl restart bluetooth

# Use bluetoothctl to pair with devices
bluetoothctl
[bluetooth]# power on
[bluetooth]# scan on
[bluetooth]# pair xx:xx:xx:xx:xx:xx
[bluetooth]# connect xx:xx:xx:xx:xx:xx
[Device]> scan off

To allow devices to auto connect you need to trust them. Here is an example:

[Earmuffs]> devices
Device 88:C6:26:4E:20:F4 Utiku Megaboom
Device 4C:87:5D:29:38:61 LE-Earmuffs
[Earmuffs]> trust 4C:87:5D:29:38:61
[CHG] Device 4C:87:5D:29:38:61 Trusted: yes
Changing 4C:87:5D:29:38:61 trust succeeded
[Earmuffs]> trust 88:C6:26:4E:20:F4
[CHG] Device 88:C6:26:4E:20:F4 Trusted: yes
Changing 88:C6:26:4E:20:F4 trust succeeded

Step 9: Battery Monitoring

Thanks go to Amatika’s post here: https://bbs.archlinux.org/viewtopic.php?id=259565

Install dunst for battery notifications:

pacman -S dunst

Create a monitoring script (monitor.sh):

#!/bin/bash

battery_level=`acpi | grep -oP '(?<=%)'`

if [ "$battery_level" -le 25 ]; then
    notify-send "Battery low. Battery level is ${battery_level}%!"
elif [ "$battery_level" -le 15 ]; then
    notify-send "Battery critical. Battery level is ${battery_level}%! Suspending..."
    sleep 20
    systemctl suspend
fi

Get cron to periodically run the monitor script by updating /etc/crontab:

*/1 * * * * XDG_RUNTIME_DIR=/run/user/$(id -u) /path/to/monitor.sh

Fixing Wake Issues

Sometimes the laptop wakes unexpectedly from suspend. Check what’s waking it:

cat /proc/acpi/wakeup

Disable devices that shouldn’t wake the system. I think the device I needed to disable was the laptop lid sensor. This means the lid no longer wakes the laptop when it’s opened. It does, however, still put the laptop to sleep when you close it which is great.

echo LID0 | sudo tee /proc/acpi/wakeup

Allow Suspend with Polkit

You need to add a polkit rule to allow users in the sudo group to syspend the laptop when the are in an interactive terminal. Add the following file /etc/polkit-1/rules.d/50-suspend.rules:

polkit.addRule(function(action, subject) {
    // To enable logging, remove --no-debug from /usr/lib/systemd/system/polkit.service
    polkit.log("action=" + action);
    polkit.log("subject=" + subject);
    if (action.id == "org.freedesktop.login1.suspend" &&
        subject.isInGroup("sudo")) {
        return polkit.Result.YES;
    }
});

Step 10: Additional Hardware Notes

Thunderbolt Hot-plug Support

See https://wiki.archlinux.org/title/Thunderbolt. Users who just want to connect Thunderbolt devices device without needing to manually grant access can create a custom udev rule, for example in /etc/udev/rules.d/99-removable.rules:

ACTION=="add", SUBSYSTEM=="thunderbolt", ATTR{authorized}=="0", ATTR{authorized}="1"

Step 11: Emoji Support

pacman -S noto-fonts-emoji unicode-emoji

Step 12: Thumbnail Generation

Install thumbnail generators for your file manager:

pacman -S raw-thumbnailer tumbler thumbler-extra-thumbnailers ufraw-thumbnailer

Note: Some RAW formats (like RAF files) may require additional tools.


Helpful Resources


Enjoy your Arch Linux MacBook Air!