Blasting from the past to the future
Alternatively: A fancy title for some notes on how to install a barebones Arch Linux.
While I loathe this approach in a professional context, when it comes to my personal computing habits I'm a big fan of "I've always done it like this and it kind of works, so why bother fixing it?".
Which is why the Arch Linux on my laptop is installed in BIOS-mode, runs X, GRUB, i3 and a whole host of other software that had had more modern replacements available for at least a couple of years by this point.
I decided that significantly shuffling around things on my desk (because new year, new me) would be a great excuse opportunity to do the same with my laptop. Plus: I needed a reason an excuse to keep stalling my work on projects anyway.
Now, if you have somewhat standard hardware, installing Linux isn't a daunting task anymore. Even if you decided to use a distribution that doesn't come bundled with an installer, (mostly) gone are the days where you would have to pray that your wireless chipset was not only by the "right" manufacturer, but also that you didn't end up with a chip from a production run that wasn't playing nice with the driver for no discernible reason.
If you're thinking to yourself "Hmm .. that sounds oddly specific, are you okay?", then I commend you on your intuition and would like to let you know that while I am okay again, whoever is responsible for making design decisions at Broadcom deserves everything they got coming for them down in the deepest recesses of hell.
However, even if the installation process is mostly straightforward these days there's at least one step or one command that I tend to forget about when I have to install something from scratch every few months. Which is why I decided to take notes this time, and figured that I might share them with the wider world while I'm at it.
If you follow the paragraphs below you'll end up with a minimal working installation of Arch Linux, with a fully encrypted disk. The only caveat is that you'll start out with no swap. I usually add a swapfile later on, but other people handle this differently, which is why I left it out. Keep that in mind, especially when you are installing on a laptop and want to suspend the device.
Before starting it makes sense to check if you have actually booted in UEFI mode:
ls /sys/firmware/efi/efivars
If this directory exists then you indeed are in UEFI mode. Proceed by connecting to the Internet (for wireless networks, use iwctl
) and sync the system clock just to be sure (timedatectl set-ntp true
)
The next step is partitioning. For the sake of consistency I assume that your drive is called like mine, /dev/nvme0n1
. Create a new GPT partition table and necessary partitions (an EFI System Partition, ESP, and an encrypted partition:
parted /dev/nvme0n1 mklabel gpt
parted /dev/nvme0n1 -- mkpart ESP fat32 1MiB 513MiB
parted /dev/nvme0n1 set 1 esp on
parted /dev/nvme0n1 -- mkpart cryptroot 513MiB 100%
Format the ESP:
mkfs.fat -F 32 /dev/nvme0n1p1
Initialize LUKS on the cryptroot partition, unlock the encrypted container you just created:
cryptsetup luksFormat /dev/nvme0n1p2
cryptsetup open /dev/nvme0n1p2 cryptroot
This creates a virtual device named cryptroot
under /dev/mapper/cryptroot
.
Most people tend to use LVM on LUKS, a choice I never really understood for devices like laptops. I've been running "plain" ext4 over LUKS ever since I stopped using the automated partitioning done by the Debian installer. Which means I simply create a file system for the virtual device and move on:
mkfs.ext4 -m1 /dev/mapper/cryptroot
I'm aware that the setup doesn't leave any room for a swap-partition, which is required for things like suspension. I solve this issue with a swapfile, which I'll talk about later. The final disk-related step before actually installing things is mounting it as well as the ESP:
mount /dev/mapper/cryptroot /mnt
mkdir /mnt/boot
mount /dev/nvme0n1p1 /mnt/boot
Now it's time to install the base system:
pacstrap /mnt base base-devel linux linux-firmware iwd neovim
The reason why I install neovim
is simply habit, the reason for iwd
is that I have had to boot the installation image for Arch Linux way too often in order to chroot
into my existing installation because I had forgotten that I didn't have an Ethernet cable at hand to manually install it afterwards.
When that is done, create an /etc/fstab
for your freshly installed system:
genfstab -U /mnt >> /mnt/etc/fstab
I always check the created file for correctness. The chance of something going wrong is tiny, but once again .. I've been bitten before. Time to jump into the new installation:
arch-chroot /mnt
Set the timezime your system is in, adjust the hardware clock, ensure your locales are in order:
ln -sf /usr/share/zoneinfo/<your region>/<your city> /etc/localtime
hwclock --systohc
echo "en_US.UTF-8" >> /etc/locale.gen
locale-gen
echo "LANG=en_US.UTF-8" > /etc/locale.conf
Set the hostname and create matchin entries in /etc/hosts
:
echo "myhostname"> /etc/hostname
echo "127.0.1.1 myhostname.localdomain myhostname" >> /etc/hosts
Now for another important step ("important" as in "it's still possible, but much more annoying to fix later on than other things"), configuring mkinitcpio
for encryption.
You do that by editing /etc/mkinitcpio.conf
, ensuring that the line for HOOKS
is configured correctly. For my system it looks like this:
HOOKS=(base udev autodetect modconf block keyboard keymap encrypt filesystems fsck)
If you do use LVM, ensure that lvm
is included and comes before filesystems
. Re-generate the initramfs, creating updated initrd
images in /boot
:
mkinitcpio -P
The move from BIOS to UEFI aside, the following steps were the first major changes in comparison to my older setup. I've always used GRUB, except for a short time in my earlier youth where I thought that using LILO might be a sane choice.
It's a sane choice if you need flexibility or support for more complex boot configurations. In my case however, all I needed was the ability to boot a single operating system the most simple way possible - which is where systemd-boot
comes in.
I began by installing it:
bootctl --path=/boot install
Then I created a configuration file for the bootloader in /boot/loader/loader.conf
that looked like this:
default arch.conf
timeout 4
console-mode max
editor no
The configuration file the loader is supposed to look for is located under /boot/loader/entries/arch.conf
and contains the following lines:
title Arch Linux
linux /vmlinuz-linux
initrd /initramfs-linux.img
options cryptdevice=UUID=<UUID_of_cryptroot_partition>:cryptroot root=/dev/mapper/cryptroot rw
Because I always forget the command to get the UUID of a partition: It's blkid
.
And that's it. There are no further steps required to configure the bootloader. It truly bothers me to give anything by Lennart Poettering credit, but that definitely was a breeze compared to fidgeting around with GRUB_CMDLINE_LINUX
and praying that grub-mkconfig
didn't throw a useless error message.
Last but not least I useradd
-ed myself and passwd
'd a password for root
before exiting the chroot and rebooting the system. Provided you didn't fuck up and forgot anything important you should be able to boot into your new system.
Since pretty much every single configuration choice after the base installation is a highly personal affair I decided to skip explaining my process for replacing i3 with Sway, and other things. If you're interested in how I configure my software, feel free to reach out to me or take a look at my dotfiles on GitHub.
With the new setup up and running I asked myself if it was worth the effort, and if it will be worth the effort of unlearning old habits in order to accommodate the new requirements and quirks that come with new software. Even if said software is intended to be a verbatim replacement for the old one.
On one hand it's not. The old setup was working and doing its job. Yes, there were some issues and problems that I had to come up with workarounds for. But I had done this work years ago and dealing with those things has become second nature to me. It wasn't broke, so there was no real need to fix things.
Except that it was kind of broke, a fact that was hidden by a relatively fine-tuned configuration, careful workarounds and muscle memory. With the new setup it's not like there aren't any issue (one prominent example is that Sway doesn't allow for window swallowing like i3 does, and all the third-party solutions rely on the Scratchpad, which interferes with my habit of taking notes), but it feels more "modern", in the positive sense of the word, than before.
Xorg is old, something that's noticeable not just under the hood, but by the way it's configured. Wayland is much more simple in that regard, more straightforward. It feels like at least some of the lessons learned throughout the last decades of computing have been noted and implemented.
The same applies to pipewire
, which I now use for everything audio. It's always fun shitting on PulseAudio, but that's because there's plenty to make fun of. It's a behemoth that's great when it works, but horrible when it doesn't. Debugging audio problems between PulseAudio and a pair of older Bluetooth headphones of mine has cost me a lot of nerves. Here, once more, it feels like the developers have taken hard-learned lessons and decided to make our lives easier.
All in all I'm confident that the afternoon spent installing and exploring was time worth spent. I will not be answering questions that inquire if my confidence is authentic or a measure I've taken to justify the expense in time and delay in actual work.