System preparation

System preparation

These notes expand from the Boot the live environment to the Reboot section in the install guide. Due to hardware specifics and different environmental conditions, such as the Internet connection, you may need to adapt and troubleshoot on your own.

Booting the target machine

I connect the target machine using wired ethernet and insert an installation medium (USB flash) prepared earlier to boot the installation system. This way I can avoid troubleshooting of missing drivers and unsupported wireless NIC1 hardware.

Changing crucial UEFI settings

Disable Secure Boot

For most computers it is necessary to disable Secure Boot2 in order to boot the installation system from an installation medium, such as an USB flash drive. On my hardware this has already been turned off.

Switch RAID mode off

Some computers provide a RAID3 mode for storage devices, which is mostly not detected by Linux due to proprietary drivers. I use the UEFI settings to switch the storage settings to AHCI (or SATA) mode instead of any RAID mode.

Live environment setup

In the live environment, I set a German console keymap using the command:

loadkeys de-latin1

I list the UEFI variables to verify the UEFI boot mode by issueing:

ls /sys/firmware/efi/efivars

I ensure networking by querying the link status and verify the connection with a ping to the site:

ip link

I synchronize the system clock via NTP4:

timedatectl set-ntp true

Disk partition layout

I partition the disk and encrypt the partitions to protect data at rest. The first partition is used as EFI system partition mounted at /boot. Partition 2 will become a LUKS25 encrypted partition carrying a Logical Volume Group (LVG) managed by LVM6. The LVG consists of three logical volumes for Swap7 space, /home and / (root). This layout is known as LVM on LUKS and illustrated below:

+----------------+ +-----------------------------------------------------------+
| Boot partition | | Logical volume 1  | Logical volume 2  | Logical volume 3  |
|                | |                   |                   |                   |
| /boot          | | [Swap]            | /                 | /home             |
|                | |                   |                   |                   |
|                | | /dev/lvg/swap     | /dev/lvg/root     | /dev/lvg/home     |
|                | |_ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _|
|                | |                                                           |
|                | |                 LUKS2 encrypted partition                 |
| /dev/nvme0n1p1 | |                      /dev/nvme0n1p2                       | 
+----------------+ +-----------------------------------------------------------+


I identify the block device (e.g. /dev/nvme0n1) using lsblk and modify the partitions as follows:

fdisk /dev/nvme0n1

I create two partitions:

  1. EFI system partition, 940 MB, type ID: 1
  2. Linux filesystem partition, remaining space, type ID: 20 (default)

The fdisk command sequence for an unpartitioned disk is:

  • g (use GPT)
  • n
  • 1 (default, you can also use Return)
  • Return (as it typically defaults to disk sector 2048)
  • +940M
  • t
  • 1 (default, you can also use Return)
  • 1
  • n
  • 2 (default, you can also use Return)
  • Return (as it defaults to first disk sector)
  • Return (as it defaults to last disk sector)
  • w

Encryption and LVM

I encrypt the second partition as a LUKS container by using a strong passphrase:

cryptsetup luksFormat /dev/nvme0n1p2

Next, I open this container using lvg as the device mapper name:

cryptsetup open /dev/nvme0n1p2 lvg

I create a Physical Volume (PV) on top of the container at /dev/mapper/lvg:

pvcreate /dev/mapper/lvg

I create a Volume Group (VG) lvg and add the previously created PV to it:

vgcreate lvg /dev/mapper/lvg

I create a Logical Volume (LV) for each filesystem (/, /home, and Swap):

lvcreate -L 16G lvg -n swap
lvcreate -L 40G lvg -n root
lvcreate -l 100%FREE lvg -n home
The size of the first LV depends on the amount of memory of your hardware configuration. If you have more than 16 GB of memory, create a swap space accordingly in order to use hibernation.

Formatting and mounting

I format the LVs with ext4 and a swap filesystem (FS), respectively:

mkfs.ext4 /dev/lvg/root
mkfs.ext4 /dev/lvg/home
mkswap /dev/lvg/swap

The boot partition uses a FAT32 FS:

mkfs.fat -F32 /dev/nvme0n1p1

I mount the filesystems at /mnt:

mount /dev/lvg/root /mnt
mount /dev/lvg/home /mnt/home
mount --mkdir /dev/nvme0n1p1 /mnt/boot

And I activate the Swap partition:

swapon /dev/lvg/swap

At this time I can check the layout of my storage device using lsblk.

NVMe lsblk

The layout of the NVMe storage after partitioning and formatting

System initialization

Now I can install the essential packages into the previously mounted location:

pacstrap /mnt base linux linux-firmware lvm2 vim
The package lvm2 is necessary for mounting the LVs and vim is my favorite text editor. You may want to use another one found in the List of applications.

I generate a fstab file by using UUIDs:

genfstab -U /mnt >> /mnt/etc/fstab

If you are using a SSD, you may want to adjust /etc/fstab to use noatime for the filesystems instead of discard) for security reasons. See this section in the ArchWiki article on Dm-crypt Specialties.

I use vim /etc/fstab to open and edit the file accordingly.

I change root into the new system:

arch-chroot /mnt

Next, I first change the root password using the command:



I set the timezone for Germany (CET8) and sync the hardware clock:

ln -sf /usr/share/zoneinfo/Europe/Berlin /etc/localtime
hwclock --systohc

For the locale, I uncomment the line de_DE.UTF-8 UTF-8 and en_US.UTF-8 UTF-8 in the /etc/locale.gen file and run:


I create the file /etc/locale.conf to set the system locale accordingly and make the console keyboard layout persistent via a /etc/vconsole.conf file:

echo "LANG=de_DE.UTF-8" > /etc/locale.conf
echo "KEYMAP=de-latin1" > /etc/vconsole.conf

Initramfs configuration

I edit /etc/mkinitcpio.conf inserting encrypt, lvm2, and resume (for suspend and hibernate) into the HOOKS variable to match the following order:

HOOKS=(base udev autodetect modconf kms keyboard keymap consolefont modconf block encrypt lvm2 resume filesystems fsck)

Afterwards a manual generatation of the image is necessary:

mkinitcpio -P
Any warnings about possibly missing firmware can be safely ignored as long as there’s no critical device shown.

Systemd-boot installation

I use bootctl with the /boot partition to install the UEFI boot manager Systemd-boot:

bootctl --path=/boot install

I create a loader configuration at /boot/loader/loader.conf containing:

default linux
timeout 0
editor  no

I create the loader file /boot/loader/entries/linux.conf containing:

title   Linux
linux   /vmlinuz-linux
initrd  /initramfs-linux.img
options cryptdevice=UUID=MyUuid:lvg resume=/dev/lvg/swap root=/dev/lvg/root quiet rw
The resume parameter is used for suspend and hibernate.

Next, I identify the UUID of the LUKS partition (TYPE=“crypto_LUKS”) created in the Encryption and LVM step by using blkid. The following command conveniently saves it to the $MyUuid variable:

MyUuid=$(blkid | grep crypto_LUKS \
| cut --delimiter=' ' --field=2 | sed 's/[^a-z0-9\\-]//g')

I edit /boot/loader/entries/linux.conf and replace MyUuid with the $MyUUID value in the string cryptdevice=UUID=MyUUID:lvg using the following command:

sed -i "s/MyUuid/$MyUuid/" /boot/loader/entries/linux.conf

I check the boot loader entry to contain the correct UUID. Otherwise the system is unable to boot from the correct device and fall back to an emergency shell. If this happens to you, refer to Boot problems.


I set the hostname in a /etc/hostname file to arch-studio24, for example:

echo "arch-studio24" > /etc/hostname

And I complete the network configuration using Systemd-networkd and Systemd-resolvd.

For this, I retrieve and note the udev assigned names of the network interfaces using the utility:

ip link

I configure a wired adapter using DHCP by creating a new file at the location /etc/systemd/network/ and providing the udev name (enp0s13f0u1 is used in the following example):



I enable the systemd-networkd.service to activate it at system startup:

systemctl enable systemd-networkd.service

I create the Systemd-resolved configuration directory:

mkdir /etc/systemd/resolved.conf.d

I manually set a censorship-free DNS9 server such as by creating /etc/systemd/resolved.conf.d/dns_servers.conf with the content:


Additionally, I setup via /etc/systemd/resolved.conf.d/fallback_dns.conf as fallback DNS containing:


I enable systemd-resolved.service to activate it at system startup:

systemctl enable systemd-resolved.service

I backup the Glibc resolver file and use Systemd-resolved in stub mode:

cp /etc/resolv.conf /etc/resolv.conf.bkp

Next, I exit the arch-chroot (using exit or the key combination <Ctrl+d>) to create the resolv.conf symlink:

ln -sf /run/systemd/resolve/stub-resolv.conf /mnt/etc/resolv.conf
Creating the symlink inside an arch-chroot is not possible since the file is bind-mounted from the live-environment, see the note in Systemd-resolvd#DNS.


Finally, I can unmount all partitions to ensure none of them is busy, and reboot into the installed system:

umount -R /mnt
You may have to remove the installation media or change the boot sequence to boot from the storage device chosen in Partitioning step.

After the reboot I can login into the new system as root user and proceed with the basic configuration of the installed system.

  1. Network interface controller in the Wikipedia ↩︎

  2. Disabling Secure Boot in the ArchWiki ↩︎

  3. RAID in the Wikipedia ↩︎

  4. NTP in the ArchWiki ↩︎

  5. Dm-crypt in the ArchWiki ↩︎

  6. LVM in the ArchWiki ↩︎

  7. Swap in the ArchWiki atime option explanation for SSDs in the ArchWiki ↩︎

  8. CET in the Wikipedia ↩︎

  9. Domain Name System in the Wikipedia ↩︎

Last updated on