Arch Linux on MacBook

Attention: I write all tutorials for myself according to my preferences and needs. Do not blindly follow this “tutorial” or 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 detailed in my 2012 tutorial, but the MacBook requires special attention. The article is a bit incomplete, but I probably won’t edit it anytime soon.

I no longer use this dual-boot configuration because I did not find the result very satisfactory; the Wi-Fi sometimes failed, the touchpad did not work as well as in OS X (I even tried editing the driver source code in vain), the battery lasted less, and it was taking up too much space on my 128GB SSD.

Now I have a desktop with Arch, an external HD with several Live CDs, and some virtual machines on OS X. So far, this setup has handled everything I need.

Why a MacBook?

My old Acer, which was already slow and old, had another problem with the screen, so I decided it was time to get a new laptop.

I was still living in Germany and found a MacBook Air 13" being auctioned on eBay. I made a relatively low offer, but I managed to win. The keyboard is German, but it was easy to get used to.

Despite some criticisms of Apple products, I have to acknowledge that the hardware quality is excellent, as well as the possibility of resale. There is also the possibility of developing for iOS.

In terms of software, OS X has not disappointed me. Since I bought it, I have run Mavericks, Yosemite, and El Capitan without any issues. Many FOSS are also available since Darwin is Unix-like (and POSIX!).

Backup and OS X Update

To reduce the risk of issues, back up your files, free up disk space, and update OS X.

Disk Partitioning

Split Macintosh HD into two partitions using Disk Utility. I only used 23GB for Arch, as my MacBook’s SSD has only 128GB.

Archboot via USB

Download the latest version of Arch at https://www.archlinux.org/download/ and write the .iso to a USB drive:

sudo dd if=archlinux-2014.10.01-dual.iso of=/dev/rdisk2 bs=1m

UEFI Boot Manager

Since kernel 3.3, it’s possible to boot into Linux without using bootloaders like GRUB due to EFISTUB.

We only need a boot manager to select different operating systems.

Systemd-boot

Formerly known as gummiboot, it is the simplest boot manager with fewer features. I won’t use it.

rEFInd

rEFInd is a fork of rEFIt. It basically displays a menu during boot that allows you to choose the operating system to boot into.

In El Capitan, you need to run csrutil disable in Recovery Mode first.

Download the latest version available on the website and install with the following options:

sudo ./install.sh --alldrivers

I am installing in the ESP, as I use Whole-Disk Encryption in OS X.

diskutil list
mkdir /Volumes/ESP
sudo mount -t msdos /dev/disk0s1 /Volumes/ESP

Rename the folder and the .efi file if you experience 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 ""

(This line is commented out as #dont_scan_volumes "Recovery HD").

Installation

Connect the USB drive to a USB port and restart the computer. One of the icons in rEFInd should boot from the USB drive. It will display Boot Legacy OS from FAT volume.

Wi-Fi will not work, so have a USB-Ethernet adapter or include the driver broadcom-wl-dkms on the USB drive.

Follow the installation normally, but do not install any bootloader. My installation, with an encrypted disk, is more or less as follows:

loadkeys i386/qwertz/de-latin1.map.gz             # ou br-abnt2
timedatectl set-ntp true
fdisk -l /dev/sda                                 # ou 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

Several programs use default directories and environment variables. The following commands create these 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 place these 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 for server X"
ssh-copy-id -i ~/.ssh/servidorx.pub '-p 2345 user@serverx'
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 only once to the network via DHCP:

dhcpcd enp0s20u1

Wifi

Driver: https://aur.archlinux.org/packages/broadcom-wl/.

The broadcom-wl-dkms driver also works well.

sudo pacman -S wpa_supplicant
packer broadcom-wl
sudo wifi-menu wlp3s0

Networkd

Static configuration. Not recommended for notebooks, but 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 sudo activation

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 outputs with pavucontrol.

Enable simultaneous execution 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 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 tested several drivers and different configurations. Unfortunately, none work 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 AUR: $ packer touchegg.

Copy the configuration file:

cp -r /usr/share/touchegg/ ~/.config

Edit it manually:

vim ~/.config/touchegg/touchegg.conf

Or with the GUI available on AUR.

xSwipe

The wiki also suggested xSwipe, but I couldn’t get it to work. It asks to activate SHMConfig, but I think that is deprecated.

Disable touchpad while typing

Add syndaemon -t -k -i 2 & to ~/.xinitrc.

Webcam

iSight.

Find out the Mac version:

$ sudo dmidecode -s system-product-name
MacBookAir6,2

Suspend, Resume, and Hibernate

Hibernate:

Add resume to the HOOKS in /etc/mkinitcpio.conf:

HOOKS="base udev autodetect modconf block resume filesystems keyboard fsck"

Run mkinitcpio: # mkinitcpio -p linux

Calibrate monitor colors

Save the ICC Profiles from OS X somewhere accessible by Linux:

cp -r /Library/ColorSync/Profiles /Volumes/External

Install xcalib available on 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/external/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

Add firmware password

Disable root login via 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

Julio Batista Silva
Julio Batista Silva
Data Engineer

I’m a computer engineer passionate about science, technology, photography, and languages. Currently working as a Data Engineer in Germany.

comments powered by Disqus