Notes from a first ever Arch Linux installation

After four years of using Ubuntu full-time on my laptop, I’ve been feeling like dropping out of the Canonical feature churn and trying out a more lightweight Linux distribution. I probably spend 90% of my computer time in either a web browser or a terminal session, and I definitely don’t need Gnome, snapd, or any of the other Ubuntu bells-and-whistles to make this a comfortable experience.

So I decided to dive in and give Arch Linux running XFCE a try. So far I’m really liking the minimal approach and the opportunity to get a bit closer to the underlying operating system, although some familiar annoyances still exist (spoiler: Bluetooth still sucks 😕).

XFCE4 running on Arch

Here are some notes.

Installation of Arch

I start by flashing the Arch ISO image onto a USB drive, which then booted into Arch’s live setup environment on my new box just fine.

Arch comes without a graphical installer, so a command-line installation is unavoidable. This gist contains the basic instructions to set up an encrypted Arch installation using LVM on an NVME machine.

The original Gist is updated frequently and worth checking too but at the time of writing is missing several essential packages from the pacstrap command, including mkinitcpio, lvm2, dhcpcd (seemingly essential to connect to the internet when booting from the newly-installed OS, see below) and linux (the Linux kernel, doh).

Rebooting and enabling networking

Then I rebooted. Unfortunately it was immediately clear that no internet connection was available, despite it having worked fine in the live installation environment, and ethernet being physically connected.

The problem was that dhcpcd hadn’t been installed during the pacstrap phase, and starting the installation from scratch seemed the easiest option. After reinstalling with dhcpcd included, it was necessary to:

sudo systemctl enable dhcpcd
sudo systemctl start dhcpcd
sudo dhcpcd eno1 # check `ip a` for interface name

After this, the ethernet connection immediately became available.

Installing XFCE

XFCE is a lightweight desktop environment for Unix-y machines. Installing is trivial:

sudo pacman -S xfce4 xfce4-goodies xorg

Making XFCE start automatically on boot required two config files (source).

Firstly $HOME/.xinitrc:

#!/bin/bash
exec startxfce4

and at the end of .zshrc (or .bashrc):

if [ $(tty) == "/dev/tty1" ]; then
  startx
fi

Note: there’s probably a better way to do this using systemd but I haven’t figured it out yet.

Getting Bluetooth to work

Firstly it is necessary to install the base Bluetooth layer.

sudo pacman -S bluez bluez-utils
sudo systemctl enable bluetooth.service
sudo systemctl start bluetooth.service

Then run bluetoothctl and use the following approximate sequence of steps:

power on
agent on
scan on
pair <device ID>

Bluetooth never worked well for me on Ubuntu and despite a good start I’ve experienced a few issues on Arch too.

Firstly, at some stage my Logitech Bluetooth mouse stopped actually moving the pointer or appearing as an input device, despite seemingly pairing successfully over Bluetooth. Following the instructions here solved the issue - hopefully it won’t repeat too often.

Secondly, some systemd tweaks were required to get Bluetooth and hibernation to work together nicely - see below.

Install a web browser

🤷

# and/or firefox-developer-edition
sudo pacman -S firefox

Getting hibernate to work

Getting hibernation to work properly on Linux has been a source of much fun in the past and this time around was no exception.

At first I experienced consistent instantaneous wakeup from hibernation. After checking journalctl this turned out to be caused by a PCI USB extension board that I’d damaged slightly while removing the internal packaging from the computer post-transit. After physically detaching this useless board completely from the machine, the instantaneous wakeup was fixed.

However, the box still failed to resume from hibernation, sticking on a black screen shortly after the disk encryption password phase. This required a bit more tracking down, but further careful examination of journalctl revealed that the open source Nouveau drivers for NVIDIA graphics cards were spewing some suspicious logs during the hibernate phase. For example:

Jun 29 08:16:24 rob-arch kernel: ------------[ cut here ]------------
Jun 29 08:16:24 rob-arch kernel: nouveau 0000:01:00.0: timeout
Jun 29 08:16:24 rob-arch kernel: WARNING: CPU: 1 PID: 140 at drivers/gpu/drm/nouveau/nvkm/engine/disp/cursgv100.c:31 gv100_disp_curs_idle.isra.0+0xd7/0xf0 [nouveau]
Jun 29 08:16:24 rob-arch kernel: Modules linked in: mousedev uhid rfcomm cfg80211 cmac algif_hash intel_rapl_msr algif_skcipher 8021q snd_sof_pci af_alg garp snd_sof_intel_byt mrp snd_sof_intel_ipc intel_rapl_common stp bnep llc snd_sof_intel_hda_common snd_soc_hdac_hda sn>
Jun 29 08:16:24 rob-arch kernel:  rfkill ecc cec apple_mfi_fastcharge snd_timer rc_core snd mei_me syscopyarea mei sysfillrect soundcore sysimgblt fb_sys_fops intel_pch_thermal ie31200_edac wmi evdev mac_hid drm crypto_user agpgart ip_tables x_tables hid_apple hid_generic >
<snip>
Jun 29 08:16:24 rob-arch kernel: Call Trace:
Jun 29 08:16:24 rob-arch kernel:  nvkm_object_init+0x3e/0x100 [nouveau]
Jun 29 08:16:24 rob-arch kernel:  nvkm_object_init+0x6f/0x100 [nouveau]
Jun 29 08:16:24 rob-arch kernel:  nvkm_object_init+0x6f/0x100 [nouveau]
Jun 29 08:16:24 rob-arch kernel:  nvkm_object_init+0x6f/0x100 [nouveau]
Jun 29 08:16:24 rob-arch kernel:  nvkm_object_init+0x6f/0x100 [nouveau]
Jun 29 08:16:24 rob-arch kernel:  nouveau_do_resume+0x29/0xd0 [nouveau]
Jun 29 08:16:24 rob-arch kernel:  nouveau_pmops_resume+0x60/0x90 [nouveau]
Jun 29 08:16:24 rob-arch kernel:  ? pci_legacy_resume+0x80/0x80

As with all software I would much prefer to choose the FOSS option for NVIDIA drivers if possible, but the convenience of working hibernation is too much of a pull so I did quick sudo pacman -S nvidia (see here for more details) and rebooted. This time, the box both hibernated and resumed successfully 🎉

Finally, it was necessary to install two simple systemd services to cycle the bluetooth “power” before and after hibernation. (These may also be required with other targets such as suspend.target and suspend-then-hibernate.target if they are used.)

In /etc/systemd/system/bluetooth-power-on.service:

[Unit]
Description=Turn bluetooth power on
After=hibernate.target

[Service]
Type=oneshot
ExecStartPre=/bin/sleep 5s
ExecStart=/usr/bin/bluetoothctl power on

[Install]
WantedBy=hibernate.target

And /etc/systemd/system/bluetooth-power-off.service:

[Unit]
Description=Turn bluetooth power off
Before=hibernate.target

[Service]
Type=oneshot
ExecStart=/usr/bin/bluetoothctl power off

[Install]
WantedBy=hibernate.target

Both can be activated with systemctl enable bluetooth-power-X. After doing this, Bluetooth should automatically power back on after resuming from hibernation.

Slow mirrors

It might be random but the Pacman mirrors chosen by my system were very slow (averaging 250k/s download speed for all packages).

As per the Arch Wiki, this can be fixed by installing the pacman-contrib package and then using the contained rankmirrors script:

# change country=ES to something appropriate:
curl -s "https://www.archlinux.org/mirrorlist/?country=ES&protocol=https&use_mirror_status=on" | sed -e 's/^#Server/Server/' -e '/^#/d' | rankmirrors -n 5 -

The output of this command can be used to replace /etc/pacman.d/mirrorlist (backing it up first naturally). After doing this, package download speeds average several MB/s.

Pacman

I’m still getting familiar with it but it appears lightweight and easy to use. Best of all, there are no PPAs to install and manage 🚀.

Other bits

A handful of other softwares that I’ve installed so far: