Skip to content

Instantly share code, notes, and snippets.

@AnAnonymousPotato
Last active October 22, 2025 11:58
Show Gist options
  • Save AnAnonymousPotato/b579c5f4472e7e6a022babcde7f60007 to your computer and use it in GitHub Desktop.
Save AnAnonymousPotato/b579c5f4472e7e6a022babcde7f60007 to your computer and use it in GitHub Desktop.
AnonSpud's Personal Arch Linux Installation Guide

AnonSpud's Personal Arch Linux Installation Guide

Goal: a modern Arch Linux install (Btrfs, snapshots via Snapper, gaming-ready) dual-booting with Windows 11. Secure Boot is OFF in this guide. This guide is made for my personal use, and has choices picked by me.

Hardware & choices used in this guide

  • CPU: Intel Core i5-12400F
  • GPU: AMD Radeon RX-6650 XT (8 GB)
  • RAM: 16 GB DDR4-3200 (2×8 GB)
  • Filesystem: Btrfs with subvolumes @, @home, @snapshots, @log, @cache
  • Snapshot tool: snapper + snap-pac
  • Bootloader: GRUB (UEFI) — simple fix for MSI/firmware quirks included
  • Audio: PipeWire + wireplumber
  • Swap: zram via zram-generator (configured)
  • Gaming helpers: gamemode, Vulkan + 32-bit libs, Steam/Lutris compatible

Table of contents

  1. Preparation (live USB)
  2. Disk layout & partitioning
  3. Formatting & labels
  4. Create Btrfs subvolumes
  5. Mounting (recommended options)
  6. Mount Windows ESP temporarily (for os-prober)
  7. Install base system (pacstrap)
  8. Generate & edit /etc/fstab (important)
  9. Chroot — system configuration
  10. Users & passwords
  11. GRUB install & MSI boot fix
  12. Enable services
  13. Reboot and post-install tasks
  14. Snapper configuration
  15. GRUB snapshot integration (grub-btrfs)
  16. Install KDE, GPU & multimedia packages
  17. ZRAM (recommended config)
  18. Gaming extras & performance
  19. Post-install: AUR helper, firewall & mirror updates
  20. Optional: SDDM auto-login
  21. Notes & troubleshooting tips

1. Preparation (live USB)

  • Boot Arch ISO in UEFI mode.
  • Keyboard layout:
loadkeys us
  • Verify UEFI mode (should show 64):
cat /sys/firmware/efi/fw_platform_size
  • Ensure network:
ping -c 3 archlinux.org
  • Sync clock:
timedatectl set-ntp true

2. Disk layout & partitioning

Example using /dev/nvme1n1 (replace with your disk):

  • Partition 1: 512M — EFI System (FAT32)
  • Partition 2: remaining — Linux filesystem (Btrfs)

Use gdisk (or cfdisk if you prefer a TUI):

gdisk /dev/nvme1n1

3. Formatting & labels

Format EFI partition (with label ARCH_ESP):

mkfs.fat -F32 -n ARCH_ESP /dev/nvme1n1p1

Format Btrfs root partition (with label ARCH_ROOT):

mkfs.btrfs -L ARCH_ROOT /dev/nvme1n1p2

4. Create Btrfs subvolumes

Mount the raw Btrfs device, create subvolumes, then unmount:

mount /dev/nvme1n1p2 /mnt

btrfs subvolume create /mnt/@
btrfs subvolume create /mnt/@home
btrfs subvolume create /mnt/@snapshots
btrfs subvolume create /mnt/@log
btrfs subvolume create /mnt/@cache

umount /mnt

These names are concise and map to /, /home, /.snapshots, /var/log, /var/cache respectively.


5. Mounting (recommended options)

Choose mount options (remember to remove discard=async option from fstab, which is added automatically):

BTRFS_OPTS="rw,ssd,noatime,compress=zstd:1,space_cache=v2"

Mount root and create mount points:

mount -o $BTRFS_OPTS,subvol=@ /dev/nvme1n1p2 /mnt
mkdir -p /mnt/{home,.snapshots,var/{log,cache},efi,win-esp}
mount -o $BTRFS_OPTS,subvol=@home /dev/nvme1n1p2 /mnt/home
mount -o $BTRFS_OPTS,subvol=@snapshots /dev/nvme1n1p2 /mnt/.snapshots
mount -o $BTRFS_OPTS,subvol=@log /dev/nvme1n1p2 /mnt/var/log
mount -o $BTRFS_OPTS,subvol=@cache /dev/nvme1n1p2 /mnt/var/cache
mount /dev/nvme1n1p1 /mnt/efi

Notes:

  • We do not enable discard=async here — prefer fstrim.timer.
  • compress=zstd:1 is a good balance for desktop/SSD.

6. Mount Windows ESP temporarily (for os-prober)

To let os-prober detect Windows (if Windows ESP is on another disk), mount it read-only.

Find the Windows ESP (e.g., /dev/nvme0n1p3) with lsblk -f then:

mount -o ro /dev/nvme0n1p3 /mnt/win-esp

After running os-prober/grub-mkconfig you can umount /mnt/win-esp (but not now).


7. Install base system (pacstrap)

Install a curated base set (long commands can be broken with \ backslash):

pacstrap /mnt base base-devel linux linux-headers linux-firmware git btrfs-progs grub efibootmgr os-prober ntfs-3g dosfstools intel-ucode nano networkmanager \
pipewire pipewire-alsa pipewire-pulse pipewire-jack wireplumber reflector man man-db man-pages sudo grub-btrfs snapper snap-pac inotify-tools

You can add extra packages later (via pacman); the above covers essentials for this guide.


8. Generate & edit /etc/fstab (important)

Generate fstab:

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

CRITICAL: open /mnt/etc/fstab and ensure every Btrfs line uses exactly:

rw,ssd,noatime,compress=zstd:1,space_cache=v2

Delete any discard=async entries added by genfstab (we prefer scheduled fstrim.timer).


9. Chroot — system configuration

Enter chroot:

arch-chroot /mnt

Set timezone (Asia/Kolkata):

ln -sf /usr/share/zoneinfo/Asia/Kolkata /etc/localtime
hwclock --systohc

Locales: edit /etc/locale.gen and uncomment en_US.UTF-8 and en_IN.UTF-8, then:

locale-gen

Create /etc/locale.conf with your locale settings:

echo "LANG=en_IN.UTF-8" > /etc/locale.conf
echo "LC_MESSAGES=en_US.UTF-8" >> /etc/locale.conf

Set hostname and edit /etc/hosts (replace my-arch-pc with your preferred hostname):

# To set the hostname
echo "my-arch-pc" > /etc/hostname

Edit /etc/hosts and add this line at the end:

nano /etc/hosts

Add:

127.0.0.1   localhost
::1         localhost
127.0.1.1   my-arch-pc

10. Users & passwords

Set root password:

passwd

Create your normal user (replace anirudh with your preferred name) and set its password:

useradd -mG wheel anirudh
passwd anirudh

Enable wheel sudoers: Do EDITOR=nano visudo and uncomment this line:

%wheel ALL=(ALL:ALL) ALL

11. GRUB install & MSI boot fix

Install GRUB to the EFI and register entry:

grub-install --target=x86_64-efi --efi-directory=/efi --bootloader-id="Arch (GRUB)" --recheck

Create the empty fallback file to satisfy some firmware (MSI):

mkdir -p /efi/EFI/BOOT
touch /efi/EFI/BOOT/bootx64.efi

Edit /etc/default/grub and set:

nano /etc/default/grub

Change this line:

GRUB_DISABLE_OS_PROBER=false

Then generate config:

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

Verify with efibootmgr and remove /win-esp if you mounted it earlier:

efibootmgr
umount /win-esp
rmdir /win-esp

12. Enable services

Enable networking and scheduled TRIM (recommended):

systemctl enable NetworkManager
systemctl enable fstrim.timer

13. Reboot and post-install tasks

Exit chroot, unmount and reboot:

exit
umount -R /mnt
reboot

Remove USB and boot into your new system.


14. Snapper configuration

Create the root snapper config and set permissions:

sudo snapper -c root create-config /
sudo chmod a+rx /.snapshots

Enable cleanup and timers:

sudo snapper -c root set-config NUMBER_CLEANUP="yes"
sudo systemctl enable --now snapper-timeline.timer
sudo systemctl enable --now snapper-cleanup.timer

Verify snapshot creation after a pacman transaction:

sudo pacman -Syu
sudo snapper -c root list

You should see pre and post snapshots created by snap-pac hooks.


15. GRUB snapshot integration (grub-btrfs)

Enable the daemon that adds snapshots to the GRUB menu:

sudo systemctl enable --now grub-btrfsd

This makes it easy to boot older snapshots from GRUB.


16. Install KDE, GPU & multimedia packages

Enable multilib in /etc/pacman.conf (uncomment [multilib] and Include = /etc/pacman.d/mirrorlist) and update:

sudo nano /etc/pacman.conf
sudo pacman -Syu

Install desktop, drivers and 32-bit libs for gaming:

sudo pacman -S plasma-meta dolphin konsole sddm sddm-kcm bluez bluez-utils
sudo pacman -S mesa lib32-mesa vulkan-radeon lib32-vulkan-radeon libva-mesa-driver lib32-libva-mesa-driver mesa-vdpau lib32-mesa-vdpau

Notes:

  • Do not need xf86-video-amdgpu for Wayland; mesa + kernel amdgpu driver + Vulkan packages are the important parts.
  • lib32-* packages are required for many Proton/Wine games (32-bit runtimes).

Enable graphical login and Bluetooth:

sudo systemctl enable sddm
sudo systemctl enable bluetooth
reboot

17. ZRAM (recommended config)

Install zram-generator and configure a sensible zram device:

sudo pacman -S zram-generator
sudo tee /etc/systemd/zram-generator.conf > /dev/null <<'EOF'
[zram0]
zram-size = ram / 2
compression-algorithm = zstd
fs-type = swap
EOF

# Set a reasonable swappiness (tweak to taste, recommended 133 or 180)
echo 'vm.swappiness=180' | sudo tee /etc/sysctl.d/99-zram-swappiness.conf

Apply the sysctl setting and reboot to activate zram:

sudo sysctl --system
reboot

After reboot, verify zram is active:

zramctl

Note: Hibernation is not supported on zram alone. Use a disk swap if you require suspend-to-disk.


18. Gaming extras & performance

  • Install GameMode (Feral) and the 32-bit variant:
sudo pacman -S gamemode lib32-gamemode
sudo systemctl enable --now gamemoded
sudo usermod -aG gamemode $USER
  • Use gamemoderun (or Steam/Lutris launch options) to request optimizations:
gamemoderun %command%
  • For Wine/Proton, make sure lib32-mesa, lib32-vulkan-radeon and lib32-libva-mesa-driver are installed.
  • If you prefer Wayland, XWayland will run X11 apps; keep mesa and 32-bit libs installed for compatibility.

19. Post-install: AUR helper, firewall & mirror updates

Install an AUR helper (yay)

Many useful packages for gaming and desktop use are in the AUR. Install yay as your AUR helper:

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

Setup firewall (ufw)

Install and configure ufw (Uncomplicated Firewall):

sudo pacman -S ufw
sudo systemctl enable --now ufw
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw enable

Check status:

sudo ufw status verbose

Configure Reflector for automatic mirror updates

Since you already installed reflector, configure it to automatically update your mirrorlist:

sudo tee /etc/xdg/reflector/reflector.conf > /dev/null <<'EOF'
--save /etc/pacman.d/mirrorlist
--protocol https
--country India
--latest 10
--sort rate
EOF

Enable the reflector timer:

sudo systemctl enable --now reflector.timer

This will automatically update your mirrors weekly.


20. Optional: SDDM auto-login

If you're the only user and prefer automatic login to your desktop, you can configure SDDM to skip the login screen.

Security warning: Auto-login bypasses the login screen, meaning anyone with physical access to your computer can access your account. Only enable this on personal machines in secure environments.

Create or edit the SDDM configuration file:

sudo mkdir -p /etc/sddm.conf.d
sudo tee /etc/sddm.conf.d/autologin.conf > /dev/null <<'EOF'
[Autologin]
User=anirudh
Session=plasma
EOF

Replace anirudh with your actual username. The Session=plasma value is for KDE Plasma; if you install a different desktop environment later, you may need to change this value.

To find available sessions:

ls /usr/share/xsessions/
ls /usr/share/wayland-sessions/

For KDE Plasma on Wayland, you might use Session=plasmawayland instead.

Reboot to test:

reboot

To disable auto-login later, simply delete the configuration file:

sudo rm /etc/sddm.conf.d/autologin.conf

21. Notes & troubleshooting tips

  • /etc/fstab: Double-check Btrfs mount options — removing discard=async is intentional.
  • Snapshots ≠ Backups: Snapshots live on same disk — keep off-device backups for important data.
  • If GRUB fails after updates: Rebuild /boot/grub/grub.cfg and ensure ESPs are mounted when doing so.
  • Gaming performance: For competitive gaming, consider lowering vm.swappiness to 60-100 for more responsive performance.
  • Microcode updates: The intel-ucode package provides CPU microcode updates. GRUB should automatically detect and load it.

I hope that whoever is following this guide now has a fully functional Arch Linux system!

[OLD] Arch Linux Installation Guide — Written by AI

(UEFI • Dual-Boot with Windows 11 • Btrfs (flat) • Snapper + grub-btrfs • ZRAM • KDE Plasma on Wayland)

⚠️ IMPORTANT DISCLAIMER
This gist is meant for my personal use. I am sharing it publicly in case it may help others, but it is tailored specifically to my hardware and needs.
This guide was created through multiple AI language models: written, refined, and combined by them in several rounds. I take no credit for the technical content.
I will not be responsible if anything goes wrong while following this guide. It is entirely AI-generated and comes with no guarantees of accuracy, safety, or suitability for your system.
This guide is powerful and destructive if applied to the wrong device. Always double-check disk names with lsblk -f or blkid before running any destructive command.
Follow this guide at your own risk.


Quick reference — devices & names

Item Device / Value
Windows drive (DO NOT TOUCH) /dev/nvme0n1
Target Arch drive (WILL BE WIPED) /dev/nvme1n1
ESP (Arch, FAT32) /dev/nvme1n1p1 (≈550 MiB)
/boot (ext4) /dev/nvme1n1p2 (≈1 GiB)
Btrfs root /dev/nvme1n1p3 (rest)
username anirudh
hostname archpc

Table of contents

  1. Pre-installation checklist
  2. Boot live ISO & network
  3. Partitioning & formatting (DESTROYS /dev/nvme1n1)
  4. Btrfs subvolumes & mount points
  5. Base install (pacstrap) & fstab
  6. Chroot: system configuration
  7. Install GRUB & ensure Windows detection
  8. Graphics, Audio, KDE (Wayland) setup
  9. Snapshots (Snapper) & grub-btrfs integration
  10. ZRAM (no swap) with systemd-zram-generator
  11. Services & maintenance timers
  12. AUR, multilib & yay (Steam)
  13. Finalize & reboot checklist
  14. Post-install verification & quick checks
  15. Updates, rollback & recovery
  16. Common pitfalls & troubleshooting
  17. Useful copy-paste command sets

1 — Pre-installation checklist

  • Back up important data from both drives.
  • Firmware: UEFI mode enabled (CSM/Legacy off).
  • Secure Boot: disabled for this guide. (You can re-enable later if you sign boot artifacts.)
  • TPM: enabled (Windows 11 requires it). We won’t use it for Arch here.
  • Create Arch USB (Rufus in DD mode, Ventoy, or dd).
  • Boot USB in UEFI mode.

2 — Boot live ISO & network

Boot the Arch USB and confirm UEFI:

ls /sys/firmware/efi/efivars

(If the directory exists, you are in UEFI mode.)

Configure network:

  • Ethernet (usually automatic):

    ping -c 3 archlinux.org
  • Wi-Fi (using iwctl):

    iwctl
    # at the prompt:
    device list
    station <device> scan
    station <device> get-networks
    station <device> connect "<SSID>"
    exit
    ping -c 3 archlinux.org

Sync clock:

timedatectl set-ntp true

3 — Partitioning & formatting (DESTROYS /dev/nvme1n1)

WARNING: This section will erase everything on /dev/nvme1n1. Verify with lsblk and only continue if you're 100% sure.

List disks:

lsblk -f

Sample partition layout (recommended):

  • /dev/nvme1n1p1 — EFI (FAT32) — 550 MiB
  • /dev/nvme1n1p2/boot (ext4) — 1 GiB
  • /dev/nvme1n1p3 — Btrfs root — rest

Create GPT partitions with gdisk:

gdisk /dev/nvme1n1
# then in gdisk:
o     # new GPT
n 1 [Enter] +550M ef00
n 2 [Enter] +1G 8300
n 3 [Enter] [Enter] 8300
p     # verify
w     # write
Y     # confirm

Format partitions:

mkfs.fat -F32 -n ARCH_ESP /dev/nvme1n1p1
mkfs.ext4 -L ARCH_BOOT /dev/nvme1n1p2
mkfs.btrfs -f -L ARCH_ROOT /dev/nvme1n1p3

Sanity check:

lsblk -f

4 — Btrfs subvolumes & mount points

Create flat subvolumes: @, @home, @snapshots.

mount /dev/nvme1n1p3 /mnt
btrfs subvolume create /mnt/@
btrfs subvolume create /mnt/@home
btrfs subvolume create /mnt/@snapshots
umount /mnt

Mount subvolumes for installation (SSD-friendly options):

BTRFS_OPTS="rw,noatime,ssd,compress=zstd:1,space_cache=v2"

mount -o subvol=@,$BTRFS_OPTS /dev/nvme1n1p3 /mnt
mkdir -p /mnt/{home,.snapshots,boot/EFI}
mount -o subvol=@home,$BTRFS_OPTS /dev/nvme1n1p3 /mnt/home
mount -o subvol=@snapshots,$BTRFS_OPTS /dev/nvme1n1p3 /mnt/.snapshots
mount /dev/nvme1n1p2 /mnt/boot
mount /dev/nvme1n1p1 /mnt/boot/EFI

Verify mount layout:

findmnt -R /mnt

Note: We prefer scheduled fstrim (via fstrim.timer) instead of the discard mount option.


5 — Base install (pacstrap) & fstab

Optionally pick fast mirrors (reflector):

pacman -S --noconfirm reflector
reflector --country India,Singapore --age 12 --protocol https --sort rate --save /etc/pacman.d/mirrorlist

Install base system:

pacstrap /mnt base base-devel linux linux-firmware intel-ucode \
  btrfs-progs grub efibootmgr dosfstools os-prober \
  networkmanager vim git sudo

If you have AMD CPU, replace intel-ucode with amd-ucode.

Generate fstab:

genfstab -U /mnt >> /mnt/etc/fstab
# Review it:
sed -n '1,200p' /mnt/etc/fstab

Make sure Btrfs entries include subvol= and compress=zstd:1 etc.


6 — Chroot: system configuration

Enter chroot:

arch-chroot /mnt /bin/bash

Time, locale, keyboard:

ln -sf /usr/share/zoneinfo/Asia/Kolkata /etc/localtime
hwclock --systohc

echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen
locale-gen
echo "LANG=en_US.UTF-8" > /etc/locale.conf

# console keymap
echo "KEYMAP=in" > /etc/vconsole.conf

Hostname & hosts:

echo "archpc" > /etc/hostname

cat > /etc/hosts <<EOF
127.0.0.1   localhost
::1         localhost
127.0.1.1   archpc.localdomain archpc
EOF

Users & sudo:

passwd                              # set root password
useradd -m -G wheel -s /bin/bash anirudh
passwd anirudh

pacman -S --noconfirm sudo
EDITOR=vim visudo
# In visudo: uncomment '%wheel ALL=(ALL:ALL) ALL'

Rebuild initramfs:

mkinitcpio -P

Enable NetworkManager (system service):

systemctl enable NetworkManager

7 — Install GRUB & ensure Windows detection

Important: os-prober detects other OSs when their EFI partition is mounted. Mount Windows ESP read-only inside the chroot before generating grub config.

Mount Windows ESP (temporary):

mkdir -p /boot/WinESP
mount -o ro /dev/nvme0n1p1 /boot/WinESP   # adjust if Windows uses a different partition

Install GRUB to the Arch ESP:

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

Enable os-prober:

# Edit or add to /etc/default/grub:
# GRUB_DISABLE_OS_PROBER=false
sed -i 's/^#GRUB_DISABLE_OS_PROBER=.*/GRUB_DISABLE_OS_PROBER=false/' /etc/default/grub || \
  echo "GRUB_DISABLE_OS_PROBER=false" >> /etc/default/grub

Generate grub config:

grub-mkconfig -o /boot/grub/grub.cfg
# Verify Windows entry:
grep -i "Windows" /boot/grub/grub.cfg || echo "WARNING: Windows not detected in GRUB."

Unmount Windows ESP:

umount /boot/WinESP

Tip: If os-prober fails to find Windows, ensure the Windows ESP is correctly mounted and that os-prober package is installed.


8 — Graphics, Audio & KDE (Wayland) setup

AMD GPU (RX 6650 XT)

pacman -S --noconfirm mesa lib32-mesa vulkan-radeon lib32-vulkan-radeon

(Drivers are in-kernel via amdgpu. Mesa and Vulkan userspace provide OpenGL & Vulkan.)

Audio (PipeWire + WirePlumber)

pacman -S --noconfirm pipewire pipewire-pulse pipewire-alsa wireplumber pipewire-jack
pacman -S --noconfirm bluez bluez-utils
systemctl enable bluetooth.service

Note: pipewire-media-session is deprecated — do not install it together with wireplumber. Use one session manager; we use wireplumber.

KDE Plasma

Minimal (recommended):

pacman -S --noconfirm plasma-desktop plasma-wayland-session sddm konsole dolphin firefox

Full KDE (optional):

pacman -S --noconfirm plasma-meta kde-applications

Enable SDDM:

systemctl enable sddm

Install Xorg fallback:

pacman -S --noconfirm xorg-server xorg-apps xorg-xinit

9 — Snapshots: Snapper & grub-btrfs integration

Install Snapper:

pacman -S --noconfirm snapper

Create config for root:

snapper -c root create-config /

Edit /etc/snapper/configs/root and set retention (suggested):

TIMELINE_CREATE="yes"
TIMELINE_CLEANUP="yes"
TIMELINE_LIMIT_HOURLY="5"
TIMELINE_LIMIT_DAILY="7"
NUMBER_LIMIT="50"

Enable timers:

systemctl enable snapper-timeline.timer
systemctl enable snapper-cleanup.timer

grub-btrfs & snap-pac (AUR): After installing an AUR helper (yay), install:

yay -S grub-btrfs snap-pac
systemctl enable --now grub-btrfsd

grub-btrfsd updates GRUB menu entries to include snapshots. snap-pac provides pacman hooks so snapshots are created automatically on package changes.

Storage note: snapshots are copy-on-write; initially cheap, but grow with changes. Monitor with:

btrfs filesystem df /
snapper list

10 — ZRAM (no swap): systemd-zram-generator

Install generator:

pacman -S --noconfirm systemd-zram-generator

Create /etc/systemd/zram-generator.conf:

[zram0]
zram-size = min(ram / 2, 4096)
compression-algorithm = zstd
swap-priority = 100

Set swappiness (example):

echo "vm.swappiness=100" > /etc/sysctl.d/99-swappiness.conf

Note: ZRAM is fast and reduces SSD writes; hibernation is not supported with zram alone (no resume swap). If you need suspend-to-disk, create a real swap partition/file and configure resume.


11 — Services & maintenance timers

Enable recommended services (system-level):

systemctl enable fstrim.timer          # weekly TRIM
systemctl enable systemd-timesyncd     # time synchronization
systemctl enable bluetooth.service
systemctl enable snapper-timeline.timer
systemctl enable snapper-cleanup.timer
pacman -S --noconfirm smartmontools fwupd
systemctl enable smartd
systemctl enable fwupd-refresh.timer

Optional: limit journal size in /etc/systemd/journald.conf:

SystemMaxUse=1G

12 — AUR, multilib & yay (Steam)

Enable multilib:

Edit /etc/pacman.conf and uncomment:

[multilib]
Include = /etc/pacman.d/mirrorlist

Then:

pacman -Syy

Install yay as regular user (anirudh):

su - anirudh
git clone https://aur.archlinux.org/yay.git
cd yay
makepkg -si
cd .. && rm -rf yay
exit

Install AUR helpers for snapshots & GRUB:

yay -S --noconfirm grub-btrfs snap-pac

Install Steam:

pacman -S --noconfirm steam

AUR security: always review PKGBUILD before building. Don’t run untrusted build scripts as root.


13 — Finalize & reboot checklist

  • Verify /etc/fstab entries.
  • Ensure mkinitcpio -P succeeded.
  • grub-mkconfig -o /boot/grub/grub.cfg finished without errors and Windows detected.
  • Enabled services: NetworkManager, sddm, fstrim.timer, snapper timers, smartd, fwupd-refresh.timer.
  • Confirm user anirudh exists and in wheel.

Exit chroot, unmount, reboot:

exit
umount -R /mnt
reboot

Remove USB when appropriate.


14 — Post-install verification & quick checks (first boot)

Log in as anirudh.

Quick checks:

# ZRAM
swapon --show

# Btrfs usage
sudo btrfs filesystem df /

# GRUB entries
sudo grub-mkconfig -o /boot/grub/grub.cfg
grep -i windows /boot/grub/grub.cfg || echo "Windows not listed in GRUB"

# GPU
glxinfo | grep "OpenGL renderer"    # may require pacman -S mesa-demos
vulkaninfo | grep "deviceName"       # requires vulkan-tools

# Audio
pactl info
systemctl --user enable --now pipewire pipewire-pulse wireplumber

Create initial snapshot:

sudo snapper -c root create -d "Initial setup complete"
sudo snapper list

15 — Updates, rollback & recovery

Update workflow (manual, safe):

sudo snapper -c root create -d "pre-update"   # optional if snap-pac isn't installed
sudo pacman -Syu
yay -Syu
reboot if kernel updated

Rollback:

  • Temporary: choose snapshot from GRUB snapshots menu at boot.

  • Permanent:

    sudo snapper rollback
    sudo grub-mkconfig -o /boot/grub/grub.cfg
    reboot

Cleanup:

sudo pacman -Rns $(pacman -Qtdq || true)
sudo paccache -rk2

16 — Common pitfalls & troubleshooting

  • Windows not in GRUB: mount Windows ESP read-only in chroot and re-run grub-mkconfig.
  • Disk full due to snapshots: snapper list; delete old snapshots snapper -c root delete <num>. Adjust retention.
  • Partial upgrades: never use pacman -Sy <pkg> alone. Always pacman -Syu.
  • No audio: ensure user PipeWire services running: systemctl --user status pipewire.
  • No Wi-Fi: check ip link and dmesg for firmware errors; install necessary firmware packages.
  • Hibernation needed: create swap partition/file and configure resume= in mkinitcpio.conf (advanced).

17 — Useful copy-paste command sets

Create subvolumes & mount (for pacstrap)

mount /dev/nvme1n1p3 /mnt
btrfs subvolume create /mnt/@
btrfs subvolume create /mnt/@home
btrfs subvolume create /mnt/@snapshots
umount /mnt

BTRFS_OPTS="rw,noatime,ssd,compress=zstd:1,space_cache=v2"
mount -o subvol=@,$BTRFS_OPTS /dev/nvme1n1p3 /mnt
mkdir -p /mnt/{home,.snapshots,boot/EFI}
mount -o subvol=@home,$BTRFS_OPTS /dev/nvme1n1p3 /mnt/home
mount -o subvol=@snapshots,$BTRFS_OPTS /dev/nvme1n1p3 /mnt/.snapshots
mount /dev/nvme1n1p2 /mnt/boot
mount /dev/nvme1n1p1 /mnt/boot/EFI

Base install + fstab

pacstrap /mnt base base-devel linux linux-firmware intel-ucode \
  btrfs-progs grub efibootmgr dosfstools os-prober \
  networkmanager vim git sudo
genfstab -U /mnt >> /mnt/etc/fstab
arch-chroot /mnt

GRUB install + include Windows

# inside chroot:
mkdir -p /boot/WinESP
mount -o ro /dev/nvme0n1p1 /boot/WinESP
grub-install --target=x86_64-efi --efi-directory=/boot/EFI --bootloader-id=ARCH
sed -i 's/^#GRUB_DISABLE_OS_PROBER=.*/GRUB_DISABLE_OS_PROBER=false/' /etc/default/grub || \
  echo "GRUB_DISABLE_OS_PROBER=false" >> /etc/default/grub
grub-mkconfig -o /boot/grub/grub.cfg
umount /boot/WinESP

I hope you have a working Arch Linux system by now. Enjoy!


Ultimate Arch Linux Installation Guide (UEFI • Btrfs • ZRAM • KDE)

⚠️ IMPORTANT DISCLAIMER

This gist is meant for my personal use. I am sharing it publicly in case it may help others, but it is tailored specifically to my hardware and needs.

This guide was created with the aid of multiple AI models and is provided as-is. It was criticized and fixed by other AI models. Some edits were also made by a human. Still, I take no responsibility for anything that happens while following it.

This guide can be destructive if applied to the wrong device. Always double-check disk names with lsblk -f or blkid before running destructive commands.

Follow this guide at your own risk.


Target: Install Arch Linux on /dev/nvme1n1 (1 TB) and keep Windows intact on /dev/nvme0n1 (500 GB).

Key choices in this guide (opinionated, tested best-practices)

  • UEFI only, separate EFI System Partition on the Arch drive (/dev/nvme1n1p1).
  • Separate /boot partition (ext4, ~1 GiB) mounted at /boot.
  • Root filesystem: Btrfs with flat subvolume layout: @ (root), @home (home). Snapper will create .snapshots unless you manage snapshots manually.
  • Compression: compress=zstd:1 (good perf/space tradeoff for NVMe).
  • No swap partition — use zram (via zram-generator). Hibernation will not be available with this setup.
  • GRUB as the UEFI bootloader, with optional os-prober to detect Windows.
  • Snapshots with Snapper + optional grub-btrfs (AUR) to show snapshots in the GRUB menu. Timeshift is provided as an alternate desktop-friendly snapshot tool.
  • Desktop: KDE Plasma (Wayland) with SDDM (autologin disabled).
  • AMD GPU (RX 6650 XT): open amdgpu kernel driver + Mesa + Vulkan + 32-bit libs for Steam.
  • Audio: PipeWire + WirePlumber. Network: NetworkManager.
  • AUR helper: yay (install after first boot as user). Multilib enabled for Steam.

Table of Contents

  1. Quick plan
  2. Safety & essential checks
  3. Live environment preparation
  4. Partitioning /dev/nvme1n1 (DESTRUCTIVE)
  5. Format partitions
  6. Btrfs subvolumes & mounting (safe Snapper flow)
  7. Install base system (pacstrap)
  8. Generate fstab & chroot configuration
  9. GRUB (UEFI) installation & Windows detection
  10. Snapshots: Snapper (recommended) & grub-btrfs (AUR)
  11. ZRAM configuration (zram-generator)
  12. Optional: disable CoW for some directories
  13. KDE Plasma, audio & GPU stack
  14. Multilib & AUR (yay) — post-boot
  15. Enable services & housekeeping
  16. Finalize, reboot & post-install checks
  17. Updates, rollback & maintenance workflow
  18. Common pitfalls & troubleshooting
  19. Concise copy-paste checklist (read first)
  20. Further reading & references

Quick plan

  1. Verify live environment (UEFI, network, keyboard, clock).
  2. Partition /dev/nvme1n1 (EFI, /boot, Btrfs root)
  3. Format partitions, create @ and @home subvolumes
  4. Mount, pacstrap base system
  5. Chroot → locale, hostname, user, mkinitcpio -P
  6. Install GRUB on /boot/efi, optionally mount Windows ESP read-only to detect Windows
  7. Configure Snapper (or Timeshift), install grub-btrfs via AUR and enable its daemon
  8. Configure zram-generator and swappiness
  9. Install KDE Plasma, Mesa/Vulkan, PipeWire; enable system services
  10. Install AUR items (yay) as user anirudh after first login

Safety & essential checks

# Verify boot mode
cat /sys/firmware/efi/fw_platform_size
# If the above returns 64, then you're good to go

# Confirm device mapping carefully:
lsblk
# Or
blkid
# Or
fdisk

Important: Confirm Windows is /dev/nvme0n1 and the target drive is /dev/nvme1n1. If not, stop.


Live environment preparation

  • Boot the Arch Linux USB in UEFI mode.
  • Connect to the network (Ethernet preferred).
# keyboard
loadkeys in       # or: loadkeys us

# test connection
ping -c 3 archlinux.org

# enable network time
timedatectl set-ntp true

If you need Wi‑Fi, use iwctl (see man iwctl).


Partitioning /dev/nvme1n1 (DESTRUCTIVE)

WARNING: This will erase everything on /dev/nvme1n1. Double- and triple-check lsblk.

You can use gdisk (recommended for GPT) or cfdisk (interactive). Example gdisk flow:

gdisk /dev/nvme1n1
# inside gdisk:
# o      -> create new GPT
# n 1    -> default start, +550M, ef00 (EFI System)
# n 2    -> default start, +1G, 8300 (Linux filesystem)   # /boot
# n 3    -> default (rest), 8300                         # root
# p      -> verify
# w      -> write

Partition table (recommended):

  • /dev/nvme1n1p1 — EFI System Partition (≈550 MiB), FAT32 → mount /boot/efi
  • /dev/nvme1n1p2/boot (≈1 GiB), ext4 → mount /boot
  • /dev/nvme1n1p3 — root (remaining), Btrfs → subvolumes

Verify with:

lsblk -f /dev/nvme1n1

Format partitions

# EFI
mkfs.fat -F32 -n ARCH_ESP /dev/nvme1n1p1

# /boot
mkfs.ext4 -L ARCH_BOOT /dev/nvme1n1p2

# root (Btrfs)
mkfs.btrfs -f -L ARCH_ROOT /dev/nvme1n1p3

Btrfs subvolumes & mounting (safe Snapper flow)

Important Snapper note: Do not pre-create a @snapshots subvolume if you plan to run snapper -c root create-config /. Let Snapper create its .snapshots automatically for the simplest, safest flow. This section shows the recommended safe sequence.

  1. Create @ and @home only; let Snapper create .snapshots later.
mount /dev/nvme1n1p3 /mnt
btrfs subvolume create /mnt/@
btrfs subvolume create /mnt/@home
umount /mnt
  1. Mount with SSD-friendly options and subvolumes:
BTRFS_OPTS="rw,noatime,ssd,compress=zstd:1,space_cache=v2"

mount -o subvol=@,$BTRFS_OPTS /dev/nvme1n1p3 /mnt
mkdir -p /mnt/{home,boot,boot/efi}
mount -o subvol=@home,$BTRFS_OPTS /dev/nvme1n1p3 /mnt/home
mount /dev/nvme1n1p2 /mnt/boot
mount /dev/nvme1n1p1 /mnt/boot/efi

# verify
findmnt -R /mnt

Why these options? compress=zstd:1 is a low-cost compression that often improves IO on modern SSDs. noatime reduces writes. space_cache=v2 is the current recommended free-space caching.


Install base system (pacstrap)

IMPORTANT: AUR packages are not installed with pacstrap. Install AUR packages later as user anirudh with yay.

Update mirrorlist and install base packages:

pacman -Syy --noconfirm
pacman -S --noconfirm reflector
reflector --country India --age 12 --protocol https --sort rate --save /etc/pacman.d/mirrorlist

pacstrap -K /mnt \
  base base-devel linux linux-firmware intel-ucode \
  btrfs-progs grub efibootmgr inotify-tools \
  snapper zram-generator zstd reflector vim sudo \
  networkmanager network-manager-applet \
  pipewire pipewire-alsa pipewire-pulse wireplumber \
  bluez bluez-utils \
  git openssh man-db man-pages \
  wget curl \
  mesa vulkan-radeon libva-mesa-driver \
  linux-headers

Notes:

  • Replace intel-ucode with amd-ucode if you have an AMD CPU.
  • inotify-tools is useful for AUR tools like grub-btrfs.

Generate fstab & chroot configuration

genfstab -U /mnt >> /mnt/etc/fstab
sed -n '1,200p' /mnt/etc/fstab

Then chroot:

arch-chroot /mnt /bin/bash

Timezone, locale, keyboard

ln -sf /usr/share/zoneinfo/Asia/Kolkata /etc/localtime
hwclock --systohc

echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen
locale-gen
echo "LANG=en_US.UTF-8" > /etc/locale.conf

# console keymap
echo "KEYMAP=in" > /etc/vconsole.conf  # or 'us'

Hostname & hosts

echo "archpc" > /etc/hostname
cat > /etc/hosts <<EOF
127.0.0.1   localhost
::1         localhost
127.0.1.1   archpc.localdomain archpc
EOF

Root password & user

passwd                 # set root password
useradd -m -G wheel,audio,video,optical,storage -s /bin/bash anirudh
passwd anirudh

pacman -S --noconfirm sudo
EDITOR=vim visudo        # uncomment: %wheel ALL=(ALL:ALL) ALL

Rebuild initramfs

mkinitcpio -P

Enable system-level services

systemctl enable NetworkManager

Do not enable user-level systemctl --user units in chroot. Enable them after first login (instructions later).


GRUB (UEFI) installation & Windows detection

Ensure /boot/efi is mounted in chroot (we mounted earlier at /mnt/boot/efi).

Enable os-prober in grub defaults (script-safe):

grep -q "^GRUB_DISABLE_OS_PROBER=false" /etc/default/grub || \
  (sed -i 's/^#GRUB_DISABLE_OS_PROBER=.*/GRUB_DISABLE_OS_PROBER=false/' /etc/default/grub 2>/dev/null || \
   echo 'GRUB_DISABLE_OS_PROBER=false' >> /etc/default/grub)

Install GRUB to the Arch ESP (mounted at /boot/efi):

grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=ARCH
grub-mkconfig -o /boot/grub/grub.cfg

If Windows does not appear, temporarily mount Windows ESP read-only and regenerate GRUB:

mkdir -p /boot/WinESP
mount -o ro /dev/nvme0n1p1 /boot/WinESP   # adjust if Windows ESP is different
grub-mkconfig -o /boot/grub/grub.cfg
umount /boot/WinESP

Note: os-prober must be installed for detection to work. Install it before running grub-mkconfig.


Snapshots: Snapper (recommended) & grub-btrfs (AUR)

This guide recommends Snapper for snapshot management and optional grub-btrfs to list snapshots in GRUB.

Snapper (safe flow)

# create config for root — this will create .snapshots for you
snapper -c root create-config /

# edit /etc/snapper/configs/root to adjust retention
vim /etc/snapper/configs/root

# enable timers
systemctl enable --now snapper-timeline.timer snapper-cleanup.timer

Retention example (in /etc/snapper/configs/root):

TIMELINE_CREATE="yes"
TIMELINE_CLEANUP="yes"
TIMELINE_MIN_AGE="1800"
TIMELINE_LIMIT_HOURLY="24"
TIMELINE_LIMIT_DAILY="7"
TIMELINE_LIMIT_WEEKLY="4"
TIMELINE_LIMIT_MONTHLY="6"
NUMBER_LIMIT="50"
NUMBER_LIMIT_IMPORTANT="10"

grub-btrfs (AUR)

Install grub-btrfs with yay after first boot (post-install AUR step). Once installed, enable its daemon and regenerate GRUB:

# as user via yay:  yay -S grub-btrfs
sudo systemctl enable --now grub-btrfsd
sudo grub-mkconfig -o /boot/grub/grub.cfg

Do not enable grub-btrfsd before the package is installed — it will fail.

Alternative: Timeshift + timeshift-autosnap (AUR) is an easier GUI option for desktop users. Do not run Snapper and Timeshift against the same subvolumes without careful separation.


ZRAM configuration (zram-generator)

Package name: zram-generator (Arch package).

Create /etc/systemd/zram-generator.conf:

[zram0]
zram-size = min(ram / 2, 8192)
compression-algorithm = zstd
swap-priority = 100

Set swappiness (example conservative value):

echo "vm.swappiness=180" > /etc/sysctl.d/99-swappiness.conf

zram-generator creates zram-based swap at boot. Hibernation is not supported with zram-only setups.


Optional: disable CoW for specific directories

Btrfs CoW is useful, but for certain high-write directories (databases, logs, browser caches) you might want No-COW for performance. Example for /var/log (advanced):

# create a dedicated subvolume, mount it as /var/log and mark as NOCOW
btrfs subvolume create /@varlog
mkdir -p /var/log
# mount it temporarily and set NOCOW before adding content
mount -o subvol=@varlog,$BTRFS_OPTS /dev/nvme1n1p3 /mnt/varlog
chattr +C /mnt/varlog
# then copy logs back, update fstab and remount at /var/log

Caution: chattr +C must be applied to an empty directory. Incorrect use can lead to data loss. Proceed only if you understand the implications.


KDE Plasma, audio & GPU stack

Install KDE minimal (system-level):

pacman -S --noconfirm plasma-desktop plasma-wayland-session sddm konsole dolphin firefox
systemctl enable --now sddm

Xorg fallback:

pacman -S --noconfirm xorg-server xorg-apps xorg-xinit

Audio (PipeWire & WirePlumber) + Bluetooth:

pacman -S --noconfirm pipewire pipewire-pulse pipewire-alsa wireplumber pipewire-jack
pacman -S --noconfirm bluez bluez-utils
systemctl enable --now bluetooth.service

Enable user audio services after first login (as user anirudh):

systemctl --user enable --now pipewire pipewire-pulse wireplumber

AMD GPU (RX 6650 XT):

pacman -S --noconfirm mesa vulkan-radeon lib32-mesa lib32-vulkan-radeon libva-mesa-driver

Multilib & AUR (yay) — post-boot (as user anirudh)

Enable multilib in /etc/pacman.conf by uncommenting the [multilib] block and then:

pacman -Syy
pacman -S --needed base-devel git

# install yay as normal user
su - anirudh
git clone https://aur.archlinux.org/yay.git
cd yay
makepkg -si    # inspect PKGBUILD before running
cd ..
rm -rf yay
exit

Then use yay to install AUR packages like grub-btrfs, snap-pac, or timeshift-autosnap.

Security note: Always inspect AUR PKGBUILDs and sources before building.


Enable services & housekeeping

Enable system services (as root):

systemctl enable --now NetworkManager
systemctl enable --now systemd-timesyncd
systemctl enable --now fstrim.timer
systemctl enable --now snapper-timeline.timer snapper-cleanup.timer  # if using Snapper
pacman -S --noconfirm smartmontools fwupd
systemctl enable --now smartd
systemctl enable --now fwupd-refresh.timer

Set journald limits in /etc/systemd/journald.conf if desired:

SystemMaxUse=200M
SystemKeepFree=50M
SystemMaxFileSize=20M

Then systemctl restart systemd-journald.


Finalize, unmount & reboot

Important: verify everything before reboot.

# exit chroot
exit
# unmount everything
umount -R /mnt
reboot

Remove the USB when the system restarts.


Post-install verification & quick checks (first boot)

Log in as anirudh and run:

# zram
swapon --show
cat /sys/block/zram0/disksize

# btrfs usage
sudo btrfs filesystem df /

# GRUB and Windows
sudo grub-mkconfig -o /boot/grub/grub.cfg
grep -i windows /boot/grub/grub.cfg || echo "Windows not present in GRUB"

# GPU
glxinfo | grep "OpenGL renderer"

# Audio
pactl info
systemctl --user enable --now pipewire pipewire-pulse wireplumber

# Snapper
sudo snapper list

Create an initial snapshot:

sudo snapper -c root create -d "Initial setup complete"

Updates, rollback & maintenance workflow

Safe update:

sudo snapper -c root create -d "pre-update"
sudo pacman -Syu
# update AUR packages as user
yay -Syu

Rollback:

  • Boot a snapshot from the GRUB snapshots submenu.
  • To permanently rollback after confirming the snapshot works:
sudo snapper rollback
sudo grub-mkconfig -o /boot/grub/grub.cfg
sudo reboot

Cleanup:

sudo pacman -Rns $(pacman -Qtdq || true)
sudo paccache -rk2

Common pitfalls & troubleshooting

  • Wrong device selected: always verify lsblk before destructive commands.
  • Windows not in GRUB: mount Windows ESP read-only and re-run grub-mkconfig. Ensure os-prober is installed.
  • Snapper vs Timeshift: do not use both on the same subvolumes unless you separate responsibilities.
  • User services in chroot: enable user units only after first login.
  • Partial upgrades: never run partial upgrades (pacman -Sy package alone). Use pacman -Syu.
  • ZRAM & hibernation: zram-only setups do not support suspend-to-disk / hibernation.

Concise copy-paste checklist (read the guide first)

# 1) Confirm devices
lsblk -o NAME,FSTYPE,SIZE,MOUNTPOINT,LABEL

# 2) Partition /dev/nvme1n1 (gdisk/cfdisk)

# 3) Format
mkfs.fat -F32 -n ARCH_ESP /dev/nvme1n1p1
mkfs.ext4 -L ARCH_BOOT /dev/nvme1n1p2
mkfs.btrfs -f -L ARCH_ROOT /dev/nvme1n1p3

# 4) Create subvolumes & mount
mount /dev/nvme1n1p3 /mnt
btrfs subvolume create /mnt/@
btrfs subvolume create /mnt/@home
umount /mnt

BTRFS_OPTS="rw,noatime,ssd,compress=zstd:1,space_cache=v2"
mount -o subvol=@,$BTRFS_OPTS /dev/nvme1n1p3 /mnt
mkdir -p /mnt/{home,boot,boot/efi}
mount -o subvol=@home,$BTRFS_OPTS /dev/nvme1n1p3 /mnt/home
mount /dev/nvme1n1p2 /mnt/boot
mount /dev/nvme1n1p1 /mnt/boot/efi

# 5) pacstrap (no AUR)
pacstrap -K /mnt base base-devel linux linux-firmware intel-ucode btrfs-progs \
  grub efibootmgr inotify-tools snapper zram-generator zstd reflector vim sudo \
  networkmanager pipewire wireplumber mesa vulkan-radeon linux-headers

# 6) fstab and chroot
genfstab -U /mnt >> /mnt/etc/fstab
arch-chroot /mnt
# ...finish chroot steps from guide...

Further reading & references

  • ArchWiki: Installation guide, Btrfs, Snapper, Zram, GRUB, KDE, PipeWire (search archwiki for authoritative pages).

End of guide. I hope you now have a fully working Arch Linux system! Good luck for you Arch journey!

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