about | arch-pi | arch-usb | mirror symmetry | valleycat | vim | ramroot
2022-05-11
Chris Magyar

   _          _    _    _                _   _ ___ ___
  /_\  _ _ __| |_ | |  (_)_ _ _  ___ __ | | | / __| _ )
 / _ \| '_/ _| ' \| |__| | ' \ || \ \ / | |_| \__ \ _ \
/_/ \_\_| \__|_||_|____|_|_||_\_,_/_\_\  \___/|___/___/
This page explains how to install Arch Linux on a USB flash drive. The end result is a persistent installation identical to that on a normal hard drive along with several performance optimizations aimed at running Linux on removable flash media.
The only packages explicitly installed besides linux, linux-firmware, and base are:
Basic services, such as networking and time sync, are all handled by systemd.

Prepare USB Stick

This bootable Linux USB stick will be compatible with both BIOS and UEFI booting modes. In order for a storage device to boot in BIOS mode, the first 512 bytes of the device's memory must contain an MBR (master boot record). For a storage device to boot in UEFI mode, a special EFI system partion is required. Both partitions can be created using gdisk.
Before proceeding, determine the device name of the target USB drive. View the currently available block devices before inserting the USB:
# lsblk
Now insert the target flash drive and view the devices again. The newly detected device /dev/sdX is the name of the target USB you will use for further partitioning and formatting. Note that in the device name you will use is literally /dev/sdX where the only thing that changes is the single lowercase letter value of X. Double check that you have the correct device name /dev/sdX, lest you may repartition the internal hard drive of the machine you are on!

wipe

The process of zeroing out or wiping the target USB is almost always optional. Overwriting the USB with zeros may be needed in rare cases when previous data aligns with the newly created partition table. If you have trouble installing a bootloader further on in the installation, you may have to come back to this point and wipe your USB before continuing.
Use dd to write the USB with all zeros, permanently erasing all data:
# dd if=/dev/zero of=/dev/sdX status=progress

Expect this to take a relatively long time (hour+) depending on the size of the USB.

partition

Use sgdisk to create a 10M BIOS partition, a 500M EFI partition, and allocate the rest of the USB to a Linux partition:
# sgdisk -o -n 1:0:+10M -t 1:EF02 -n 2:0:+500M -t 2:EF00 -n 3:0:0 -t 3:8300 /dev/sdX

format

View the new block layout of the target USB device:
# lsblk /dev/sdX
NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINTS
sdX      8:112  1 14.5G  0 disk
├─sdX1   8:113  1   10M  0 part
├─sdX2   8:114  1  500M  0 part
└─sdX3   8:115  1   14G  0 part

You should now have three blocks on your target USB device: a 10MB block /dev/sdX1, a 500MB block /dev/sdX2, and a block for all the remaining memory /dev/sdX3.
Do not format the /dev/sdX1 block. This is the BIOS/MBR partion.
Format the 500MB EFI system partition with a FAT32 filesystem:
# mkfs.fat -F32 /dev/sdX2
Format the Linux partition with an ext4 filesystem:
# mkfs.ext4 /dev/sdX3

Install Base Package Set

Following the Arch Way, this guide intends to install the minimum number of packages necessary to create a portable working Linux system.

mount

Mount the ext4 formatted partition as the root filesystem:
# mkdir -p /mnt/usb
# mount /dev/sdX3 /mnt/usb
Mount the FAT32 formatted EFI partition to boot:
# mkdir /mnt/usb/boot
# mount /dev/sdX2 /mnt/usb/boot

pacstrap

Download and install the Arch Linux base packages:
# pacstrap /mnt/usb linux linux-firmware base vim

fstab

Generate a new fstab using UUIDs as source identifiers:
# genfstab -U /mnt/usb > /mnt/usb/etc/fstab

Configure New System

Several additional packages will be installed to support wifi interfaces, battery systems, and sudo users.

chroot

All configuration can be performed within a chroot environment.
Begin by chrooting into the new system:
# arch-chroot /mnt/usb
Inside a chroot the names of block devices may differ from the host system. View the block device list and note the new name of the USB device /dev/sdY:
# lsblk

locale

Use tab-completion to discover the appropriate entries for region and city:
# ln -sf /usr/share/zoneinfo/region/city /etc/localtime
Generate /etc/adjtime:
# hwclock --systohc
Edit /etc/locale.gen and uncomment your desired language (for US English, uncomment en_US.UTF-8 UTF-8):
# vim /etc/locale.gen
Generate the locale information:
# locale-gen
Set the LANG variable in /etc/locale.conf (for US English, localeline is en_US.UTF-8):
# echo LANG=localeline > /etc/locale.conf

hostname

Create the /etc/hostname file containing your desired valid hostname on a single line:
# echo hostname > /etc/hostname
Edit /etc/hosts to contain only the following content:
# vim /etc/hosts
127.0.0.1    localhost
::1          localhost
127.0.1.1    hostname.localdomain    hostname

mount options

To prevent excess writes to the USB and improve system performance, use the noatime mount option in fstab. Open /etc/fstab in an editor and change each relatime or atime option to noatime:
# vim /etc/fstab
# /dev/sdY3
UUID=uuid1  /      ext4  rw,noatime     0 1

# /dev/sdY2
UUID=uuid2  /boot  vfat  rw,noatime,... 0 2

journal config

To prevent the systemd journal service from writing to the USB, change the storage settings in journald.conf. Edit a drop-in file to contain the following content:
# mkdir -p /etc/systemd/journald.conf.d
# vim /etc/systemd/journald.conf.d/10-volatile.conf
[Journal]
Storage=volatile
SystemMaxUse=16M
RuntimeMaxUse=32M

bootloader

The GRUB bootloader along with efibootmgr will enable the USB to boot in both BIOS and UEFI boot modes.
Install the grub and efibootmgr packages:
# pacman -S grub efibootmgr
Install GRUB for MBR/BIOS booting mode:
# grub-install --target=i386-pc --boot-directory /boot --removable /dev/sdY
Install GRUB for UEFI booting mode:
# grub-install --target=x86_64-efi --efi-directory /boot --boot-directory /boot --removable
Generate a GRUB configuration:
# grub-mkconfig -o /boot/grub/grub.cfg

network interface names

To ensure that the main ethernet and wifi interfaces will always be named eth0 and wlan0, revert to traditional device naming:
# ln -s /dev/null /etc/udev/rules.d/80-net-setup-link.rules

networking

Create a new systemd-networkd configuration file with the following content to automatically establish wired network connections:
# vim /etc/systemd/network/20-ethernet.network
[Match]
Name=en*
Name=eth*

[Network]
DHCP=yes
IPv6PrivacyExtensions=yes

[DHCPv4]
RouteMetric=100

[IPv6AcceptRA]
RouteMetric=100
Enable networkd and resolved:
# systemctl enable systemd-networkd.service
# systemctl enable systemd-resolved.service
Install and enable iwd to allow user control over wireless interfaces:
# pacman -S iwd
# systemctl enable iwd.service
Copy the wired network configuration file and edit it to the following to handle wifi interfaces:
# cp /etc/systemd/network/20-ethernet.network /etc/systemd/network/20-wlan.network
# vim /etc/systemd/network/20-wlan.network
[Match]
Name=wl*

[Network]
DHCP=yes
IPv6PrivacyExtensions=yes

[DHCPv4]
RouteMetric=600

[IPv6AcceptRA]
RouteMetric=600
Enable network time synchronization:
# systemctl enable systemd-timesyncd.service

battery support

Install support for checking battery charge and state:
# pacman -S acpi

root password

Set the root password:
# passwd

user account

Create a new user account and set its password:
# useradd -m user
# passwd user

sudo

Install sudo:
# pacman -S sudo
Enable sudo for the sudo group by creating a new rule in /etc/sudoers.d/:
# EDITOR=vim visudo /etc/sudoers.d/10-sudo
%sudo ALL=(ALL) ALL
Ensure the sudo group exists and that user is a member of it:
# groupadd sudo
# usermod -aG sudo user
Install polkit to allow various commands (reboot and shutdown, among others) to be run by non-root users:
# pacman -S polkit

logout

Logout of the chroot:
# exit
Unmount the USB:
# umount /mnt/usb/boot /mnt/usb && sync

Installation Complete!

Welcome to Arch Linux! First time users should probably checkout the ArchWiki's general recommendations.