Arch Linux UEFI base install

Arch Linux is a hugely popular Linux distribution. It’s based on the rolling release philosophy. No major version updates and rarely ever will any of your packages be outdated by more then a few days. It’s greatly customizable and comes with a formidable selection of official packages and community maintained packages in the Arch User Repository.

It does not come with an installer like many other Linux distributions. This makes Arch appear much less friendly to potential new users. It’s all part of the learning curve and looks a lot scarier then it really is. The official installation guide is an excellent starting point.

In this article I share my usual Arch Linux installation procedure on UEFI systems. It’s the first of three articles documenting my complete setup from bare metal to Plasma/KDE desktop. I used this approach multiple times to install Arch on Laptops, Desktops and VMs and ended up with solid and practical systems I use on daily basis.

Preparing the install medium

If you haven’t done so already, download the Arch Linux iso. I recommend using Bittorent. It’s usually the fastest way to download the image and reduces the stress on the various HTTP/FTP mirrors.

The Arch Linux Wiki provides a long-winded article on how to create a bootable USB stick covering almost all options. Refer to this article if you’re not on a Linux or UNIX system or can’t use the command below for some reason.

On Linux or Unix you’ll find the dd command. I’m using it to burn the iso to a USB stick:

sudo dd bs=4M if=/path/to/archlinux.iso of=/dev/sdx status=progress oflag=sync

Post-Boot

Once you’re booting from your freshly minted Arch Linux USB stick you’ll find yourself in a terminal environment. No installer, no instructions, just a command line and root access.

At this point I usually enable SSH access and continue the installation from another computer. This makes copy & pasting commands possible. This step is completely optional.

# Set root password
passwd

# Start SSH
systemctl start sshd

Use ip a to list your network connection if you don’t know your IP.

If you don’t have a working internet connection, check out the “Connect to the Internet” section of the installation guide. If you’re limited to WiFi, check out the wireless guide

Lastly I’m enabling NTP to make sure the system time is accurate:

# Enable NTP
timedatectl set-ntp true

Disk preparation

Disclaimer: I’m not very knowledgeable about UEFI simply because I don’t really care about it. All I know is that installing an OS on computers with it is more challenging then it used to be. Feel free to suggest changes to my way of doing it.

Consider the following examples as just that. Examples. A lot depends on your hardware and your preferred partition layout. So use these instructions as a guide to come up with your own set of commands.

Of course /dev/sda is just an example value. Your disk might be called something like /dev/nvme0n1. List your installed disks with fdisk -l to find out.

export SYSTEM_DEV=/dev/sda
export EFI_PART=${SYSTEM_DEV}1
export ROOT_PART=${SYSTEM_DEV}2

echo System Disk: $SYSTEM_DEV 
echo EFI Partition: $EFI_PART 
echo Root Partition: $ROOT_PART

# Destroy partition table, etc.
dd bs=4M count=20 if=/dev/urandom of=$SYSTEM_DEV

# Start `cfdisk` for easy partitioning
cfdisk $SYSTEM_DEV

I’m using cfdisk to set up the actual partitions. There are many other ways, but I find cfdisk to be hazle free and simple to use. Create the partitions as described in the table below or in whatever way you intend to layout your partitions.

When asked about the partition type choose gpt.

Size Type
300M EFI System
remaining Linux filesystem

Finally format and mount:

mkfs.fat -F32 $EFI_PART
mkfs.ext4 $ROOT_PART
mount $ROOT_PART /mnt

Installing Arch Linux

Finally we’re ready to run the installation. This comes down to essentially two lines:

pacstrap /mnt base base-devel
genfstab -U -p /mnt >> /mnt/etc/fstab

Installing the base-devel collection will enable you to use AUR packages later on. Some of these need to be compiled from source and you’ll also need the makepkg command as well as some other commonly used ones. You can skip them for now if you like and install them later on using pacman -S base-devel.

Configure YOUR Arch Linux

What happens next is a bit mystifying to new users. Your Arch Linux Root has been prepared, but of course it doesn’t run just yet. Instead we’ll use chroot to jump into it from the live boot environment using it’s kernel and everything. Think of this as life support for your not quite ready Arch installation.

Tip: You can repeat the chroot step at any time. This is very helpful if you have trouble booting into your system and need to perform repairs from within the system.

## Enter Arch Installation
arch-chroot /mnt

Set the root password right away, that way you won’t forget later on (happened multiple times to me ;) ):

passwd root

After this point you’re working within your actual Arch installation. Any change you make is permanent.

Remember: Change values as needed for YOUR setup.

Let’s start with some time zone and locale settings:

## Timezone
rm /etc/localtime
ln -sf /usr/share/zoneinfo/Asia/Tbilsi /etc/localtime
hwclock --systohc --utc

## Set locale
sed -i 's/#en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen
locale-gen
echo LANG=en_US.UTF-8 > /etc/locale.conf

Preparing the host name:

echo "ENTER_YOUR_HOSTNAME_HERE" > /etc/hostname
echo 127.0.0.1  localhost > /etc/hosts
echo ::1    localhost >> /etc/hosts
echo 127.0.1.1  ENTER_YOUR_FQDN_HERE ENTER_YOUR_HOSTNAME_HERE >> /etc/hosts

Here I like to make sure I’m completely up to date running the package updater:

pacman -Syu

Additional tools I like to have installed early:

pacman -S ntp sudo openssh bash-completion
systemctl enable ntpd sshd

Networking with NetworkManager

I’m usually using NetworkManager, especially on mobile computers which change networks a lot. A great alternative is using systemd-networkd.

pacman -S networkmanager networkmanager-openvpn openvpn
systemctl enable NetworkManager

Another completely optional step is installing ModemManager. This package is only useful if you plan on using some sort of Modem like an LTE modem or something along these lines. I use this with my Lenovo X270 which has an integrated LTE Modem. Skip this if you don’t plan on using this.

pacman -S modemmanager rp-pppoe mobile-broadband-provider-info usb_modeswitch
systemctl enable ModemManager

Make it boot

At this point you have two options. Either go with a classic bootloader like GRUB or use systemd’s integrated boot management. I’m using both methods but only learned about the systemd method later on. Slowly I move away from GRUB as it just removes one more element in the stack that may potentially go wrong.

One thing GRUB offers over systemd is automatic configuration. So far Arch Linux doesn’t provide automatic configuration of the systemd boot process. It’s not difficult to configure but a small type in the boot config can cause big headaches.

If neither systemd nor GRUB look good to you, check out the Arch Wiki on bootloaders for more options.

Tip: There is a good chance for something to go wrong at this point. If your system doesn’t boot after restart don’t panic. Nothing’s lost and you can go back into the Arch live system, mount your partition (as described above) and enter your arch system with arch-chroot again. Make your changes as needed and try again.

Option A: Use systemd to boot

Depending on your CPU make install either intel-ucode or amd-ucode. Make sure your boot partition is loaded and that your kernel files as well as your Intel and/or AMD microcode image are stored on it.

Install the EFI bootloader:

bootctl install

Your boot partition now has a loader directory. It contains loader.conf and another directory called entries. The config file defines some defaults like timeout and what entry to boot by default. Your OS entries (e.g. for arch linux) go into the entries directory. Do not add them to the loader.conf file directly.

Start with /boot/loader/loader.conf:

echo > "default  arch
timeout  4
console-mode max
editor   no" > /boot/loader/loader.conf

What matters most here is the arch entry. It fefers to the filename of your entry file. If you have multiple OS and would prefer for example OpenSUSE to be your default pick set the default value to suse and call the config file suse.conf. Of course we’ll stick to arch for now.

Before you create the entry file get your root partitions UUID using the blkid command. The result should look something like this:

/dev/sda1: UUID="6726-0548" TYPE="vfat" PARTLABEL="EFI System" PARTUUID="6ec8cde7-bc90-4f9b-9f28-9d4d6303116b"
/dev/sda2: UUID="fae052bf-bb5e-478d-9e3b-dcb1213ebf32" TYPE="ext4" PARTLABEL="Linux filesystem" PARTUUID="b4d28a94-7299-4c57-17d1-c0143839ec7b"

Copy the value of PARTUUID for your root partition. In case of the example above that’d be: b4d28a94-7299-4c57-17d1-c0143839ec7b. Use that ID in the entry file.

Create a new file called /boot/loader/entries/arch.conf:

echo > "title   Arch Linux
linux   /vmlinuz-linux
initrd  /intel-ucode.img
initrd  /initramfs-linux.img
options root=PARTUUID=b4d28a94-7299-4c57-17d1-c0143839ec7b rw" > /boot/loader/entries/arch.conf

One optional step is to automate the bootctl update command for systemd-boot updates to take effect. Create a pacman hook that’ll run every time systemd updates:

mkdir -p /etc/pacman.d/hooks/
echo "[Trigger]
Type = Package
Operation = Upgrade
Target = systemd

[Action]
Description = Updating systemd-boot
When = PostTransaction
Exec = /usr/bin/bootctl update" > /etc/pacman.d/hooks/100-systemd-boot.hook

Option B: Install the GRUB boot loader

Be aware that there’s a multitude of ways to boot Linux. GRUB is a bit of a legacy product at this point. I personally don’t care about what boots my system, so I usually stick to what I know. Feel free to use alternative ways.

This step is part of the more complicated UEFI setup of Arch.

# Prepare an initrd (contains all the kernal bits and pieces needed during boot)
mkinitcpio -p linux

# Install GRUB and UEFI related tools
pacman -S grub efibootmgr dosfstools os-prober mtools
mkdir /boot/EFI
mount $EFI_PART /boot/EFI
grub-install --target=x86_64-efi  --bootloader-id=grub_uefi --recheck

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

Disable logind power management

Arch Linux manages your power settings using logind. Once you use KDE or another bloated desktop environment (I do) the power manager of that one takes over. All good and well until you shut down your notebook and immediately close the lid. What happens then is that the higher level manager shuts down and logind just sends your computer to sleep. The shutdown still happens but only once the computer wakes up. Hugely annoying.

This is why I disable logind’s authority over any relevant power management:

echo "HandlePowerKey=ignore
HandleSuspendKey=ignore
HandleHibernateKey=ignore
HandleLidSwitch=ignore
HandleLidSwitchExternalPower=ignore
HandleLidSwitchDocked=ignore" > /etc/systemd/logind.conf

Disable the PC speaker

Another optional change I like to do early, disabling the hugely annoying PC speaker:

echo blacklist pcspkr > /etc/modprobe.d/blacklist.conf

Create a regular user

So far we only have root access. At this point I usually create my user:

export MYUSER=ENTER_USERNAME_HERE

useradd -m -U -G users,wheel,storage,power -s /bin/bash $MYUSER
passwd $MYUSER

Wrap it up

Logout and reboot:

logout
reboot

This concludes my version of an Arch Linux base installation. It may look like quite a procedure but it mostly comes down to copy & paste of some amended commands.

I see the lack of an installer in systems like Arch and Gentoo Linux as advantageous. Not only do you have a high level of control from the first moments on but you also learn a lot about the system. Rarely do I go through an Arch installation on a new device without finding out something I didn’t know before.

Don’t be afraid to try for yourself and keep on learning.

In the next part I’ll share with you my post install steps to make Arch useful on a command line level.