I started my Linux journey with Arch Linux about five years ago (Technically, I used Ubuntu 9.10 way back when, but that's a story for another day). As a newbie, installing Arch by hand was a pretty big deal for me. It taught me almost everything about Linux and open source software in general.
Overtime, I moved on from Arch to Debian/Ubuntu/Fedora, but I always keep a technical note on how to install Arch Linux. What drives me to revisit this topic? Well, because I decided to put Linux on an old MacBook Pro with Intel CPU. I can think of no better distro than Arch Linux: it is flexible, lightweight, and... did I mention it's Arch, btw?
This article focuses on installing Arch Linux base system on a laptop or desktop with a single hard drive, and with UEFI support. It uses one of three partition/firesystem schemes and one of two boot loaders (GRUB or systemd-boot). The scenarios are:
- LVM with ext4: no encryption
- LVM on LUKS: offers root partition encryption
- Btrfs on LUKS: above, and btrfs
Encrypted EFI system partition with Unified Kernel Image
The purpose is to dual boot Arch Linux with MacOS, so encrypted EFI partition is out of the question here. I might write another article in the future about Unified Kernel Image.
When researching and refining my notes, I came across YouTube channel EF linux. He was such a great guy, concise and straight to the point. I also recommend his video about btrfs snapshot with timeshift.
So, without further ado, let me present my raw notes of installing Arch Linux in (late) 2023.
Live system stage
Preparation
wireless network config
Wi-Fi: iwctl
(authenticates to Wi-Fi) or wifi-menu
(netctl)
Ethernet: ArchISO's systemd-networkd and systemd-resolved should work out of the box
SSH remote install:
passwd
to set root password
systemctl start sshd.service
ip addr
to get IP address
Optional:
setfont ter-132b
set larger font for HiDPI
timedatectl set-ntp true
to ensure the system clock is accurate
ls /sys/firmware/efi/efivars
verify boot mode (BIOS or UEFI)
cat /sys/firmware/efi/fw_platform_size
another way to verify (64 or 32)
Partitioning
https://wiki.archlinux.org/title/Partitioning
https://wiki.archlinux.org/title/EFI_system_partition
https://wiki.archlinux.org/title/Btrfs
https://wiki.archlinux.org/title/Install_Arch_Linux_on_LVM
https://wiki.archlinux.org/title/Dm-crypt/Encrypting_an_entire_system
Boot partition
Partition the disk: create ESP (EFI system partition) and "Linux root" partition
cfdisk
is TUI of fdisk
fdisk -l
check existing disks/partitions
fdisk /dev/sd[X]
Format and mount:
mkfs.fat -F 32 /dev/sda1
format ESP to FAT32
mkdir -p /mnt/boot
mount /dev/sda1 /mnt/boot
Notes on ESP mount point:
/boot
: cannot be encrypted; contains kernels, initramfs images, microcode, boot loader config files; supports dual boot with Windows/MacOS/efi
(historically/boot/efi
): only boot loader config files
Mount point | Partition | Partition type | GUID | Size |
---|---|---|---|---|
/boot or /efi | /dev/sda1 | EFI system partition | C12A7328-F81F-11D2-BA4B-00A0C93EC93B | 300MB to 1GB |
/ | /dev/sda2 | Linux root | 4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709 | remainder |
1. LVM
LVM with ext4 (no LUKS encryption), see Install Arch on LVM
- create pv, vg and lv on /dev/sda2 (if lv will be formatted with ext4, leave 256 MiB space for e2scrub; see next section on how to)
- format
mkfs.ext4 /dev/VolGroup/root
- mount
mount /dev/VolGroup/root /mnt
- note: swap and home logic volumes are optional
2. LVM on LUKS
- LUKS2
cryptsetup luksFormat /dev/sda2 cryptsetup open /dev/sda2 cryptroot
- LVM
pvcreate /dev/mapper/cryptroot pvdisplay/pvscan vgcreate VolGroup /dev/mapper/cryptroot lvcreate -L 100%FREE VolGroup -n root lvreduce -L -256M VolGroup/root ### if ext4, leave 256 MiB space for e2scrub
- format and mount
mkfs.ext4 /dev/VolGroup/root mount /dev/VolGroup/root /mnt
3. Btrfs on LUKS
- LUKS2
cryptsetup luksFormat /dev/sda2 cryptsetup open /dev/sda2 cryptroot
- Btrfs
mkfs.btrfs -L archlinux /dev/mapper/cryptroot mount /dev/mapper/cryptroot /mnt cd /mnt btrfs subvolume create @ ## or root btrfs subvolume create @home ## or home cd umount /mnt mkdir /mnt/home mount -o subvol=@,compress=zstd /dev/mapper/cryptroot /mnt mount -o subvol=@home,compress=zstd /dev/mapper/cryptroot /mnt/home
Install base system
(optionally) edit mirrors /etc/pacman.d/mirrorlist
pacstrap -K /mnt base linux linux-firmware amd/intel-ucode sudo lvm2 btrfs-progs nano
optionally networkmanager
- Kernels can be
linux-lts
orlinux-zen
- skip
linux-firmware
if it's a VM
FSTAB
genfstab -U /mnt >> /mnt/etc/fstab
use -U or -L to define by UUID or labels, respectively
cat /mnt/etc/fstab
to verify
Chroot stage
arch-chroot /mnt
Initramfs (mkinitcpio)
Workflow:
edit hooks in/etc/mkinitcpio.conf
re-generate mkinitcpio -P
See also:
mkinitcpio common hooks
kernel parameters
1. LVM
lvm2
package must be installed in the arch-chroot environment
"udev" and "lvm2" for busybox-based initramfs: HOOKS=(base udev ... block lvm2 filesystems)
"systemd" and "lvm2" for systemd-based initramfs: HOOKS=(base systemd ... block lvm2 filesystems)
2. LVM on LUKS
lvm2
package must be installed in the arch-chroot environment
"keyboard", "encrypt" and "lvm" for busybox-based initramfs: HOOKS=(base udev autodetect modconf kms keyboard keymap consolefont block encrypt lvm2 filesystems fsck)
"keyboard", "sd-encrypt" and "lvm" for systemd-based initramfs: HOOKS=(base systemd autodetect modconf kms keyboard sd-vconsole block sd-encrypt lvm2 filesystems fsck)
3. Btrfs on LUKS
btrfs-progs
package must be installed in the arch-chroot environment
"keyboard" and "encrypt" for busybox-based initramfs
"keyboard" and "sd-encrypt" for systemd-based initramfs
For single device btrfs pool, "filesystem" hook is sufficient (no need for "btrfs" hook)
For multi device btrfs pool, use one of "udev", "systemd" or "btrfs" hooks. See common hooks
Additionally, edit /etc/fstab
to add mount options: (get UUID by lsblk -f
or blkid
)
UUID=XXX / btrfs subvol=@,compress=zstd:9,discard=async,noatime,ssd
UUID=YYY /home btrfs subvol=@home,compress=zstd:9,discard=async,noatime,ssd
Boot loader
Installation:
- systemd-boot is shipped with the
systemd
package which is a dependency of thebase
meta package - GRUB
pacman -S grub efibootmgr
- rEFInd:
pacman -S refind-efi efibootmgr
Kernel parameters references:
1. LVM
Choose any boot loader
Kernel parameter root=/dev/VolGroup/root
2. LVM on LUKS
Grub install (assuming esp is /boot)
grub-install --target=x86_64-efi --efi-directory=/boot --bootloader-id=GRUB
grub-mkconfig -o /boot/grub/grub.cfg
(Optional) fallback boot path:
either use --removable
flag
or mkdir *esp*/EFI/BOOT
and cp *esp*/EFI/GRUB/grubx64.efi *esp*/EFI/BOOT/BOOTX64.EFI
Kernel parameters: https://wiki.archlinux.org/title/Dm-crypt/Encrypting_an_entire_system#Configuring_the_boot_loader_2
Get UUID by lsblk -f
or blkid
Unlock encrypted root partition at boot: (get device-UUID refers to LUKS pratition /dev/sda2)
For encrypt
hook: cryptdevice=UUID=<device-UUID>:cryptroot:allow-discards root=/dev/VolGroup/root
For sd-encrypt
hook: rd.luks.name=<device-UUID>=cryptroot rd.luks.options=discard root=/dev/VolGroup/root
3. Btrfs on LUKS
Install systemd-boot: bootctl install
optionally set --esp-path=/custom/esp
Automatic update: enable systemd-boot-update.service
and/or add pacman hook
Configure nano /boot/loader/loader.conf
# default name must match filename /boot/loader/entries/arch.conf
default arch
timeout 3
console-mode max
# console-mode auto/keep
# editor no
Add loaders nano /boot/loader/entries/arch.conf
add -lts
for LTS kernel
title Arch Linux
linux /vmlinuz-linux
initrd /intel-ucode.img
# initrd /amd-ucode.img
initrd /initramfs-linux.img
# kernel parameters for btrfs on LUKS ("encrypt" hook), where XXX is /dev/sdb2, YYY is /dev/mapper/cryptroot
options cryptdevice=UUID=XXX:cryptroot:allow-discards root=/dev/mapper/VolGroup-root rw quiet splash
# kernel parameters for btrfs on LUKS ("sd-encrypt" hook), where XXX is /dev/sdb2, YYY is /dev/mapper/cryptroot
options rd.luks.name=XXX=cryptroot rd.luks.options=discard root=UUID=YYY rootflags=subvol=@ rw quiet splash
Note:
- Fedora GRUB only has "rd.luks.name=", no "root=" nor "rootflags="; but Arch has to have these
- Either set "rootflags=" here or
btrfs subvolume set-default <subvolume-id> /
Fallback nano /boot/loader/entries/arch-fallback.conf
; add -lts
for LTS kernel
title Arch Linux (fallback initramfs)
...
initrd /initramfs-linux-fallback.img
...
Time zone
From here on is easy, just follow Installation Guide
ln -sf /usr/share/zoneinfo/Canada/Toronto /etc/localtime
to set timezone
hwclock -w -u
to set time
Localization
nano /etc/locale.gen
uncomment en_CA.UTF-8
and other needed locales
or
echo "en_CA.UTF-8 UTF-8" >> /etc/locale.gen
lastly
locale-gen
to generate locale
nano /etc/locale.conf
to set the LANG
variable: LANG=en_US.UTF-8
or
optionally locale > /etc/locale.conf
Network configuration
echo MYHOSTNAME > /etc/hostname
nano /etc/hosts
127.0.0.1 localhost
::1 localhost
127.0.1.1 MYHOSTNAME.localdomain MYHOSTNAME
either systemctl enable systemd-networkd.service systemd-resolved.service
and follow some example configurations
or pacman -S networkmanager
+ systemctl enable NetworkManager
User and password
We want passwordless rootpasswd
for root
ensure sudo
package is installed
useradd -m -G wheel -s /bin/bash your_user
passwd your_user
EDITOR=nano visudo
uncomment %wheel All=(All) All
Reboot
exit
to exit chroot
umount -R /mnt
optional but safe
reboot now
Post-install
Useful topics
systemd-boot: enable systemd-boot-update.service
and/or add pacman hook
zram: replaces swap file or swap partition
Hibernation: (swap partition)
For "encrypt" hook: resume=/dev/VolGroup/swap (same format as root parameter)
systemd-boot ("sd-encrypt" hook): does not require additional kernel parameter with systemd >= v255
Snapper does not have command line tool; but has GRUB and rEFInd integration
Timeshift has a GUI as well as a command line tool