0daysto.live

Arch Linux on Framework Laptop Setup

Updated:

This blog post covers the install process I used to set up Arch on my 11th Gen Framework laptop. This guide is opinionated and you should feel free to adjust things if you prefer differently - I will do my best to point out sections where alternative options exist. This sets the machine up with the disk encrypted with LUKS (avoids the problem of double password entry on boot that other guides had), resume from hibernate working and a barebones i3wm. My next blog post will be about my environment configuration and all the other applications I installed.

Other guides I used as reference:

Why Arch?

Arch is very popular, has a very detailed wiki and a very minimal install allowing you to configure everything to your own preferences. I also enjoy getting the latest release of packages and the kernel without having to wait too long.

Pre-Installation

The Hardware

I ordered an 11th Gen Framework laptop (DIY edition) for €928. I didn’t get the 12th Gen because it seems like that has more issues than the 11th Gen at the time I ordered. I ordered without the SSD and RAM as I could get those cheaper elsewhere.

The SSD I got is a 1TB NVMe Samsung 980 which cost €92.

The RAM I got is a 32GB Crucial RAM Stick which cost €121.

Update the BIOS

Before doing anything it’s a good idea to update the BIOS. To access the BIOS press F2 during boot. The version is shown on the BIOS screen next to InsydeH2O Version eg GFW30.03.07 is version 3.07

On linux (if you’ve already installed) you can use dmidecode to check the BIOS version:

sudo pacman -S dmidecode
sudo dmidecode -s bios-version

For the 11th gen Framework I downloaded the BIOS update zip file from here

Extract that zip file onto a FAT32 formatted USB stick.

Boot from USB and the BIOS installer will run.

After installation remove the USB.

Reference: https://community.frame.work/t/bios-guide/4178

Prepare Bootable USB

Download the Arch ISO and install it on a USB stick, I used Rufus to do it.

BIOS Settings

To boot from USB we will need to disable Secureboot in the BIOS.

Get to the BIOS menu as mentioned earlier by pressing F2 while the laptop is turning on. Enter Secure Boot under the Security tab and set Enforce Secure Boot to Disabled.

While we’re here we can change around some other BIOS settings. On my machine I choose to disable the fingerprint reader and the camera which can be done at I/O Interface on the Security tab. I would also choose to disable Bluetooth here if I could but currently can’t do that in the BIOS as Wifi and Bluetooth are the same device. There is a known issue with using the touchpad to wake from sleep that can be avoided by disabling PS2 Mouse emulation in the Advanced tab.

When you are done configuring the BIOS press F10 to save and exit. Boot again with the USB inserted and it should boot into Arch.

Connect Bootable USB to Internet

Run the iwctl command to open the wifi client.

device list                       # list devices
# wlan0 is the name of my wifi device
station wlan0 scan                # wifi scan
station wlan0 get-networks        # get list of networks
station wlan0 connect YOURNETWORK # connect to network

When the internet is connected you can use exit to quit the iwctl program.

Partitioning the SSD

Run gdisk /dev/nvme0n1 to start.

The first partition is the boot partition. I chose to make my boot partition 100mb as that is enough space for a minimal enough bootloader. However I later regretted this because I ran into trouble due to not having enough space for something I wanted to do.1

You can avoid a similar fate by allowing more space in the boot partition, 256mb would be enough I think.

In gdisk do the following:

Command: n
Partition Number: 1
First sector: Enter Key
Last sector: +256m
Hex code or GUID: 8300

Next is the EFI partition. The general recommendation for this seems to be 300mb.

Command: n
Partition Number: 2
First sector: Enter Key
Last sector: +300m
Hex code or GUID: ef00

Finally the root partition can take the rest of the disk:

n enter enter enter enter

Some guides will say to leave some SSD space unallocated to prolong the SSD lifetime but this is an outdated myth and you can safely ignore it.

Finally now that we’ve set up the layout we want we can write the changes to disk:

p # prints the partition table so you can make sure everything is correct
w # write the changes to the disk
y # confirm you want to write the changes

Setting Up The Encrypted Drive

GRUB only barely supports LUKS2 at the moment so we will stick to using LUKS1 for now.

UPDATE 03/05/2023: I have since updated my system to LUKS2 and it works fine so I have added the command to use the newer header and argon2id hashing if you wish to try it.

First create the encrypted container.

LUKS1 with PBKDF:

cryptsetup luksFormat --type luks1 --use-random -S 1 -s 512 -h sha512 -i 5000 /dev/nvme0n1p3

LUKS2 with argon2id

cryptsetup luksFormat --type luks2 --use-random -S 1 -s 512 -h sha512 -i 5000 /dev/nvme0n1p3

Open the LUKS volume:

cryptsetup open /dev/nvme0n1p3 cryptlvm

Next create the partitions in the container. Here I’m only making swap and root partitions but you can have /home and other directories on their own partition if you wish.

It’s recommended to make the swap partition 1.5x the amount of RAM if you want to use hibernation. I have 32GB ram so I made my swap 48GB.

pvcreate /dev/mapper/cryptlvm
vgcreate vg /dev/mapper/cryptlvm
lvcreate -L 48G vg -n swap
lvcreate -l 100%FREE vg -n root

Next we format our partitions. I’m using ext4 as my main filesystem but you may be interested in using another filesystem like XFS, ZFS, Btrfs.

mkfs.ext2 /dev/nvme0n1p1	  # boot partition
mkfs.fat -F32 /dev/nvme0n1p2  # efi partition
mkfs.ext4 /dev/vg/root		  # main root partition
mkswap /dev/vg/swap		      # swap

mount /dev/vg/root /mnt
swapon /dev/vg/swap

mkdir /mnt/efi
mount /dev/nvme0n1p2 /mnt/efi

mkdir /mnt/boot
mount /dev/nvme0n1p1 /mnt/boot

Installing the Base System

Now we have everything mounted at /mnt and we’re ready to install Arch. First thing is to enable parallel downloads in /etc/pacman.conf to save us some time:

nano /etc/pacman.conf # set ParallelDownloads=10

Next we install:

pacstrap /mnt base linux linux-firmware mkinitcpio lvm2 nano dhcpcd wpa_supplicant intel-ucode iwd grub

Create fstab:

genfstab -pU /mnt >> /mnt/etc/fstab
sed -i 's/relatime/noatime/' /mnt/etc/fstab # change relatime to noatime

The sed command sets noatime instead of relatime to reduce disk writes and improve performance. It just means that the access timestamp for files won’t be updated (modified timestamp will still update).

Now we can run arch-chroot to run commands from the point of view of our arch install and not from our live USB:

arch-chroot /mnt

Configuring time:

ln -s /usr/share/zoneinfo/Europe/Dublin /etc/localtime
hwclock --systohc --utc

Setting hostname (the name for you computer):

echo MYHOSTNAME > /etc/hostname

Setting locale, for me this is en_IE:

nano /etc/locale.conf

into that file:

LANG=en_IE.UTF-8
LANGUAGE=en_IE
LC_ALL=C

Uncomment en_IE.UTF-8 UTF-8 in /etc/locale.gen and generate locale

locale-gen "en_IE.UTF-8"

Set up the hosts file:

nano /etc/hosts

into that file:

127.0.0.1 localhost
::1 localhost

Set a root passwd:

passwd

You need to set a root password so you can login when we reboot later.

Set Up GRUB

initramfs

Edit the mkinitcpio config: nano /etc/mkinitcpio.conf

These are the lines I changed:

HOOKS=(base udev autodetect keyboard modconf block encrypt lvm2 filesystems fsck resume)
COMPRESSION="zstd"
COMPRESSION_OPTIONS=(-T0 -19)

The order of the hooks is important. The main changes from default here are the addition of encrypt for the disk encryption and resume for hibernation support.

I also enabled maximum compression using zstd to make efficient use of the small boot partition. This may have a performance impact on boot times.

Create the initramfs:

mkinitcpio -p linux

GRUB

Configure GRUB:

nano /etc/default/grub

In that file:

GRUB_CMDLINE_LINUX="cryptdevice=/dev/nvme0n1p3:luks resume=/dev/vg/swap mem_sleep_default=deep nmi_watchdog=0"
GRUB_ENABLE_CRYPTODISK=y

GRUB_CMDLINE_LINUX contains kernel parameters that are used on boot. Cryptdevice is obviously our encrypted container, resume points to where swap is.

mem_sleep_default configures how sleep works. I chose deep which suspends everything to RAM and puts the system in a low power state, this is useful on a laptop where power is at a premium. There is also the option for suspend to disk but that takes longer to take the computer out of sleep mode and I think at that point you may as well use hibernate.

The last one is to disable NMI watchdog which is for detecting hard lockups on the CPU. I choose to disable it because it has some minor performance overhead but it’s probably safer to leave it on.

Another popular tweak people do here is

mitigations=off

which disables the mitigations for CPU vulnerabilities such as Spectre and Meltdown as they have a significant performance impact. You can read more about that here but I keep the mitigations on myself.

Now we install grub:

mkdir /boot/grub
grub-mkconfig -o /boot/grub/grub.cfg

pacman -S efibootmgr
grub-install --target=x86_64-efi --efi-directory=/efi --removable
# the --removable is useful if BIOS updates mess up bootloader

We are now ready to reboot into our arch install:

exit # to exit back to the livecd
umount /mnt/efi /mnt/boot /mnt
swapoff /dev/vg/swap
reboot # dont forget to remove the USB!

After booting in

You should be able to login with the username root and the password we set earlier.

internet

Enable iwd and dhcpcd so that it connects to the internet automatically

systemctl enable iwd dhcpcd
systemctl start iwd dhcpcd

We do need to follow the steps from earlier to connect for the first time though.

pacman

Edit the pacman config and enable parallel downloads (and color!)

nano /etc/pacman.conf
pacman -Syu # full system update

Next I install my window manager and other necessities

FunctionProgram I usePopular Alternatives
Window Manager/Desktop Environmenti3KDE, dwm, XFCE
Status Bari3statusconky
Terminal Emulatoralacrittykitty, rxvt, st, xterm
Display ServerXorgWayland
App launcherdmenurofi
Superuser commandssudodoas
pacman -S i3-wm i3status sudo alacritty xorg-server xorg-xinit dmenu base-devel ttf-dejavu ttf-font-awesome noto-fonts-emoji wget git

yay

On Arch there is the official repositories and the community AUR. To install things from the AUR I use a program called yay.

git clone https://aur.archlinux.org/yay.git
cd yay
makepkg -si

audio

To get audio working I installed pulseaudio and alsa-utils

pacman -S pulseaudio alsa-utils
alsamixer

In alsamixer you need to unmute your device by pressing m.

Pipewire is a popular alternative to Pulseaudio and seems like a cleaner implementation but I’m sticking with Pulseaudio for now.

Note 04/05/2023: I ran into a reoccurring freezing bug which can be fixed by commenting out load-module module-suspend-on-idle in /etc/pulse/default.pa worth doing preemptively as the bug is hard to diagnose when it happens.

user account

Create a user account and set a password for it:

useradd -m -s /bin/bash USERNAME 
passwd USERNAME

Add our new user account to the sudoers file so we can run commands as root with sudo:

nano /etc/sudoers
USERNAME ALL=(ALL:ALL) ALL

Switch to that user account for a sec:

su USERNAME

Make it so that i3 will start when we login:

echo 'exec i3' > ~/.xinitrc

Add the following to ~/.bash_profile:

if [ -z "${DISPLAY}" ] && [ "${XDG_VTNR}" -eq 1 ]; then
  exec startx
fi

Post-Installation

Disable Bluetooth

I don’t use any bluetooth with my PC so I disable it.

systemctl enable [email protected]
echo 'SUBSYSTEM=="rfkill", ATTR{type}=="bluetooth", ATTR{state}="0"' > /etc/udev/rules.d/50-bluetooth.rules

Increase VM Writeback Timeout

This reduces disk writes which means more efficient power usage. This comes with the risk that if there is data loss the window of data that is lost is increased but I think 15 seconds for that is no big deal, you could go even higher.

echo 'vm.dirty_writeback_centisecs=1500' > /etc/sysctl.d/99-vm-writeback.conf

Update resolv.conf DNS Servers

I put Google and Cloudflare DNS servers into my resolv.conf to avoid using my ISP’s DNS server. It would be even better to use something like DNScrypt.

nano /etc/resolv.conf
nameserver 1.1.1.1
nameserver 8.8.8.8

Blacklisting Unneeded Modules

List modules found by autodetection:

mkinitcpio -M

Then to blacklist one’s you don’t need:

nano /etc/modprobe.d/blacklist.conf

And in that I put:

blacklist iTCO_wdt # disable watchdog
blacklist bluetooth
blacklist wmi

Then we need to configure mkinitcpio to use it:

nano /etc/mkinitcpio.conf

And we change this line:

FILES=(/etc/modprobe.d/blacklist.conf)

Recreate initramfs:

mkinitcpio -p linux

Future

There is no end to how much you can tweak your system after installing it so it’s good I think to stop at some point and actually use it. What follows is stuff I would consider doing in the future (or is not currently possible).

SecureBoot and Evil Maid

It is possible to do the whole SecureBoot hardening stuff to secure the boot process from Evil Maid attacks by signing the bootloader with your own keys but I haven’t done that on my machine and won’t be covering it here but it is something to onsider. This guide by Huntrar covers that: https://gist.github.com/huntrar/e42aee630bee3295b2c671d098c81268

GRUB support for LUKS2

As mentioned earlier GRUB only barely supports LUKS2. In the future I would like to use LUKS2 instead of LUKS1 and use Argon as the hashtype.

Xorg vs Wayland

Xorg has been gradually becoming more abandoned as a project over time for many reasons. The Wayland project is meant to supplant X11/Xorg as the display server but not everything is done yet and I’d still consider Xorg to be more well supported and reliable. Maybe some day I will switch but that day is not today

Are We Wayland Yet

Systemd

I don’t like systemd for a lot of reasons and would consider using a distro that doesn’t use it, maybe Artix Linux. If you want to read about the debate over systemd you can visit nosystemd.org

Alternate Kernels

We’ve installed the default stable linux kernel in this guide but there are other kernel projects that may interest you. The ones I found most interesting are:

Alternate Filesystems

I did read up a bit on different filesystems like ZFS and Btrfs but I didn’t really see anything appealing enough to move from ext4. Using a different filesystem is still something I might do in the future though.

Avoid extra login processes

An interesting setup I read about from Samuel Holland on the suckless mailing lists avoids having a few processes and the user login at boot since that’s meaningless on a single-user system and it doesnt provide any extra protection when you use full disk encryption anyway. I just use i3lock to lock my PC, I never really “logout” unless I’m shutting down fully.

eGPU

Later I bought an eGPU enclosure so that I could play games from the laptop on an external monitor. I chose to get the Razer Core X and it works really well. I should have got the Chroma version though as that comes with a 4 USB ports for only a small increase in cost. If I did that it would effectively be a one-cable docking station. You don’t even need to plug in in the power cable for the laptop as it can charge through the same port.

I’ll probably do a seperate post about this.

Framework Laptop

Coreboot

It would be nice if we could use Coreboot as the BIOS since it is open source however this is currently not possible on Framework laptops (if you have a different laptop/motherboard it might be supported).

There is ongoing discussion to try make this happen. One of the issues seems to be that the laptops get shipped with Intel Boot Guard enabled.

Non-Intel CPUs

I would love if Framework had support for AMD or ARM CPUs. They have better performance on laptops than Intel CPUs in terms of energy usage and they don’t get as hot which means less fans.

Another bonus is that they don’t have Intel ME backdoors.

UPDATE: Framework now have AMD CPU builds available on pre-order

Skin

There’s cool 3rd party skins available on dbrand that would be nice to get just for aesthetic reasons.

End

Thanks for reading, hopefully this is helpful to someone. If you spot any mistakes or improvements to be made on this let me know, you can message me on Fediverse @[email protected]. I use arch btw.


  1. There wasn’t enough space to load nvidia drivers in the boot process before the decryption screen so that it would be shown when I’m booting with my eGPU plugged in and not have a black screen. It’s still usable in this state I just have to do the decryption step blind without visual output and then afterwards the screen works. I will probably fix this at a later date but repartitioning with encrypted disks is complicated and has a risk of data loss and it doesn’t bother that much at the moment. ↩︎