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 optimizations aimed at running Linux on removable flash media. It is compatible with both BIOS and UEFI booting modes.
The only packages explicitly installed are linux, linux-firmware, base, efibootmgr, grub, iwd, polkit, sudo, and vim. Basic services are handled by systemd.
Install Base System
Determine the target USB device name:
For the remainder of this guide, the device name will be referred to as /dev/sdX.
wipe (optional)
Use dd to write the USB with all zeros, permanently erasing all data:
Expect this to take a relatively long time (hour+) depending on the size of the USB.
partition
Create a 10M BIOS partition, a 500M EFI partition, and a Linux partition with the remaining space:format
Do not format the /dev/sdX1 block. This is the BIOS/MBR parition.
Format the 500MB EFI system partition with a FAT32 filesystem:
Format the Linux partition with an ext4 filesystem:
mount
Mount the ext4 formatted partition as the root filesystem:
# mount /dev/sdX3 /mnt/usb
Mount the FAT32 formatted EFI partition to /boot:
# mount /dev/sdX2 /mnt/usb/boot
pacstrap
Download and install the Arch Linux base packages:
fstab
Generate a new /etc/fstab using UUIDs as source identifiers:
Configure Base System
Unless otherwise noted, all configuration is done within a chroot. Chroot into the new system:
Exit the chroot environment when finished by typing exit.
locale
Use tab-completion to discover the appropriate entries for region and city:
Edit /etc/locale.gen and uncomment the desired language (for US English, uncomment en_US.UTF-8 UTF-8):
Generate the locale information:
Set the LANG variable in /etc/locale.conf (for US English, localeline is en_US.UTF-8):
time/date
Generate /etc/adjtime:
hostname
Create a /etc/hostname file containing the desired hostname on a single line:
Edit /etc/hosts to contain only the following content:
127.0.0.1 localhost ::1 localhost 127.0.1.1 hostname.localdomain hostname
password
Set the root password:
bootloader
Install grub and efibootmgr:
Install GRUB for both BIOS and UEFI booting modes:
# grub-install --target=x86_64-efi --efi-directory /boot --recheck --removable
Generate a GRUB configuration:
networking
Create a networkd configuration file with the following content to automatically establish wired connections:
[Match] Name=en* Name=eth* [Network] DHCP=yes IPv6PrivacyExtensions=yes [DHCPv4] RouteMetric=100 [IPv6AcceptRA] RouteMetric=100
Enable networkd:
Install and enable iwd to allow user control over wireless interfaces:
# systemctl enable iwd.service
Create a networkd configuration file with the following content for wireless connections:
[Match] Name=wl* [Network] DHCP=yes IPv6PrivacyExtensions=yes [DHCPv4] RouteMetric=200 [IPv6AcceptRA] RouteMetric=200
Enable resolved:
NOTE: this command must be done outside of the chroot environment. Create link to /run/systmed/resolve/stub-resolv.conf:
Enable timesyncd:
user
Create a new user account and set its password:
# passwd user
Ensure the wheel group exists and add user to it:
# usermod -aG wheel user
sudo
Install sudo:
Enable sudo for the sudo group by creating a rule in /etc/sudoers.d/:
%sudo ALL=(ALL) ALL
Ensure the sudo group exists and add user to it:
# usermod -aG sudo user
Install polkit to allow various commands (reboot and shutdown, among others) to be run by non-root users:
noatime (optional)
Decrease excess writes to the USB by discarding file access times. Change each relatime or atime option to noatime in /etc/fstab:
# /dev/sdX3 UUID=uuid1 / ext4 rw,noatime 0 1 # /dev/sdX2 UUID=uuid2 /boot vfat rw,noatime,... 0 2
journal (optional)
Prevent the systemd journal service from writing to the USB by configuring it to use RAM. Create a drop-in config file with the following content:
# vim /etc/systemd/journald.conf.d/10-volatile.conf
[Journal] Storage=volatile SystemMaxUse=16M RuntimeMaxUse=32M
mkinitcpio (optional)
Ensure all modules are always included in the initcpio image. Remove the autodetect hook from the default options in /etc/mkinitcpio.d/linux.preset and disable fallback (fallback is now default):
ALL_kver='/boot/vmlinuz-linux' PRESETS=('default') default_image='/boot/initramfs-linux.img' default_options='-S autodetect'
Remove the existing fallback image:
Generate a new initcpio image:
nomodeset (optional)
Create a GRUB menu item with the nomodeset kernel parameter. Copy the default menuentry from /boot/grub/grub.cfg into /etc/grub.d/40_custom and add the nomodeset kernel parameter:
... menuentry 'Arch Linux ... [nomodeset]' ... ... linux /vmlinuz-linux ... nomodeset ...
Generate a new GRUB configuration:
microcode (optional)
Enable microcode updates. Install amd-ucode and intel-ucode:
Add ucode image files to any desired custom entries in /etc/grub.d/40_custom:
... menuentry 'Arch Linux ...' ... ... initrd /boot/amd-ucode.img /boot/intel-ucode.img ... ...
Generate a new GRUB configuration:
dns over tls (optional)
Enable DNS over TLS. Create /etc/systemd/resolved.conf.d/10-dns-tls.conf:
[Resolve] DNS=1.1.1.1#cloudflare-dns.com FallbackDNS=9.9.9.9#dns.quad9.net 8.8.8.8#dns.google DNSOverTLS=opportunistic
interface names (optional)
Ensure that ethernet and wifi interfaces are always named eth* and wlan*. Revert to traditional device naming: