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:
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.
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.
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
Download the Arch ISO and install it on a USB stick, I used Rufus to do it.
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.
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.
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
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
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.
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
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!
You should be able to login with the username root and the password we set earlier.
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.
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
Function | Program I use | Popular Alternatives |
---|---|---|
Window Manager/Desktop Environment | i3 | KDE, dwm, XFCE |
Status Bar | i3status | conky |
Terminal Emulator | alacritty | kitty, rxvt, st, xterm |
Display Server | Xorg | Wayland |
App launcher | dmenu | rofi |
Superuser commands | sudo | doas |
pacman -S i3-wm i3status sudo alacritty xorg-server xorg-xinit dmenu base-devel ttf-dejavu ttf-font-awesome noto-fonts-emoji wget git
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
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.
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
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
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
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
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
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).
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
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 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
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
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:
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.
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.
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.
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.
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
There’s cool 3rd party skins available on dbrand that would be nice to get just for aesthetic reasons.
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.
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. ↩︎