I recently bought a Dell XPS 7390 for personal projects, as I wanted a portable laptop to do things like Arduino projects and bill paying. I used arch for a long time in the past, but not really since college. I wanted to get back into it, and also document what I did to set up my own setup. Some things will be poorly documented or might not be good for your personal setup, but this is more of a guide for me to look back at to remember how I set everything up.

A LOT of this guide was inspired/stolen from this great blog post.

Creating Arch USB

I use an IODD Mini as an encrypted flash drive, as well as holding all my ISOs that I boot to. I love it, it lets you store a ton of ISOs and even VHDs, and expose them as mountable, bootable drives. I have recovery systems, memcheck isos, and a variety of Linux ISOs.

This makes Arch super easy to install for me. I just downloaded the latest Arch ISO from the Arch Downloads page and popped it on a folder on my IODD, and exposed it as a mountable ISO.

Setting up Laptop for install

The Dell laptop I got came with Windows pre-installed. I booted into it and set it up so that I could do things like download the latest BIOS (which I find easier to update from Windows for the first time). That was a waste of time, the BIOS actually came fully updated (well done Dell).

There are a couple things you have to do in the BIOS before you can even boot from the USB drive:

  1. Disable UEFI Secure Boot
  2. Change the SATA operating mode from RAID to ACHI
  3. In the "Security" section, turn on the options that allow you to boot from Thunderbolt devices. I had to do this to get my usb-c adapter to even be recognized as a boot device. I think this is an IODD mini quirk, so maybe you don't have to do this. But you might as well, you can always turn it on later again.

Let's Get Going

Internet Connection

You probably want to be connected to internet for your setup so you can update / upgrade packages while you are going through the process.

Your network device might be something other than wlan0 like wlp2s0. For me, my device identifier changed halfway through the install, yours might too. Replace wlan0 with whatever shows up from iw dev in your Interface section.

  1. Connect to your wifi network
lspci -k | grep -A3 'Network controller'
iw dev
ip link set wlan0 up
iw dev wlan0 scan | grep 'SSID:'
wpa_supplicant -B -i wlan0 -c <(wpa_passphrase 'your_network_ssid' 'password')
Connecting to a wifi network

2. Now you're connected to a wifi network, let's get an IP address (assuming you have DHCP): dhcpcd wlan0

3. Sync system time with timedatectl set-ntp true

Partitioning your drive

I'm going to create a drive with a 512M boot partition, and the rest as my root partition, encrypted with LUKS and managed with LVM

  1. Get the drive name with lsblk (mine is nvme0n1)
  2. Partition the drive with fdisk. Create a boot partition first, then a root partition
fdisk /dev/nvme0n1
(fdisk) g
(fdisk) n (skip, skip, +512M)
(fdisk) t (1, 1)
(fdisk) n (skip, skip, skip)

3. Format the partitions

# Format the boot partition
mkfs.fat -F32 -nESP /dev/nvme0n1p1

# Format the root partition
mkfs.ext4 /dev/nvme0n1p2

4. Encrypt the drive

cryptsetup -c aes-xts-plain64 -y --use-random luksFormat /dev/nvme0n1p2
cryptsetup luksOpen /dev/nvme0n1p2 luks

5. Create LVM partitions

pvcreate /dev/mapper/luks
vgcreate vg0 /dev/mapper/luks
# Create 8G swap
lvcreate -L 8G vg0 -n swap
# Create 25G root
lvcreate -L 25G vg0 -n root
# Give the rest of the drive to home
lvcreate -l 100%FREE vg0 -n home

6. Format the LUKS volumes

mkfs.ext4 /dev/mapper/vg0-root
mkfs.ext4 /dev/mapper/vg0-home
mkswap /dev/mapper/vg0-swap

7. Mount the filesystem

# mount the created partition while installing in /mnt
mount /dev/mapper/vg0-root /mnt
# create temporary mountpoints
mkdir /mnt/{boot,home}
# Mount boot partition
mount /dev/nvme0n1p1 /mnt/boot
# Mount home partition
mount /dev/mapper/vg0-home /mnt/home
# Set swap
swapon /dev/mapper/vg0-swap

Bootstrap new install

Now you have your new arch install mounted temporarily to /mnt. We can use the pacstrap tool to copy some packages installed on the ISO over there that we want, to save time later:

pacstrap -i /mnt \
  base \
  base-devel \
  linux \
  lvm2 \
  linux-firmware \
  nano \
  iw \
  dialog \
  dhcpcd \
  wpa_supplicant \
  git \
  vim \
  openssh \

Generate the fstab

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

Chroot into the new install

You can now use arch-chroot to chroot into the newly created arch system, and start installing and configuring things without rebooting.

  1. chroot into system
arch-chroot /mnt /bin/bash

2. Set timezone (I'm on eastern time. If you aren't, change this)

ln -s /usr/share/zoneinfo/America/New_York /etc/localtime

3. Set locale to en_US.UTF-8

vim /etc/locale.gen # (uncomment en_US.UTF-8 UTF-8)
echo LANG=en_US.UTF-8 > /etc/locale.conf
export LANG=en_US.UTF-8

4. Set hardware clock

hwclock --systohc --utc

5. Set hostname

echo cameron-dev > /etc/hostname

Set /etc/hosts:	localhost
::1        	localhost	cameron-dev.localdomain	cameron-dev

6. Create local user

useradd -m -g users -G wheel -s /bin/bash cameron # the shell must be listed in $(cat /etc/shells)
passwd cameron
visudo # uncomment %wheel ALL=(ALL) ALL

7. Configure mkinitcpio with modules we need

$ vim /etc/mkinitcpio.conf # Add 'encrypt' and 'lvm2' to HOOKS before 'filesystems', add i915 to MODULES
$ mkinitcpio -p linux

8. Setup systemd-boot

bootctl --path=/boot install

# Get the UUID of your root partition
touch /boot/loader/entries/arch-encrypted-lvm.conf
# This will just copy your UUID into the arch-encrypted-lvm.conf file for convenience
blkid -s UUID -o value /dev/nvme0n1p2 >> /boot/loader/entries/arch-encrypted-lvm.conf

Edit that /boot/loader/entries/arch-encrypted-lvm.conf:

title Arch Linux Encrypted LVM
linux /vmlinuz-linux
initrd /intel-ucode.img
initrd /initramfs-linux.img
options cryptdevice=UUID=<UUID>:vg0 root=/dev/mapper/vg0-root quiet rw

9. Reboot!

# exit our chroot system

Setup Wifi (Again)

systemctl enable dhcpcd.service
systemctl start dhcpcd.service
systemctl enable wpa_supplicant.service
systemctl start wpa_supplicant.service
iw dev # the device name probably changed
sudo ip link set wlp2s0 up
sudo su -c 'wpa_supplicant -i wlp2s0 -c <(wpa_passphrase "your_network_ssid" "password")'