Installing Artix Linux with OpenRC, BtrFS, and Secure Boot


Warning

This guide is not too specific and might not even work if followed step-by-step. It is only supposed to give you an idea of what to do.

Edit#0 | July 23 2024

Since I first published this article I have used it several times to intall Artix or other Arch-based distros while only referring to it as a mere handbook of sorts. I advise you do the same.

Preparing for the install

Get an Artix bootable image

The download page:

https://artixlinux.org/download.php

The init system (openrc, runit, dinit, or s6) in the filename is the init system the live image uses, not the one you are necessarily going to install.

Flash the image

You can use any of the following and more:

Boot and log in as root

Logging in as root will save you some time:

username: root
password: artix

Partition the disks

To partition the disks I’ll use gdisk, ‘cause it’s simple, and I like it.

Formatting the disks

lsblk # get the identifiers of the partitions (e.g. /dev/sda1)

EFI System Partition (ESP) — FAT32

# -n  label
mkfs.vfat -n "ESP" /dev/sda1

Storage Partition — BtrFS

# -L  label
mkfs.btrfs -L "Artix" /dev/sda2

Swap (optional)

# -L  label
mkswap -L "Swap" /dev/sda3

Configuring BtrFS

BtrFS allows for things like blazing-fast small system snapshots (in case pacman breaks your system), self-healing of data, and also filesystem-level compression. It’s more simple than OpenZFS, doesn’t have any license conflicts, and works well.

That said, it also has some downsides:

If you still want to use nodatacow on a subvolume, see this article for a workaround: https://blog.jim.nz/2015/12/04/btrfs-subvolume-with-nocow.html Some people have reported that having VMs which don’t use CoW make them faster

Create the filesystem

mkfs.btrfs -L "Artix" /dev/sda

/dev/sda is the drive we are writing to, do not confuse this with the flash disk! Use lsblk or blkid to get the identifier of the drive.

From now on, the disks will be identified as such:

  1. /dev/sda1 — ESP
  2. /dev/sda2 — BtrFS
  3. /dev/sda3 — linux swap

Mount the “Artix” BtrFS partition

mount /dev/sda2 /mnt

Create the subvolumes

@ represents root, it is merely a popular BtrFS naming convention, you can completely omit it, but its purpose is to make it clear that the subvolume is actually a subvolume and not something else

Subvolumes allow us to more elegantly control the mount options of certain directories, such as compression, nosuid, or noexec.

btrfs sub cr /mnt/@ #root
btrfs sub cr /mnt/@home
btrfs sub cr /mnt/@var_cache
btrfs sub cr /mnt/@var_log
btrfs sub cr /mnt/@var_tmp
brtfs sub cr /mnt/@tmp
btrfs sub cr /mnt/@snapshots

btrfs sub cr is the same as btrfs subvolume create

Mount the subvolumes

umount /mnt
mount -o rw,noatime,compress=zstd:3,ssd,discard=async,space_cache=v2,commit=60,subvol=@ /dev/sda2 /mnt
mkdir -p /mnt/{boot,home,var/log,var/cache,var/tmp,tmp,.snapshots}
mount -o rw,nosuid,nodev,noexec,relatime /dev/sda1 /mnt/boot
mount -o rw,nodev,noatime,compress=lzo,ssd,discard=async,space_cache=v2,commit=120,subvol=@home /dev/sda2 /mnt/home
mount -o rw,nosuid,nodev,noexec,noatime,compress=zstd:3,ssd,discard=async,space_cache=v2,commit=120,subvol=@var_cache /dev/sda2 /mnt/var/cache
mount -o rw,nosuid,nodev,noexec,noatime,compress=zstd:4,ssd,discard=async,space_cache=v2,commit=120,subvol=@var_log /dev/sda2 /mnt/var/log
mount -o rw,nosuid,nodev,noexec,noatime,compress=zstd:3,ssd,discard=async,space_cache=v2,commit=120,subvol=@var_tmp /dev/sda2 /mnt/var/tmp
mount -o rw,nosuid,nodev,noatime,compress=zstd:10,ssd,discard=async,space_cache=v2,subvol=@snapshots /dev/sda2 /mnt/.snapshots

LWN article on atime, relatime, and noatime in BtrFS: Atime and btrfs: a bad combination?

Install Artix

basestrap /mnt base base-devel openrc elogind-openrc linux-zen linux-zen-headers linux-firmware amd-ucode fish efibootmgr git neovim btrfs-progs

Generate the fstab

fstabgen -L /mnt >> /mnt/etc/fstab

Make sure to edit this file and double check everything

Modify the fstab

Mount /tmp as tmpfs, see https://www.kernel.org/doc/html/latest/filesystems/tmpfs.html

echo "tmpfs /tmp tmpfs defaults,noatime,mode=1777 0 0" >> /etc/fstab

Chroot

artix-chroot /mnt

Set up locale

Timezone

ln -sf /usr/share/zoneinfo/Region/City /etc/localtime
hwclock --systohc

Edit /etc/locale.gen

nvim /etc/locale.gen

Generate locale

locale-gen

Create a user

passwd # change the root password
useradd -m -s $(which fish) -G wheel tux
passwd tux

Configure the network

Let’s install connman.

pacman -S connman-openrc
rc-update add connmand

Connman is good for basic stuff, but I came across a bug, where if you have symbols in your Wi-Fi password it fails to read the password and connect. For more advanced stuff NetworkManager is still the way to go, although I don’t like (which is why I use iwctl with https://wiki.gentoo.org/wiki/Netifrc)

Configure BtrFS snapshots

First, we need to install yay:

git clone https://aur.archlinux.org/yay.git
su -l tux
cd /home/tux/yay
makepkg -si

Install cronie to schedule the snapshots:

pacman -S cronie

More info: Configuring snapper without systemd

Install snap-pac-git, which create a snapshot pre- and post-transaction.

yay snap-pac-git

We need to temporarily delete the /.snapshots directory, so we can recreate it using snapper:

We created the /.snapshots directory in order to generate the fstab

umount /.snapshots
rmdir /.snapshots
snapper -c root create-config / # configure snapper and create /.snapshots
mount -a # remount /.snapshots

I should probably change snapper’s default configuration, but I don’t think I’ll ever be bothered, it’s not like snapshots occupy a lot of space.

Install Hyprland (WM)

yay hyprland-git

Linux EFISTUB

Generate the SB keys by following Rod Smith’s article on controlling secure boot.

For more information on SB: https://www.rodsbooks.com/efi-bootloaders/index.html

Add custom pacman hooks (outdated)

I created some pacman hooks to automate the process of signing and moving the installed kernel.

cd ## should now be in /root
git clone https://github.com/turtureanu/pacman-hooks.git
cd pacman-hooks
cp *.hook /etc/pacman.d/hooks/
Edit#1 | July 23 2024

I now dual boot 2 Linux distros using a smart rEFInd & fstab setup, so my current pacman hooks are a bit different, have a look at them:

Hooks:

100-remove-linux-before-upgrade.hook:

[Trigger]
Operation = Install
Operation = Upgrade
Type = Package

Target = linux
Target = linux-lts
Target = linux-hardened
Target = linux-zen
Target = linux-xanmod
Target = linux-xanmod-calcule
Target = linux-xanmod-git
Target = linux-xanmod-rt
Target = linux-xanmod-anbox

[Action]
Description = Removing linux kernels before (re)install/upgrade, allows for 940-relocate-linux.hook to work flawlessly (no multiple kernels)
When = PreTransaction
Exec = /bin/sh -c 'rm /boot/vmlinuz* && rm /boot/initramfs*'

940-relocate-kernel.hook:

[Trigger]
Operation = Install
Operation = Upgrade
Type = Package

Target = linux
Target = linux-lts
Target = linux-hardened
Target = linux-zen
Target = linux-xanmod
Target = linux-xanmod-calcule
Target = linux-xanmod-git
Target = linux-xanmod-rt
Target = linux-xanmod-anbox

[Action]
Description = Rename kernel to know its name for when it gets signed
When = PostTransaction
Exec = /bin/sh -c 'mv /boot/vmlinuz-linux-* /boot/vmlinuz-linux && mv $(ls /boot/initramfs-linux*  | grep -v fallback) /boot/initramfs-linux.img'

940-sign_kernel_for_secure_boot.hook:

[Trigger]
Operation = Install
Operation = Upgrade
Type = Package

Target = linux
Target = linux-lts
Target = linux-hardened
Target = linux-zen
Target = linux-xanmod
Target = linux-xanmod-calcule
Target = linux-xanmod-git
Target = linux-xanmod-rt
Target = linux-xanmod-anbox

[Action]
Description = Sign the linux kernel for Secure Boot
When = PostTransaction
Exec = /bin/sh -c 'sbsign --key /mnt/boot/EFI_KEYS/DB.key --cert /mnt/boot/EFI_KEYS/DB.crt --output /boot/vmlinuz-linux /boot/vmlinuz-linux'

mkinitcpio configuration

Edit /etc/mkinitcpio.conf and modify the following lines:

MODULES=(btrfs)
.
.
.
COMPRESSION="lz4"
COMPRESSION_OPTIONS=(-9)

… and mkinitcpio -p linux-zen or whatever your Linux kernel is

Create a UEFI entry

efibootmgr -c -d /dev/sda -p 1 --label "Artix" -l "\EFI\ARTIX\VMLINUZ.EFI" --verbose

Enroll keys to UEFI

In summary:

  1. Disable SB
  2. Enroll DB.esl
  3. Enroll KEK.esl
  4. Enroll PK.auth
  5. Enable SB

You may also use a tool such as KeyTool.efi, if your UEFI doesn’t support manually loading keys from the interface.

After that, we’re basically done, I guess.