This very much is a rehash of Walian’s Arch install guide.. It’s a fantastic guide, please give it a read. Full credit goes to him.

Create a bootable USB

There are plenty of ways to do this, the Arch Wiki mentions a few ways. Here is a fairly basic way to do it.

  1. Download an Arch image
  2. Create a bootable usb (keeping in mind the path to the Arch Image and the USB): dd bs=4M if=path/to/archlinux-version-x86_64.iso of=/dev/disk/by-id/usb-My_flash_drive conv=fsync oflag=direct status=progress
  3. If your BIOS has Secure Boot enabled, disable it. (By default the DIY editions of the Framework laptops have it enabled)
  4. Boot into the USB

Connect to the Internet

If you have an ethernet connection you should be fine. If you’re on wifi the Arch live disk comes with iwd

Run iwctl to get into the interactive prompt then:

  1. Find your device name: device list
  2. Make sure you can find your network (replace device_name with your device from step 1):
station device_name scan
station device_name get-networks
  1. Connect (replacing both device_name and network_password): station device_name connect network_password
  2. Exit out of interactive prompt: exit

Preparing the disks

Find our drive name using: lsblk In my case it’s nvme0n1, but if it’s a SATA drive it may be something like sda.

Like in Walian’s guide we’ll create a 512MB FAT32 for boot, and the rest on a btrfs partition for root.

We’ll use sgdisk to partition it.

EFI and LINUXROOT can be whatever labels you like.

sgdisk -Z /dev/nvme0n1
sgdisk -n1:0:+512M -t1:ef00 -c1:EFI -N2 -t2:8304 -c2:LINUXROOT /dev/nvme0n1
partprobe -s /dev/nvme0n1

Running lsblk again should show our newly created partitions.

We only want to encrypt our root partition: nvme0n1p2 in my case.

To do that:

cryptsetup luksFormat --type luks2 /dev/nvme0n1p2
cryptsetup luksOpen /dev/nvme0n1p2 linuxroot

To create the filesystems:

mkfs.vfat -F32 -n EFI /dev/nvme0n1p1
mkfs.btrfs -f -L linuxroot /dev/mapper/linuxroot

To close off the preparing disks section, lets mount the partitions and create the btrfs subvolumes.

mount /dev/mapper/linuxroot /mnt
mkdir /mnt/efi
mount /dev/nvme0n1p1 /mnt/efi
btrfs subvolume create /mnt/home
btrfs subvolume create /mnt/srv
btrfs subvolume create /mnt/var
btrfs subvolume create /mnt/var/log
btrfs subvolume create /mnt/var/cache
btrfs subvolume create /mnt/var/tmp

Base install

Update pacman mirrors (replacing country with the most relevant country code for you):

reflector --country AU --protocol https --age 24 --sort rate --save /etc/pacman.d/mirrorlist

Pacstrap a base install. Taking note of amd-ucode, which you may want to swap out for intel-ucode if you’re using an Intel processor.

pacstrap -K /mnt base base-devel linux linux-lts linux-firmware amd-ucode neovim cryptsetup btrfs-progs dosfstools util-linux git unzip sbctl networkmanager sudo plasma-meta kitty

Note: If you get a corrupt package error run pacman -Sy archlinux-keyring beforehand.

Update the locale settings. Edit /mnt/etc/locale.gen with your text editor of choice (vim). Uncomment out the relevant entries.

In my case

  • ja_JP.UTF-8 UTF-8
  • en_AU.UTF-8 UTF-8
  • en_US.UTF-8 UTF-8

Run systemd-firstboot --root /mnt --prompt for further setup.

For keymap I do jp106 because I have a JIS layout keyboard, but for the majority of people us will be appropriate.

Timezone and hostname are up to you. (Melbourne is timezone: 359)

Run arch-chroot /mnt locale-gen

Create User

Create the local user, and then assign a password to them.

arch-chroot /mnt useradd -G wheel -m sebastiaan
arch-chroot /mnt passwd sebastiaan

Next we want to edit the sudoers file: /mnt/etc/sudoers

Ensure this line is uncommented: %wheel ALL=(ALL:ALL) ALL. Additionally if you like asterisks as you type your password, add this line: Defaults pwfeedback.

Unified Kernel Images

Create our kernel parameters. Because we’re using Discoverable Partitions it doesn’t need to contain anything.

echo "rw" >/mnt/etc/cmdline.d/rw.conf

Then let’s create the EFI directory structure.

mkdir -p /mnt/efi/EFI/Linux

Now lets change the HOOKS in /mnt/etc/mkinitcpio.conf to look like the following:

HOOKS=(base systemd autodetect microcode modconf kms keyboard sd-vconsole sd-encrypt block filesystems fsck)

Now lets update /mnt/etc/mkinitcpio.d/linux.preset and linux-lts.preset.

# mkinitcpio preset file for the 'linux' package

ALL_config="/etc/mkinitcpio.conf"
ALL_kver="/boot/vmlinuz-linux"

PRESETS=('default' 'fallback')

#default_config="/etc/mkinitcpio.conf"
#default_image="/boot/initramfs-linux.img"
default_uki="/efi/EFI/Linux/arch-linux.efi"
default_options="--splash /usr/share/systemd/bootctl/splash-arch.bmp"

#fallback_config="/etc/mkinitcpio.conf"
#fallback_image="/boot/initramfs-linux-fallback.img"
fallback_uki="/efi/EFI/Linux/arch-linux-fallback.efi"
fallback_options="-S autodetect"

And now to generate our UKIs:

arch-chroot /mnt mkinitcpio -P

If we run ls -lR /mnt/efi we can seem our UKIs.

Enable services and boot loader and reboot into BIOS

systemctl --root /mnt enable systemd-resolved systemd-timesyncd NetworkManager
systemctl --root /mnt mask systemd-networkd
arch-chroot /mnt bootctl install --esp-path=/efi
sync
systemctl reboot --firmware-setup

You can now remove your bootable USB.

In the BIOS under Secure Boot there should be an option to enter “Setup Mode”. On Framework laptops you do this by enabling “Erase all Secure Boot Settings”.

Save these settings and continue booting.

Log in when prompted.

Secure Boot with TPM2 Unlocking

Run sbctl status. Ensure Setup Mode is Enabled, if it isn’t boot back into the BIOS and try again.

Create and enroll out personal Secure Boot Keys. The -m flag includes the Microsoft vendor key. Great for not bricking your laptop.

sudo sbctl create-keys
sudo sbctl enroll-keys -m

Now let’s sign our .efi files, the -s flag is important because with it sbctl will automatically resign them if we update the kernel or bootloader via pacman.

sudo sbctl sign -s /usr/lib/systemd/boot/efi/systemd-bootx64.efi -o /usr/lib/systemd/boot/efi/systemd-bootx64.efi.signed
sudo sbctl sign -s /efi/EFI/BOOT/BOOTX64.EFI
sudo sbctl sign -s /efi/EFI/Linux/arch-linux.efi
sudo sbctl sign -s /efi/EFI/Linux/arch-linux-fallback.efi

Fwupd support

You may want to sign /usr/lib/fwupd/efi/fwupdx64.efi as well for fwupd support. (Which let’s you update firmware.)

sudo sbctl sign -s /usr/lib/fwupd/efi/fwupdx64.efi -o /usr/lib/fwupd/efi/fwupdx64.efi.signed

We can automatically sign this file on updates by creating a hook.

/etc/pacman.d/hooks/96-sign-fwupd-secureboot.hook

[Trigger]
Operation = Install
Operation = Upgrade
Type = Path
Target = usr/lib/fwupd/efi/fwupdx64.efi

[Action]
When = PostTransaction
Exec = /usr/bin/sbctl sign -s /usr/lib/fwupd/efi/fwupdx64.efi -o /usr/lib/fwupd/efi/fwupdx64.efi.signed
Depends = sbctl

Then set DisableShimForSecureBoot in /etc/fwupd/fwupd.conf

/etc/fwupd/fwupd.conf

[uefi_capsule]
DisableShimForSecureBoot=true

Reinstalling the kernel is a good way to test this: sudo pacman -S linux.

We’re almost done. Reboot into the BIOS again: systemctl reboot --firmware-setup, this time make sure Secure Boot is enabled.

Log into your account again.

Now it’s time to configure automatic unlocking of the root filesystem. First let’s create a recovery key.

sudo systemd-cryptenroll /dev/gpt-auto-root-luks --recovery-key

Make note of this key.

Now lets add the LUKS key to TPM.

sudo systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+7  /dev/gpt-auto-root-luks

Note to delete keys you can do the following List keys: sudo systemd-cryptenroll /dev/gpt-auto-root-luks Wipe keys: sudo systemd-cryptenroll /dev/gpt-auto-root-luks --wipe-slot=2

Reboot, and hopefully you don’t need to enter your drive encryption password anymore.

I tripped up secure boot while upgrading some case fans, and trying to reenroll the keys resulted in Failed to unseal secret using TPM2: State not recoverable.

FHere’s the fix echo 5 | sudo tee /sys/class/tpm/tpm0/ppi/request and then reboot and restart.