Arch Linux on the MacBook

Do not follow this “tutorial” blindly, and do not run any command without knowing exactly what it does.
I did this installation in 2014 and I am posting it here at the request of a member of the Arch Linux Brasil group on Facebook. The process is very similar to the one described in my 2012 tutorial, but the MacBook needs special attention. The article is a bit incomplete, but I will probably not edit it any time soon.
I no longer use this dualboot setup, since I did not find the result very satisfying: Wi-Fi failed sometimes, the touchpad does not work as well as on OS X (I even went as far as editing the drivers’ source code, in vain), the battery lasted less, and it was taking up a lot of space on my 128GB SSD.
I now have a desktop running Arch, an external drive with several Live CDs and a few virtual machines on OS X. So far that setup has handled everything I need.
Why a Macbook?
My Acer, which was already old and slow, had another screen problem, so I decided it was time to change laptops.
I was still living in Germany and found a MacBook Air 13" being auctioned on Ebay. I made a fairly low bid, but managed to win. The keyboard is German, but it was easy enough to get used to.
Although I have some criticisms of Apple products, I have to admit that the hardware quality is excellent, as is the resale value. There is also the possibility of developing for iOS.
In terms of software, OS X is not really disappointing. Since I bought it, I have run Mavericks, Yosemite and El Capitan without trouble. Much FOSS is also available, since Darwin is Unix-like (and POSIX!).
Backing up and updating OS X
To cut down the risk of trouble, back up your files, free up disk space and update OS X.
Partitioning the disk
Split Macintosh HD into two partitions using Disk Utility. I used only 23GB for Arch, since my
MacBook’s SSD holds just 128GB.
Archboot over USB
Download the latest version of Arch from https://www.archlinux.org/download/ and write the .iso to a flash drive:
sudo dd if=archlinux-2014.10.01-dual.iso of=/dev/rdisk2 bs=1m
UEFI Boot Manager
Since kernel 3.3, it has been possible to boot Linux without using bootloaders such as GRUB, thanks to EFISTUB.
All we need is a boot manager to pick between the different operating systems.
Systemd-boot
Formerly called gummiboot, it is the simplest boot manager and has the fewest features. I will not
use it.
rEFInd
rEFInd is a fork of rEFIt. It basically shows a menu during boot that lets you pick the operating system to start.
On El Capitan, you have to run csrutil disable in Recovery Mode first.
Download the latest version available on the site and install it with the following options:
sudo ./install.sh --alldrivers
I am installing to the ESP, since I use Whole-Disk Encryption on OS X.
diskutil list
mkdir /Volumes/ESP
sudo mount -t msdos /dev/disk0s1 /Volumes/ESP
Rename the folder and the .efi file if you get a 30s delay during boot:
# mv /Volumes/ESP/EFI/refind /Volumes/ESP/EFI/BOOT
# mv /Volumes/ESP/EFI/BOOT/refind_x64.efi /Volumes/ESP/EFI/BOOT/bootx64.efi
Add the following line to refind.conf:
dont_scan_volumes ""
(That line is commented out as #dont_scan_volumes "Recovery HD".)
Installation
Plug the flash drive into a USB port and restart the computer. One of the icons in rEFInd should
boot from the flash drive. Here it shows Boot Legacy OS from FAT volume.
Wi-Fi will not work, so have a USB-Ethernet adapter to hand or put the broadcom-wl-dkms driver on the flash drive.
Go through the installation as usual, but do not install any bootloader. My installation, with an encrypted disk, looks roughly like this:
loadkeys i386/qwertz/de-latin1.map.gz # or br-abnt2
timedatectl set-ntp true
fdisk -l /dev/sda # or lsblk
cryptsetup benchmark
cryptsetup -v --cipher aes-xts-plain64 --key-size 256 --hash sha1 --iter-time 1000 --use-urandom --verifiy-passphrase luksFormat /dev/sda4
cryptsetup luksDump /dev/sda4
cryptsetup luksOpen /dev/sda4 arch-luks
mkfs.ext4 -L arch /dev/mapper/arch-luks
If you want a swap:
mkswap -L swap /dev/sdXY && swapon /dev/sdXY
mount /dev/mapper/arch-luks /mnt
mkdir /mnt/boot
mount /dev/sda1 /mnt/boot
pacstrap /mnt base{,-devel}
genfstab -U -p /mnt >> /mnt/etc/fstab
arch-chroot /mnt
echo "air" > /etc/hostname
ln -sf /usr/share/zoneinfo/America/Sao_Paulo /etc/localtime
sed -i -e 's/#en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen
sed -i -e 's/#pt_BR.UTF-8 UTF-8/pt_BR.UTF-8 UTF-8/' /etc/locale.gen
locale-gen
echo LANG=en_US.UTF-8 > /etc/locale.conf
echo -e "KEYMAP=de-latin1\nFONT=latarcyrheb-sun16" > /etc/vconsole.conf
sed -i -e '/^#\[multilib\]$/,+1s/#//' /etc/pacman.conf
sed -i -e '/# Misc options/a ILoveCandy' /etc/pacman.conf
sed -i -e 's/^# Color/Color/' /etc/pacman.conf
pacman -Sy reflector
reflector --verbose -l 200 -p http --sort rate --save /etc/pacman.d/mirrorlist
$ vi /etc/mkinitcpio.conf
HOOKS="base udev autodetect modconf block encrypt filesystems keyboard keymap consolefont fsck"
mkinitcpio -p linux
passwd
pacman -S \
sudo zsh alsa-utils alsa-oss xbindkeys feh imagemagick wget \
firefox htop python python2 python-pip python2-pip git ack openssh \
apache postgresql rsync rxvt-unicode unrar zip p7zip gparted ntfsprogs \
neovim python{,2}-neovim renameutils \
mpd ncmpcpp xf86-video-vesa
# pacman -S pkgfile
# pkgfile --update
$ echo "source /usr/share/doc/pkgfile/command-not-found.zsh" >> ~/.zshrc
# amixer sset Master unmute
# amixer sset Master 50%
# speaker-test -c 2
Xdg user directories
- http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
- https://wiki.archlinux.org/index.php/Xdg_user_directories
- https://wiki.archlinux.org/index.php/XDG_Base_Directory_support
Several programs use standard directories and environment variables. The following commands create those directories:
$ sudo pacman -S xdg-user-dirs
$ nvim ~/.config/user-dirs.dirs
XDG_CACHE_HOME="${HOME}/.cache
XDG_CONFIG_HOME="${HOME}/.config
XDG_DATA_HOME="${HOME}/.config
$ sudo -e /etc/xdg/user-dirs.conf
Enabled = False
xdg-user-dirs-update
What I do is put those variables in /etc/profile and ~/.profile.
Packer
sudo pacman -S jshon expac
wget https://aur.archlinux.org/cgit/aur.git/snapshot/packer.tar.gz
tar xvzf packer.tar.gz && cd packer && makepkg
sudo pacman -U packer-20150808-1-any.pkg.tar.xz
rm -rf ~/packer
Byobu
packer byobu
byobu-enable
echo 'set -g default-terminal "screen-256color"' >> ~/.byobu/profile.tmux
SSH
$ sudo -e /etc/ssh/sshd_config
Edit the file to improve security
sudo systemctl enable sshd.socket --now
ssh-keygen -t rsa -b 4096 -f ~/.ssh/servidorx -C "pubkey para servidor X"
ssh-copy-id -i ~/.ssh/servidorx.pub '-p 2345 usuario@servidorx'
chmod 700 ~/.ssh && chmod 600 ~/.ssh/servidorx && chmod 400 ~/.ssh/authorized_keys
$ nvim ~/.ssh/config
Host servidorx
HostName ssh.servidorx
IdentityFile ~/.ssh/servidorx
User usuario
Port 2345
rEFInd.conf
$ vim /boot/EFI/refind/refind.conf
menuentry Arch {
icon EFI/refind/icons/os_arch.png
loader vmlinuz-linux
initrd initramfs-linux.img
options "cryptdevice=/dev/sda4 rw root=/dev/mapper/arch-luks"
}
Internet
Without any manager
Cable
To connect to the network just once over DHCP:
dhcpcd enp0s20u1
Wifi
Driver: https://aur.archlinux.org/packages/broadcom-wl/.
The broadcom-wl-dkms driver works well too.
sudo pacman -S wpa_supplicant
packer broadcom-wl
sudo wifi-menu wlp3s0
Networkd
Static configuration. Not recommended for laptops, but rather for servers and desktops that always connect to the same networks.
> nvim /etc/systemd/network/enp2s2.network
[Match]
Name=enp2s2
[Network]
DHCP=yes
systemctl enable systemd-resolved --now
ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf
systemctl enable systemd-networkd --now
There is also Netctl.
User groups and enabling sudo
useradd -m -g users -G wheel -s /bin/zsh julio ### Maybe audio too
passwd julio
EDITOR=nvim visudo
Uncomment the line %wheel ALL=(ALL) ALL
Backlight:
echo "255" > /sys/class/leds/smc\:\:kbd_backlight/brightness
or
cp /sys/class/leds/smc\:\:kbd_backlight/max_brightness /sys/class/leds/smc\:\:kbd_backlight/brightness
Audio
Add your user to the audio group: $ sudo gpasswd -a julio audio.
Start Pulseaudio: $ pulseaudio --start.
Control the outputs with pavucontrol.
Enable simultaneous playback with paprefs.
Video
Video driver: xf86-video-intel.
Add your user to the video group: $ sudo gpasswd -a julio video.
X11
German keyboard and natural scrolling with the touchpad:
setxkbmap -layout de -model macbook79 -option caps:swapescape
$ cat ~/.Xmodmap
keycode 54 = c C c C ccedilla Ccedilla
keycode 57 = n N n N dead_tilde N dead_tilde
!Natural Scrolling
pointer = 1 2 3 5 4 7 6 8 9 10 11 12 13 14 15
Add keyboard to HOOKS after autodetect in /etc/mkinitcpio.conf.
Touchpad
Add your user to the input group: $ sudo gpasswd -a julio input.
I tried several different drivers and settings. Unfortunately no option works as well as on OS X.
xf86-input-synaptics-mtpatch
Edit the file /etc/X11/xorg.conf.d/10-synaptics.conf:
Section "InputClass"
Identifier "touchpad_catchall"
Driver "synaptics"
MatchIsTouchpad "on"
MatchDevicePath "/dev/input/event*"
Option "LeftEdge" "-3611"
Option "RightEdge" "4246"
Option "TopEdge" "517"
Option "BottomEdge" "6108"
Option "FingerLow" "25"
Option "FingerHigh" "75"
Option "FingerPress" "257"
Option "MaxTapTime" "180"
Option "MaxTapMove" "511"
Option "MaxDoubleTapTime" "180"
Option "SingleTapTimeout" "180"
Option "ClickTime" "100"
Option "FastTaps" "0"
Option "EmulateMidButtonTime" "0"
Option "EmulateTwoFingerMinZ" "283"
Option "EmulateTwoFingerMinW" "7"
Option "VertScrollDelta" "-220"
Option "HorizScrollDelta" "-220"
Option "VertEdgeScroll" "0"
Option "HorizEdgeScroll" "0"
Option "CornerCoasting" "0"
Option "VertTwoFingerScroll" "1"
Option "HorizTwoFingerScroll" "1"
Option "MinSpeed" "1.03333"
Option "MaxSpeed" "1.4"
Option "AccelFactor" "0.017"
Option "TrackstickSpeed" "40"
Option "EdgeMotionMinZ" "30"
Option "EdgeMotionMaxZ" "160"
Option "EdgeMotionMinSpeed" "1"
Option "EdgeMotionMaxSpeed" "929"
Option "EdgeMotionUseAlways" "0"
Option "TouchpadOff" "0"
Option "LockedDrags" "0"
Option "LockedDragTimeout" "5000"
Option "RTCornerButton" "0"
Option "RBCornerButton" "0"
Option "LTCornerButton" "0"
Option "LBCornerButton" "0"
Option "TapButton1" "1"
Option "TapButton2" "3"
Option "TapButton3" "2"
Option "ClickFinger1" "1"
Option "ClickFinger2" "3"
Option "ClickFinger3" "0"
Option "CircularScrolling" "0"
Option "CircScrollDelta" "0.1"
Option "CircScrollTrigger" "0"
Option "CircularPad" "0"
Option "PalmDetect" "1"
Option "PalmMinWidth" "9"
Option "PalmMinZ" "180"
Option "CoastingSpeed" "20"
Option "CoastingFriction" "50"
Option "PressureMotionMinZ" "30"
Option "PressureMotionMaxZ" "160"
Option "PressureMotionMinFactor" "1"
Option "PressureMotionMaxFactor" "1"
Option "GrabEventDevice" "1"
Option "TapAndDragGesture" "1"
Option "AreaLeftEdge" "0"
Option "AreaRightEdge" "0"
Option "AreaTopEdge" "0"
Option "AreaBottomEdge" "0"
Option "HorizHysteresis" "5"
Option "VertHysteresis" "3"
Option "ClickPad" "1"
Option "RightButtonAreaLeft" "0"
Option "RightButtonAreaRight" "0"
Option "RightButtonAreaTop" "0"
Option "RightButtonAreaBottom" "0"
Option "MiddleButtonAreaLeft" "0"
Option "MiddleButtonAreaRight" "0"
Option "MiddleButtonAreaTop" "0"
Option "MiddleButtonAreaBottom" "0"
Option "SHMConfig" "on"
EndSection
xf86-input-mtrack-git
Settings: /etc/X11/xorg.conf.d/10-mtrack.conf
Section "InputClass"
MatchIsTouchpad "on"
Identifier "Touchpads"
Driver "mtrack"
Option "TrackpadDisable" "0"
Option "Sensitivity" "0.5"
Option "FingerHigh" "5"
Option "FingerLow" "1"
Option "IgnoreThumb" "true"
Option "IgnorePalm" "true"
Option "DisableOnThumb" "false"
Option "DisableOnPalm" "false"
Option "BottomEdge" "25"
Option "ButtonIntegrated" "true"
Option "ButtonMoveEmulate" "false"
Option "ClickFinger1" "1"
Option "ClickFinger2" "2"
Option "ClickFinger3" "3"
Option "TapButton1" "1"
Option "TapButton2" "3"
Option "TapButton3" "2"
Option "TapButton4" "0"
Option "ClickTime" "25"
Option "ScrollDistance" "75"
Option "SwipeUpButton" "8"
Option "SwipeDownButton" "9"
Option "SwipeLeftButton" "8"
Option "SwipeRightButton" "9"
EndSection
Gestures with Touchégg:
Install touchegg, available on the
AUR: $ packer touchegg.
Copy the configuration file:
cp -r /usr/share/touchegg/ ~/.config
Edit it by hand:
vim ~/.config/touchegg/touchegg.conf
Or with the GUI available on the AUR.
xSwipe
The wiki also suggested xSwipe, but I could not get it working. It asks you to enable SHMConfig,
but I think that is deprecated.
Disabling the touchpad while typing
Add syndaemon -t -k -i 2 & to ~/.xinitrc.
Webcam
Finding out the Mac version:
$ sudo dmidecode -s system-product-name
MacBookAir6,2
Suspend, Resume and Hibernate
Hibernate:
Add resume to HOOKS in /etc/mkinitcpio.conf:
HOOKS="base udev autodetect modconf block resume filesystems keyboard fsck"
Run mkinitcpio: # mkinitcpio -p linux
Calibrating the monitor’s colors
Save the ICC Profiles from OS X somewhere Linux can reach:
cp -r /Library/ColorSync/Profiles /Volumes/Externo
Install xcalib, available on the AUR:
packer xcalib
Copy the ICC Profiles to /usr/share/color/icc, /usr/local/share/color/icc or
/home/USER_NAME/.color/icc:
sudo cp -r /mnt/externo/Profiles /usr/share/color/icc/Profiles_Mac
Test the new configuration with the following command:
xcalib -d :0 /usr/share/color/icc/Profiles_Mac/Displays/Color\ LCD-933C106C-08BC-09AA-F750-C2A74A119DEF.icc
If it looks good, add the command to .xinitrc.
Security
Adding a firmware password
Disabling root login over ssh
Edit the sshd_config file: $ sudo vim /etc/ssh/sshd_config PermitRootLogin no
If you want Grub
pacman -S grub os-prober
grub-install --recheck --debug /dev/sda
grub-mkconfig -o /boot/grub/grub.cfg
Crypttab
$ /etc/crypttab
backup UUID=d85e844d-2233-45b1-baff-a4fa32a50d6c none luks,noauto,quiet
mpdscribble
packer mpdscribble
mkdir ~/mpdscribble
cp /usr/share/mpdscribble/mpdscribble.conf.example .mpdscribble/mpdscribble.conf
nvim .mpdscribble/mpdscribble.conf
Links
- http://blog.juliobs.com/instalacao-do-arch-linux/
- http://architectlinux.boardhost.com/index.php
- http://bmccarthy.net/2014/08/02/touchegg-on-archlinux/
- http://dabase.com/blog/Macbook_Air_Early_2014_Archlinux/
- http://loicpefferkorn.net/2015/01/arch-linux-on-macbook-pro-retina-2014-with-dm-crypt-lvm-and-suspend-to-disk/
- http://ryangehrig.com/index.php/arch-linux-on-macbook-air-2013/
- http://www.frankshin.com/installing-archlinux-on-macbook-air-2013/
- http://www.frankshin.com/macbook-air-62-2013-setting-it-up-with-archlinux/
- http://www.linuxveda.com/2015/04/20/arch-linux-tutorial-manual/
- http://www.rodsbooks.com/refind/
- https://bbs.archlinux.org/viewtopic.php?id=150276
- https://bbs.archlinux.org/viewtopic.php?id=165854
- https://bbs.archlinux.org/viewtopic.php?id=165899
- https://bbs.archlinux.org/viewtopic.php?id=171883
- https://code.google.com/p/touchegg/issues/detail?id=178
- https://code.google.com/p/touchegg/issues/detail?id=203
- https://github.com/BlueDragonX/xf86-input-mtrack
- https://help.ubuntu.com/community/MacBookAir6-2/Trusty
- https://news.ycombinator.com/item?id=8904213
- https://wiki.archlinux.org/index.php/Apple_Keyboard
- https://wiki.archlinux.org/index.php/Beginners'_guide
- https://wiki.archlinux.org/index.php/ICC_Profiles
- https://wiki.archlinux.org/index.php/Installation_guide
- https://wiki.archlinux.org/index.php/MacBook
- https://wiki.archlinux.org/index.php/MacBookPro11,x
- https://wiki.archlinux.org/index.php/Touchegg
- https://www.reddit.com/r/linux/comments/2srkva/arch_linux_on_macbook_pro_retina_2014_with/
- https://kroweer.wordpress.com/2011/09/07/creating-a-custom-arch-linux-live-usb/
- http://works13.com/blog/mac/the-best-way-of-running-arch-linux-on-a-mac.htm
- https://wiki.archlinux.org/index.php/Pkgfile#Command_not_found
- https://wiki.archlinux.org/index.php/Neovim
- https://support.apple.com/en-us/HT201255
- https://help.ubuntu.com/community/Byobu

I’m a Brazilian computer engineer based in Germany, passionate about tech, science, photography, and languages.
I’ve been programming for about two decades already, exploring everything from mobile apps and web development to machine learning. These days I focus on cloud SRE and data engineering.
I volunteer in the open source and Python communities, helping organize PyCon DE and PyData Berlin, mentoring, and contributing with code and translations.
On my blog, I share Linux tips, setup guides, and personal notes I’ve written for future reference. I hope others find them helpful as well. The content is available in multiple languages.
Browse my gallery for some of my photography.
Away from the keyboard, you’ll find me at concerts, playing clarinet, cycling, scuba diving, or exploring new places, cultures, and cuisines.
Always happy to connect! 🙂