Skip to content

Instantly share code, notes, and snippets.

@keithpl
Last active September 12, 2024 18:32
Show Gist options
  • Save keithpl/6f336f1a053382678c72bfc01ed6afa5 to your computer and use it in GitHub Desktop.
Save keithpl/6f336f1a053382678c72bfc01ed6afa5 to your computer and use it in GitHub Desktop.
Arch Linux Installation Notes
  • UEFI
  • Systemd-boot (gummiboot)
  • Encrypted root partition
  • mkinitcpio
  • Unified Kernel Image (UKI)
  • Intel CPU
  • NVIDIA GPU
  • Wayland (sway)
  • Secure Boot (optional)

Live CD

Ensure the clock is accurate

timedatectl

Clear any existing partition table

wipefs -af /dev/nvme0n1

Partition nvme0n1 with the following table:

  • /dev/nvme0n1p1 512M ef00 - EFI system partition
  • /dev/nvme0n1p2 rest 8300 - Linux filesystem
gdisk /dev/nvme0n1

Create and present encrypted volume for root

cryptsetup -y -v luksFormat /dev/nvme0n1p2
cryptsetup --allow-discards --perf-no_read_workqueue \
  --perf-no_write_workqueue --persistent open /dev/nvme0n1p2 root 

Format root and boot/efi volumes

mkfs.fat -F 32 /dev/nvme0n1p1
mkfs.btrfs -L root /dev/mapper/root

Create mount points and mount the newly created root and ESP (EFI System Partition) filesystems. If you have an SSD you may want to consider using the "lazytime" mount option, changes to atime will be cached in memory for up to 24 hours before being written to disk.

mount --mkdir -o lazytime /dev/mapper/root /mnt/arch
mount --mkdir -o lazytime,fmask=0077,dmask=0077 /dev/nvme0n1p1 /mnt/arch/efi

Ensure the ISO has a recent keyring otherwise pacstrap may fail

pacman -Sy archlinux-keyring

Use pacstrap to install packages for chroot environment. Optional: If wireless support is needed, add the iwd package.

pacstrap -K /mnt/arch base linux linux-firmware mkinitcpio \
  neovim intel-ucode dosfstools btrfs-progs

Generate fstab

genfstab -U /mnt/arch >> /mnt/arch/etc/fstab

Chroot into the new system environment

arch-chroot /mnt/arch

Set timezone and generate /etc/adjtime

ln -sf /usr/share/zoneinfo/America/New_York /etc/localtime
hwclock --systohc

Enable systemd timesyncd and optionally specify NTP servers

nvim /etc/systemd/timesyncd.conf
systemctl enable systemd-timesyncd

Select and generate locale(s) by uncommenting locales from /etc/locale.gen you wish to generate

nvim /etc/locale.gen
locale-gen

Set the system locale in /etc/locale.conf

LANG="en_US.UTF-8"

Explicitly define keyboard layout in /etc/vconsole.conf

KEYMAP="us"

Set default editor as neovim in /etc/profile.d/editor.sh

export EDITOR="nvim"
export VISUAL="nvim"

Set the system's hostname in /etc/hostname

alpha

Add hostname to /etc/hosts

127.0.0.1 localhost
::1       localhost
127.0.1.1 alpha.home.arpa alpha

Network interface configuration, using enp9s0f0 as the example. Create /etc/systemd/network/enp9s0f0.network

[Match]
Name=enp9s0f0

[Link]
MTUBytes=9000

[Network]
DHCP=yes

[DHCPv4]
UseDomains=yes

[DHCPv6]
UseDomains=yes

Unmount resolv.conf from the live cd and create a link to systemd-resolved's stub-resolv.conf

umount /etc/resolv.conf
ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf

Enable systemd-networkd and systemd-resolved services. Do not wait for network connectivity to load subsequent services

systemctl enable systemd-networkd systemd-resolved
systemctl disable systemd-networkd-wait-online

Adjust HOOKS array in /etc/mkinitcpio.conf to use a systemd based initramfs instead of busybox. Add "sd-encrypt" hook to allow the root volume to be decrypted at boot. The "fsck" hook may be omitted when using only btrfs.

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

Enable mkinitcpio to create unified kernel images by editing /etc/mkinitcpio.d/linux.preset. Specifically, uncomment the *_uki= lines for each preset. Optionally, comment out the *_image= lines for each preset.

# mkinitcpio preset file for the 'linux' package

#ALL_config="/etc/mkinitcpio.conf"
ALL_kver="/boot/vmlinuz-linux"
ALL_microcode=(/boot/*-ucode.img)

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"

Configure the kernel command line arguments in /etc/kernel/cmdline. mkinitcpio will integrate these into the unified kernel images. An easy way to grab filesystem UUIDs inside of (n)vim is: :read !blkid /dev/nvme0n1p2

# <LUKS_UUID> refers to the UUID of /dev/nvme0n1p2 (encrypted partition)
rd.luks.name=<LUKS_UUID>=root

# <ROOT_UUID> refers to the UUID of /dev/mapper/root
root=UUID=<ROOT_UUID>

rw loglevel=3

Generate initramfs and unified kernel images

mkdir -p /efi/EFI/Linux
mkinitcpio -P

Install systmed-boot into ESP

bootctl install

check if the installed systemd-boot is outdated when the system boots update it if required.

systemctl enable systemd-boot-update

Configure systemd-boot loader in /efi/loader/loader.conf

timeout      2
console-mode max
editor       yes

Enable periodic TRIM

systemctl enable fstrim.timer

Set root password

passwd

Optional: If wireless support is required, enable the iwd service

systemctl enable iwd

Reboot into newly installed Arch Linux instance

exit
umount -R /mnt/arch
cryptsetup close root
reboot

Post Live CD

Enable pacman colored output and parallel downloads in /etc/pacman.conf

Color
VerbosePkgLists
ParallelDownloads = 5

Enable better build parallelization and compiler optimization in /etc/makepkg.conf

CFLAGS="-march=native -O2 ..."

# Match number of cpu threads, or $(nproc)
MAKEFLAGS="-j32"

Install and run reflector to update mirror list

pacman -S reflector wget rsync

reflector --verbose --country US --age 1 --protocol http,https \
  --sort rate --save /etc/pacman.d/mirrorlist

pacman -Syyuu

Install utilities and development tools

pacman -S --needed openssh traceroute dnsutils nmap tcpdump man-db man-pages \
  texinfo gptfdisk sudo zsh zip unzip unrar p7zip yadm fzf bat htop btop \
  lsof eza usbutils ethtool pacman-contrib progress tinyxxd uucp

pacman -S --needed base-devel git go gopls python3 pyright python-pynvim gcc \
  clang cmake gdb lldb valgrind linux-headers rust rust-analyzer shellcheck \
  bash-language-server lua-language-server tree-sitter tree-sitter-cli

Change root shell to zsh

chsh -s /usr/bin/zsh root

Enable timer to weekly clean out the pacman cache

systemctl enable paccache.timer

Install open source (ish) nvidia drivers

pacman -S nvidia-open libva-nvidia-driver

Append the "nvidia_drm.modeset=1" kernel argument to /etc/kernel/cmdline

rw loglevel=3 nvidia_drm.modeset=1

Configure mkinitcpio to include the nvidia kernel modules necessary for KMS in the initramfs in /etc/mkinitcpio.conf

MODULES=(nvidia nvidia_modeset nvidia_uvm nvidia_drm)

Regenerate initramfs and unified kernel images

mkinitcpio -P

Add a new non-root user, set their password, add appropriate permissions for sudo in /etc/sudoers and switch to <new_user>

useradd -m -s /usr/bin/zsh -G audio,video,wheel -c "<gecos>" <new_user>
passwd <new_user>

visudo
su - <new_user>

All remaining commands should be ran as a non-root user

Install paru

git clone https://aur.archlinux.org/paru.git
cd paru
makepkg -si
cd && rm -rf paru

Install a bunch of damn fonts

sudo pacman -S noto-fonts noto-fonts-cjk noto-fonts-emoji \
  ttf-caladea ttf-carlito ttf-dejavu ttf-liberation ttf-opensans \
  ttf-fira-mono ttf-fira-code ttf-firacode-nerd ttf-cascadia-code \
  ttf-cascadia-code-nerd ttf-font-awesome

Install noto-fonts-extra for additional variants of noto fonts (condensed, semi-bold, extra-light)

sudo pacman -S noto-fonts-extra

Install pipewire audio system with alsa, jack and pulse compatibility

sudo pacman -S pipewire pipewire-alsa pipewire-pulse pipewire-jack \
  wireplumber gst-plugin-pipewire alsa-tools alsa-utils

Optional: If you're running a laptop, you likely need firmware to support your sound card

sudo pacman -S alsa-firmware sof-firmware

Install sway and friends

sudo pacman -S sway swaylock swayidle swaybg waybar xorg-xwayland \
  xdg-desktop-portal xdg-desktop-portal-wlr xdg-desktop-portal-gtk \
  mako libnotify wofi wtype vulkan-devel grim slurp swappy polkit \
  greetd greetd-regreet wl-clipboard wf-recorder xdg-user-dirs \
  qt5-base qt5-wayland qt6-base qt6-wayland qt5ct qt6ct \
  gtk3 gtk4 gnome-themes-extra

Enable the greetd service to start at boot

sudo systemctl enable greetd

Create greetd-sway launcher to more easily tolerate nvidia at /usr/local/bin/greetd-sway

#!/usr/bin/env bash

export WLR_RENDERER="vulkan"
export WLR_NO_HARDWARE_CURSORS=1

/usr/bin/sway --unsupported-gpu "$@"

Make greetd-sway executable

sudo chmod a+x /usr/local/bin/greetd-sway

Configure greetd to use sway as the compositor in /etc/greetd/config.toml

[default_session]
command = "greetd-sway --config /etc/greetd/sway-config"
user = "greeter"

Configure sway (launched by greetd) to launch regreet in /etc/greetd/sway-config

exec "regreet; swaymsg exit"

output * mode [email protected]

xwayland disable

include /etc/sway/config.d/*

Optionally customize regreet to look a little nicer in /erc/greetd/regreet.toml

[background]
path = "/usr/share/backgrounds/wallhaven-farcry5-lock.png"

[GTK]
application_prefer_dark_theme = true
theme_name = "Adwaita"

[commands]
reboot = [ "systemctl", "reboot" ]
poweroff = [ "systemctl", "poweroff" ]

Create desktop session entry for sway pointing to wrapper script containing workarounds in /usr/share/wayland-sessions/sway-wrapper.desktop

[Desktop Entry]
Name=Sway (custom wrapper)
Comment=An i3-compatible Wayland compositor
Exec=start-sway
Type=Application

Install terminal emulators (and other applications)

sudo pacman -S alacritty foot tmux xplr hexyl mpv ffmpeg pavucontrol \
  hunspell hunspell-en_us libreoffice-fresh \
  wireshark-cli wireshark-qt termshark \
  weechat firejail enchant aspell aspell-en aspell-ru

paru -S nmap-netcat

Create pacman hook to automatically rebuild initramfs any time the nvidia drivers are upgraded via pacman

Create /etc/pacman.d/hooks directory

sudo mkdir /etc/pacman.d/hooks

Create pacman hook /etc/pacman.d/hooks/initramfs.hook to automatically regenerate initramfs and unified kernel images whenever a change is made to the kernel, kernel modules, or microcode

[Trigger]
Operation=Install
Operation=Upgrade
Operation=Remove
Type=Package
Target=amd-ucode
Target=intel-ucode
Target=linux
Target=linux-lts
Target=nvidia
Target=nvidia-open
Target=systemd

[Action]
Description=Update Unified Kernel Image
Depends=mkinitcpio
When=PostTransaction
NeedsTargets
Exec=/bin/sh -c 'while read -r trg; do case $trg in linux) exit 0; esac; done; /usr/bin/mkinitcpio -P'

Import your gpg key(s)

mkdir --mode=0700 "$XDG_DATA_HOME/gnupg"
gpg --import public.gpg
gpg --import private.gpg
gpg --edit-key <keyname>

Laptop only

Install intel iGPU drivers and backlight control

sudo pacman -S xf86-video-intel intel-media-driver acpilight

Configure Secure Boot (optional)

Ensure your EFI's Secure Boot configuration is in "setup mode". This means you have cleared the existing keys from the EFI

Install sbctl

sudo pacman -S sbctl

Confirm your system is in secure boot setup mode

sudo sbctl status

Create custom secure boot keys

sudo sbctl create-keys

Sign the bootloader as well as the unified kernel images

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

Enroll your custom keys to the EFI, the -m option includes Microsoft's keys in addition

sudo sbctl enroll-keys -m

Create /etc/pacman.d/hooks/bootloader-sign.hook to create a pacman hook automatically signing the systemd-boot bootloader after an upgrade or re-install

[Trigger]
Operation=Install
Operation=Upgrade
Type=Package
Target=systemd

[Action]
Description=Sign systemd-boot bootloader with secure boot keys
When=PostTransaction
NeedsTargets
Exec=/usr/bin/sbctl sign -s -o /usr/lib/systemd/boot/efi/systemd-bootx64.efi.signed /usr/lib/systemd/boot/efi/systemd-bootx64.efi
@rj1
Copy link

rj1 commented Jun 11, 2021

great content, keep it coming!

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