Skip to content

Instantly share code, notes, and snippets.

@RobFisher
Last active February 23, 2024 07:25
Show Gist options
  • Star 9 You must be signed in to star a gist
  • Fork 9 You must be signed in to fork a gist
  • Save RobFisher/abd9b2b9fca4194ac8df112715045b61 to your computer and use it in GitHub Desktop.
Save RobFisher/abd9b2b9fca4194ac8df112715045b61 to your computer and use it in GitHub Desktop.
Install Arch on Framework laptop with BTRFS, encrypted swap and hibernate

See video: https://www.youtube.com/watch?v=BAQ78pBPjjc

Set up laptop

In BIOS, under security, set "Enforce secure boot" to "disabled".

Get install environment working

Keyboard layout for boot env:

localectl list-keymaps | grep uk
loadkeys uk

See IP setup:

ip -c a

Connect to wifi:

iwctl
station wlan0 scan
station wlan0 get-networks
station wlan0 connect myssid

ping www.google.com

IMPORTANT: set up system time

timedatectl list-timezones | grep London
ln -sf /usr/share/zoneinfo/Europe/London /etc/localtime
timedatectl set-ntp true
date
hwclock --systohc

Check mirror list; hopefully this has been updated automatically by Reflector:

vim /etc/pacman.d/mirrorlist

Sync package database.

pacman -Sy

Partition disk

See disks:

lsblk

Partition disk:

gdisk /dev/nvme0n1

Make boot EFI partition:

n
1
ENTER for default first sector
+350M
ef00

Make main linux partition:

n
2
ENTER for default first sector
-50G # leaving 50GB at the end for the SSD to work with
ENTER for default type linux

Print parition table:

p

Write the partiion table and exit:

w
Y

Format paritions

Format the boot parition:

mkfs.vfat /dev/nvme0n1p1

Set up BTRFS on and encrypted LUKS partition:

 cryptsetup luksFormat /dev/nvme0n1p2
 YES
 passphrase
 cryptsetup luksOpen /dev/nvme0n1p2 cryptroot
 passphrase
 lsblk
 ls /dev/mapper
 mkfs.btrfs /dev/mapper/cryptroot
 mount /dev/mapper/cryptroot /mnt
 ls /mnt

Set up BTRFS sub-volumes:

 btrfs subvolume create /mnt/@
 btrfs subvolume create /mnt/@home
 btrfs subvolume create /mnt/@var
 btrfs subvolume create /mnt/@swap
 umount /mnt

Mount the filesystems:

mount -o noatime,compress=zstd,ssd,discard=async,space_cache=v2,subvol=@ /dev/mapper/cryptroot /mnt
mkdir -p /mnt/{boot,home,var,swap}
mount -o noatime,compress=zstd,ssd,discard=async,space_cache=v2,subvol=@home /dev/mapper/cryptroot /mnt/home
mount -o noatime,compress=zstd,ssd,discard=async,space_cache=v2,subvol=@var /dev/mapper/cryptroot /mnt/var
mount -o noatime,ssd,space_cache=v2,subvol=@swap /dev/mapper/cryptroot /mnt/swap
mount /dev/nvme0n1p1 /mnt/boot
lsblk

Install Arch

Pacstrap:

pacstrap /mnt base linux linux-firmware git vim intel-ucode btrfs-progs

More setup:

genfstab -U /mnt >> /mnt/etc/fstab
vim /mnt/etc/fstab
:q

Chroot time:

arch-chroot /mnt

Localisation:

ln -sf /usr/share/zoneinfo/Europe/London /etc/localtime
vim /etc/locale.gen

Un-comment desired locales, e.g. en_GB.UTF8 and en_GB ISO-8859-1

:wq
locale-gen
echo "LOCALE=en_GB.UTF8" > /etc/locale.conf
echo "KEYMAP=uk" > /etc/vconsole.conf

Other setup:

echo "myhost" > /etc/hostname
vim /etc/hosts

Make /etc/hosts look like:

127.0.0.1   localhost
::1   localhost
127.0.1.1   myhost.localdomain  myhost

Set root password:

passwd

Set up boot

pacman -Syu grub efibootmgr networkmanager wpa_supplicant mtools dosfstools base-devel linux-headers

Choose defaults when prompted.

grub-install --target=x86_64-efi --efi-directory=/boot --bootloader-id=GRUB

Get UUID of boot device and append it to end of file for cutting and pasting:

blkid
blkid | grep n1p2 | cut -d\" -f 2
blkid | grep n1p2 | cut -d\" -f 2 >> /etc/default/grub # we need to edit this next
vim /etc/default/grub

Edit GRUB_CMDLINE_LINUX_DEFAULT to look like this; you can cut the UUID from the end of the file by pressing v to go into visual mode, moving cursor to the end, and then pressing d to cut. Later you can paste it with the p command.

"loglevel=3 quiet acpi_osi=\"Windows 2020\" mem_sleep_default=deep cryptdevice=UUID=PASTED-UUID:cryptroot:allow-discards root=/dev/mapper/cryptroot"

Set up Grub:

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

Set up boot image:

vim /etc/mkinitcpio.conf

Edit the MODULES line to look like this:

MODULES=(btrfs)

Edit the HOOKS line to look like this:

HOOKS=(base udev autodetect modconf block encrypt filesystems keyboard fsck)

Then run:

mkinitcpio -p linux

Enable services:

systemctl enable NetworkManager
systemctl enable fstrim.timer

Set up user:

useradd -m myuser
passwd myuser
password
usermod -aG wheel myuser
id
EDITOR=vim visudo

Un-comment the line underneath "uncomment to allow members of group wheel to execute any command".

Boot for the first time

exit
umount -R /mnt
reboot

Remove the USB stick. Type the LUKS password when prompted. Log in with your user created above.

Configure network after first boot

Use this tool to configure the network:

sudo nmtui

Set up encrypted swap

cd /swap
sudo su
truncate -s 0 ./swapfile
chattr +C ./swapfile
btrfs property set ./swapfile compression none
dd -if=/dev/zero of=swapfile bs=1M count=40916 status=progress # bs times counte should be size of your RAM plus a bit
chmod 600 swapfile
mkswap swapfile
swapon /swap/swapfile
vim /etc/fstab

Add this line:

/swap/swapfile none swap defaults 0 0

Check it:

cat /proc/swaps

Fix watchdog error message on reboot:

sudo vim /etc/systemd/system.conf

Un-comment and replace RebootWatchdogSec line with:

RebootWatchdogSec=0

Install some packages:

sudo pacman -Sy man-db man-pages

Set up the AUR

Choose Rustup when given the choice.

cd
git clone https://aur.archlinux.org/paru.git
makepkg -si
rustup install stable
makepkg -si

Install KDE:

sudo pacman -Sy xorg plasma-desktop sddm
paru -S alacritty

Choose pipewire-jack, wireplumber, noto-fonts, vlc

sudo systemctl enable sddm
sudo systemctl start sddm

Open Alacritty and run:

sudo pacman -Sy firefox
sudo pacman -Sy plasma-meta plasma-browser-integration kde-gtk-config xdg-desktop-portal xdg-desktop-portal-kde

Enable video acceleration in Firefox by going to about:config and setting ffmpeg_v8_api to true.

Power management (choose default):

paru -S tlpui

Fingerprint reader:

sudo pacman -Sy fprintd
fprintd-enroll

Set up hibernation

sudo vim /etc/mkinitcpio.conf

Make HOOKS look like this (add resume after filesystems):

HOOKS=(base udev autodetect modconf block encrypt filesystems resume keyboard fsck)

Now run:

 sudo mkinitcpio -p linux

Download this: https://github.com/osandov/osandov-linux/blob/master/scripts/btrfs_map_physical.c

cd ~/Downloads
gcc -O2 -o btrfs_map_physical btrfs_map_physical.c
sudo ./btrfs_map_physical /swap/swapfile
sudo ./btrfs_map_physical /swap/swapfile | cut -f 9 | head -2
getconf PAGESIZE

Divide the physical offset by the page size.

blkid | grep cryptroot
sudo vim /etc/default/grub

Make GRUB_CMDLINE_LINUX_DEFAULT look like this:

"loglevel=3 quiet acpi_osi=\"Windows 2020\" mem_sleep_default=deep cryptdevice=UUID=PASTED-UUID:cryptroot:allow-discards root=/dev/mapper/cryptroot resume=UUID=UUID-OF-DEV-MAPPER-CRYPTROOT resume_offset=CALCULATED-VALUE"

Now run:

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

Reboot once before trying to hibernate. Hibernate with:

sudo systemctl hibernate
@exbotanical
Copy link

Super helpful. Are your function keys working? I'm running a very similar setup on my FW but with i3wm; seems none of the function keys work and the usual methods for configuring them don't work.

@thesignal
Copy link

Thanks for the writeup, I used this with small adjustments for my AMD Framework.

Instead of compiling the small c programm to get the offset you can also use

btrfs inspect-internal map-swapfile -r /swap/swapfile

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment