Install the base system

The disk is partitioned, formatted and mounted under /mnt, and there is nothing on it. This chapter puts a complete Arch system there.

It will not boot yet – nothing has been told how to load a kernel, which is the next chapter – but by the end of this one you can chroot into the new system and work inside it as though it were running.

Unless a block says otherwise, every command in this chapter runs as root on the live system, over SSH.

What pacstrap actually is

pacstrap is pacman pointed at a different root. It installs packages into /mnt rather than /, sets up a pacman keyring inside the target, and copies the live system’s mirrorlist across so the new system starts out with working package sources.

There is no image, no installer and no magic. When it finishes, /mnt contains an ordinary directory tree that happens to be a Linux system.

Choosing what to install

The base package is the floor, and it is lower than people expect: glibc, bash, coreutils, pacman, systemd, and little else. It has no kernel, no editor, no bootloader and no SSH server. Everything the machine needs beyond that is an explicit choice, which is the part of Arch worth leaning into.

Package Why it is here
base The minimum system: glibc, bash, coreutils, pacman, systemd
linux / linux-rpi-16k A kernel, which base does not include
linux-firmware Firmware blobs for WiFi, GPUs and other devices
firmware-raspberrypi Pi only: VideoCore firmware and the files its bootloader reads
btrfs-progs Required – the root filesystem is btrfs and cannot be checked without it
cryptsetup Only if you encrypted the disk
sudo Administration from your own account
openssh The whole point of a headless machine
iwd WiFi, configured in a later chapter
vim An editor that exists inside the chroot
intel-ucode / amd-ucode x86_64 only: CPU microcode errata fixes, loaded at boot
Do not leave out openssh

You are installing a machine you reach over the network. If openssh is missing when you reboot, a headless box simply never comes back, and recovering it means walking over with a monitor and keyboard – the exact chore this whole book exists to avoid.

The same goes for iwd on a machine that has no ethernet.

Set the package list

The live system is running on the machine you are installing, so it can simply look at the hardware and decide for itself. Run this once, whatever you are installing on:

[zsh]: Set env vars
PKGS=(base btrfs-progs cryptsetup sudo openssh iwd vim)

case "$(uname -m)" in
  x86_64)
    PKGS+=(linux linux-firmware)
    case "$(grep -m1 '^vendor_id' /proc/cpuinfo)" in   # CPU microcode
      *GenuineIntel*) PKGS+=(intel-ucode) ;;
      *AuthenticAMD*) PKGS+=(amd-ucode)   ;;
    esac ;;
  aarch64)
    if grep -qa bcm2712 /proc/device-tree/compatible 2>/dev/null; then
      PKGS+=(linux-rpi-16k firmware-raspberrypi linux-firmware)
    else
      echo "Unrecognised aarch64 board: pick a kernel yourself" >&2
    fi ;;
esac
Why an array

The live system’s shell is zsh, not bash – that is upstream archiso, not something BOOMSTICK chose, so it is equally true of the official ISO. zsh does not split an unquoted $PKGS into separate words the way bash does, so a plain string would arrive at pacstrap as one enormous package name. An array expanded as "${PKGS[@]}" behaves identically in both shells.

What it decided, and why

  • The kernel follows uname -m. There is no single linux package that covers both.
  • Microcode is read from /proc/cpuinfo. Intel and AMD ship errata fixes that the bootloader loads before the kernel starts, and the two are different packages. Any other x86_64 vendor gets none, which is correct – there is nothing to install.
  • The Pi kernel is chosen by SoC rather than by model name. The test looks for bcm2712 in the device tree, which is exactly what linux-rpi-16k supports, and so it covers the Pi 5, the Pi 500 and the CM5 alike. An aarch64 board that is none of those says so instead of installing a kernel that cannot boot it.
  • cryptsetup is included unconditionally. You only need it if you encrypted the disk, but it costs a couple of megabytes and forgetting it on an encrypted system is a far worse afternoon than carrying it on an unencrypted one.

Check what it picked before installing it:

Run this on the live system:
echo "${PKGS[@]}"
(stdout)
base btrfs-progs cryptsetup sudo openssh iwd vim linux-rpi-16k firmware-raspberrypi linux-firmware

That output is from a Raspberry Pi. On an Intel PC the tail reads linux linux-firmware intel-ucode instead.

// settings
theme:
fx: