Rufus (for Windows users)
dd
command (for Linux users)Logging in as root
will save you some time:
username: root
password: artix
To partition the disks I’ll use gdisk
, ‘cause it’s simple, and I like it.
lsblk # get the identifiers of the partitions (e.g. /dev/sda1)
# -n label
mkfs.vfat -n "ESP" /dev/sda1
# -L label
mkfs.btrfs -L "Artix" /dev/sda2
# -L label
mkswap -L "Swap" /dev/sda3
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:
nodatacow
and datacow
mounting options (for using copy-on-write) cannot be separately used for each subvolumeIf 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
mkfs.btrfs -L "Artix" /dev/sda
/dev/sda
is the drive we are writing to, do not confuse this with the flash disk! Uselsblk
orblkid
to get the identifier of the drive.
From now on, the disks will be identified as such:
/dev/sda1
— ESP/dev/sda2
— BtrFS/dev/sda3
— linux swapmount /dev/sda2 /mnt
@
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 asbtrfs subvolume create
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?
basestrap /mnt base base-devel openrc elogind-openrc linux-zen linux-zen-headers linux-firmware amd-ucode fish efibootmgr git neovim btrfs-progs
fstabgen -L /mnt >> /mnt/etc/fstab
Make sure to edit this file and double check everything
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
artix-chroot /mnt
ln -sf /usr/share/zoneinfo/Region/City /etc/localtime
hwclock --systohc
nvim /etc/locale.gen
locale-gen
passwd # change the root password
useradd -m -s $(which fish) -G wheel tux
passwd tux
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)
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.
yay hyprland-git
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
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/
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'
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
efibootmgr -c -d /dev/sda -p 1 --label "Artix" -l "\EFI\ARTIX\VMLINUZ.EFI" --verbose
In summary:
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.