Hope this will stay relevant for longer than just 2021. This guide will focus mostly on things you shouldn't overlook and will harshly prioritise assuming that you're running on recent hardware. EFI and all that.
Always refer to the official guide in case of doubt.
First things first
One important thing first: the environment you will encounter on the live image is very different
from what you'll end up installing, some things are significantly easier there: e.g. wifi tools come
pre-installed, the default shell is a pimped
zsh with nice completions, and so on. We'll keep this
in mind where it's important.
I assume you haven't downloaded the setup image from a dodgy website so you don't really have to verify it (I wondear how many people do that).
The first thing you should do is set your preferred console keyboard layout with
the default one,
us, is the one you want.
# ls /usr/share/kbd/keymaps/**/*.map.gz # look up the possible values # loadkeys no # grab one of the file names, minus the extension
As above, we assume you're using EFI, to check this
# ls /sys/firmware/efi/efivars
If this throws any error you should stop here and stick to the official guide.
Connecting to the internet is not the same procedure during the installation phase as it will be later. The install iso has a bunch of closed source modules embedded so it should recognise your wifi card out of the box. If it doesn't, grab an ethernet cable and your favourite dongle in case you don't have an ethernet port.
- Ethernet should work once you plug the cable
- For Wifi you should use
Test the connection to be safe.
Update the system clock (so vintage)
# timedatectl set-ntp true
Partitioning the drive
Now it's time to partition the disks and there are a few forks on the road
- Encrypting using LVM or plain LUKS on a partition?
- Swap partition or swap file?
These are already four possible choices, but we can go through a couple of options. There are more encryption possibilities but if you have an opinion on them probably this guide isn't for you.
The encrypted LVM setup is the most logical because it essentially encrypts a thingy that once decrypted will provide you with the partitions you wanted (as opposed to, e.g. encrypting every single one of them individually). LUKS on a partition, on the other hand, is fine if you're using a swap file, because the file will realistically lie in your encrypted partition.
Nevertheless, start with the
efi partition: don't get stingy with the space, put at least
300MB, I'd even say 500. If the system already has one (my Macbook Pro did) you should leave
it there, although it might be small, so if you can move the contents somewhere else, expand it, and
move the stuff back, do it.
cfdisk to partition the drive. If the disk is already partitioned (as above) you shouldn't
do much, otherwise you need to create a new GPT partition table.
As mentioned, allocate 300-500M to your
efi partition, which should be the
first, and set
EFI as its type, then create a big
Linux partition for the rest of the space.
Save and quit.
Now it's time to create the encrypted volume. We'll assume that
sda1 is your
sda2 is the
Linux one you created above, but with NVMe SSDs it's possible that your drive
will be called
nvme0n1 so you'll have
nvme0n1p2 instead of
# cryptsetup -y -v luksFormat /dev/sda2 # cryptsetup open /dev/sda2 main # use whichever name you want but it needs to match below
This will just create "encrypted space". From here you can either create a partition
mkfs.ext4 /dev/mapper/main) and mount it (
mount /dev/mapper/main /mnt), that's pretty much it,
or you can proceed to creating your LVM.
# pvcreate /dev/mapper/main # needs to match the name above # vgcreate vg /dev/mapper/main # again, vg can be any name
To add partitions to a volume group, you do something like:
# lvcreate -L 8G vg -n swap # lvcreate -L 32G vg -n root # lvcreate -l 100%FREE vg -n home
The swap partition should be more than the size of your RAM. In the past 2x was recommended but since it's not uncommon to have 16 or 32G RAM it's probably overkill to go all the way to 64, so going just above should be fine.
If you just want to create a single partition because you want to use a swap file (a bit overkill to use a LVM for that) you just do
# lvcreate -l 100%FREE vg -n root
The partitions will be in
/dev/vg/root). You can format
them like normal partitions:
# mkfs.ext4 /dev/vg/root # mkswap /dev/vg/swap
Regardless of your setup during the installation phase whatever is your
/ partition should
be mounted on
# mount /dev/vg/root /mnt # in the LVM examples # mount /dev/mapper/main /mnt # in the simple LUKS setup I briefly mentioned
Once your root partition is mounted you should mount the
efi partition to
# mount /dev/sda1 /mnt/boot # if it's called sda1, of course
You can also create your swapfile now if you chose to use that instead of a partition:
sudo dd if=/dev/zero of=/mnt/swap bs=1M count=18000 # for 18G RAM mkswap /mnt/swap swapon /mnt/swap
Are you done?
- The root partition is created and mounted.
- The swap partition (or file) is created and mounted at the right place (
- The boot partition is mounted at the right place (
If all of the above is true, we can move to the next section. Some details of this setup will be crucial to make sure that the system boots, we'll mention them later.
A few extra considerations on encryption:
- You can go full paranoid and have an encrypted boot partition. There's a way to do that with GRUB. The EFI partition can't be encrypted as far as I know so you'll still leave some system files there to be potentially tampered with by an attacker. There's always a line to be drawn somewhere and this is an option if you think you need to hide your kernels.
- LVM or not, swapfile or not, don't make the silly mistake of putting your swap file or partition outside of the encrypted volume, so you should either go the swap file way, or use LVM and add a swap partition to the LVM.
- Using LVM with only one partition (the root one) and a swap file inside is overkill and perhaps there might be some performance issues, but it's not much damage. I haven't benchmarked most of this so you can try experimenting: the problem of course is that these experiments are expensive since you'd need to reinstall and so on, so I'd recommend that you pick one way and stick to it.
The actual installation
This is the easy part, but you probably still need a couple of pointers.
Install the base system
# pacstrap /mnt base linux linux-firmware
This basically installs only the base system plus the kernel plus essential Linux firmware: it won't install anything like "my webcam's firmware" or "external wifi drivers". We'll do that in a second.
fstab file for this setup:
# genfstab -U /mnt >> /mnt/etc/fstab
This basically looks at what's mounted and where and generates a matching
/etc/fstab. Edit the paths
if they're wrong, e.g. if the
efi partition is mounted to
/mnt/boot instead of
/boot, keep in
mind that this is in what will become your setup, so no
/mnt there – hence
Now you can chroot to
/mnt and we'll operate as if everything is installed.
# arch-chroot /mnt
Set the time zone and sync the hardware clock:
# ln -sf /usr/share/zoneinfo/Europe/Oslo /etc/localtime # pick whichever time zone # hwclock --systohc
Now you need to think of what you need to install in the system to make sure that once you reboot
you're not in some bizarre desert island. As I mentioned earlier, exotic wifi stuff isn't installed by
default, but luckily many things are in the Arch Linux repository. For instance, if you need the
# pacman -S linux-headers broadcom-wl-dkms
Repeat this step for every peripheral you know that you will need (minus
linux-headers of course):
the most crucial one in general is just the WiFi because keyboards and screens should work out of
the box and maybe you just miss the
nvidia driver and stuff like that if you have a Nvidia card,
but since the open source driver is installed already, you should be fine for minimal usage.
Once you're sure that you have a working WiFi module installed, this is also the right time to
figure out how you want to use your new setup: if you want to fine tune it yourself and install
whichever minimal WM (e.g. i3), have fun, but be careful to install whichever tools you need to
connect to the internet. If you want to use
gnome on the other hand, just run:
# pacman -S gnome
And this should install everything on its own. If you use
gnome you need to have
Network Manager installed even though these days
systemd has a thingy that is able to
control the network. Check if
networkmanager are installed.
# pacman -Q wpa_supplicant networkmanager
If not, well,
pacman -S etc. etc..
As a rule of thumb, Arch Linux doesn't enable stuff for you after you install it,
when it comes to global
systemd configuration, so do this:
# systemctl enable NetworkManager.service
This makes sure Network Manager starts when you reboot, so that then you can use GNOME's GUI to configure your wifi, or wired connection.
Now it's a good moment to look at the guide and maybe follow the steps related to localisation and network configuration. You only need to set a hostname for your computer, not much else.
Create a root password:
This is also a good moment to create your own user:
# useradd -m username # passwd username
This is a matter of taste but I'd install your usual comfort zone packages now, e.g.
your favourite shell, your favourite text editor and so on. Not to imply that since
you'll fuck up your boot loader configuration it's better to have a nice text editor
and shell so that you won't be too annoyed when you'll have to fix your mistakes, you
never know what life has in store for you so it's just nicer to face adversities
from a nice
Boot loader and
Alright: this is where you can't fuck stuff up. If you fuck stuff up here your system
won't boot. Typically when this happens it's recoverable from the install medium you
arch-chroot and so on. With encrypted setups doing this is annoying because
on every reboot with the install medium you always need to open the volume, mount the
LVM and so on, so every fuckup adds minutes to the debugging process. To add insult to
injury, debugging is often hard because the messages aren't very helpful.
Having said that, here we go.
What I'd do first is check the guide.
Depending on whether you used option 1 or 2 (LUKS on a partition or LVM on LUKS) you have
This is what mine with
HOOKS="base systemd sd-plymouth autodetect keyboard sd-vconsole modconf block sd-encrypt lvm2 filesystems resume fsck"
The order of stuff is very important here so even though you might not find some things yet
sd-plymouth certainly isn't there) if you used
lvm2 make sure that things like
encrypt are available.
If you don't have
sd-related things don't panic, we haven't added those yet. We'll do that in
Now it's a good time to run your first
# mkinitcpio -P
Chances are that this has been run already by several of the commands we ran earlier.
systemd-boot. A few principles:
- It will be installed in your EFI partition.
- It will grab loader entries from
/boot/loader/entries/so once it's installed we'll make sure you have a valid one there.
# bootctl install
There are ways to keep it updated. Either you just run
bootctl update every now and then or
add a hook so that it's done automatically
(this isn't a hard requirement).
The crucial thing is to get one working entry. Check out the contents of
might be something there already. Just in case, here's what a working entry looks like:
title Linux linux /vmlinuz-linux initrd /intel-ucode.img initrd /initramfs-linux.img options rd.luks.name=[PLACEHOLDER_1]=[PLACEHOLDER_2] root=[PLACEHOLDER_3] rw
Trivial things first: if you have an Intel CPU you should install the
intel-ucode package and keep that
line, otherwise if you have an AMD CPU you should install the
amd-ucode package and replace
Now with the three placeholders. We need to rewind a bit and do some matching. The third placeholder is the
easy one: this is the root partition's "device". In our case, if we used LVM, we decided that it's
/dev/mapper/vg-root points to the same device). So
root=/dev/vg/root it is.
The first and second placeholder are, respectively, the UUID of the outermost layer of the partitions onion, so, in the LVM case, the ID of the partition containing the LVM (not the LVM itself), e.g.:
# blkid /dev/sda1: LABEL_FATBOOT="EFI" LABEL="EFI" UUID="67E3-17ED" BLOCK_SIZE="512" TYPE="vfat" PARTLABEL="EFI System Partition" PARTUUID="183dd690-3d06-4702-aad4-cbc2902758fe" /dev/sda2: UUID="5f6f3aa3-2a8c-4712-ab3e-c8264d34088d" TYPE="crypto_LUKS" PARTUUID="d67e5442-a316-6c48-8c43-098fb2152ba7" /dev/mapper/lvm: UUID="V2C8qe-zkLT-Ra03-p9f0-rJ3b-NLPH-iJv7no" TYPE="LVM2_member" /dev/mapper/vg-root: UUID="1d5508bf-7878-4f02-98f9-91c32e4aadf2" BLOCK_SIZE="4096" TYPE="ext4"
You see that there's two possible mistakes you can make: you can pick the vg-root's own UUID, the LVM's or the outer
partition's. The latter is the one you should pick, so, in this case,
I am not sure how many mistakes you can make with the second placeholder as in the LVM case
lvm just works even though that's not the name of the outer shell, but regardless, in this setup
with those names and ID's, this works:
options rd.luks.name=5f6f3aa3-2a8c-4712-ab3e-c8264d34088d=lvm root=/dev/vg/root rw
Triple, quadruple check the UUID's because fucking this up means your computer won't boot and you'll need to debug this over and over.
If you don't use LVM, the principle is the same:
# blkid /dev/nvme0n1p1: UUID="284C-3A64" BLOCK_SIZE="512" TYPE="vfat" PARTUUID="0794ef09-5eb8-d144-b103-bc7b975f8963" /dev/nvme0n1p2: UUID="79ac497a-7eac-4f16-af63-f362c52ed44c" TYPE="crypto_LUKS" PARTUUID="58319ad0-043c-fc48-9c4b-c466484d1135" /dev/mapper/main: UUID="fd884ff1-12a0-4289-89ce-11ca73f4af89" BLOCK_SIZE="4096" TYPE="ext4"
rd.luks.name should point to the outer shell, i.e.
options rd.luks.name=79ac497a-7eac-4f16-af63-f362c52ed44c=main root=/dev/mapper/main
And as above,
main is the name of whatever you picked earlier: unclear if there needs to be consistency
(there probably has to), so remember the general idea and keep tabs.
Save your new entry as
/boot/loader/entries/linux.conf. It should be fine to keep that as your only
Now back to
/etc/mkinitcpio.conf, check out the
HOOKS line again:
HOOKS="base systemd autodetect keyboard sd-vconsole modconf block sd-encrypt lvm2 filesystems resume fsck"
In the LVM case, you should have all of this, in this order.
systemd runs first, it's the boot loader
and all, then after block devices are detected, you run the decryption step, then open the LVM,
then open the filesystems.
In the simple LUKS case it should look exactly the same, minus
lvm2, that's not necessary:
HOOKS="base systemd autodetect keyboard sd-vconsole modconf block sd-encrypt filesystems resume fsck"
To be safe, run
mkinitcpio -P again (no use not doing so).
Now you can reboot and cross your fingers.
I have rebooted and it doesn't work
If you see
systemd-boot's prompt (i.e. you see a
Linux entry) but then booting hangs the mistake
should be almost certainly because you messed up ID's and names. Don't despair, it's fixable without
having to start from scratch. Boot from the install medium and mount the root and boot partitions.
mkinitcpio.confjust in case, compare with the
- Check the UUID's in
/boot/loader/entries/linux.conf(or whichever the UUIDs).
Fixing these mistakes is very annoying because each reboot is time consuming.
I have rebooted and it works
Well done, there isn't much left to do.
From here on I'll take a few things for granted, like that GNOME works and that your main
sudo (and of course that
sudo is installed), etc.
For some strange reason,
plymouth hasn't made it out of the AUR. This is a good opportunity to
install an AUR helper, i.e. a piece of software that handles installation from the AUR automatically.
yay but you might have a different opinion. Have a look
here on how to install it.
$ yay -S plymouth plymouth-theme-arch-charge $ sudo plymouth-set-default-theme arch-charge
If you're using GNOME, you will also need to install
gdm-plymouth (again, using
and make sure to enable it via
systemctl enable gdm). It should tell you that
it conflicts with regular
gdm and it will replace it on its own.
If you remember from earlier there's an extra
mkinitcpio hook to be added:
HOOKS="base systemd sd-plymouth autodetect keyboard sd-vconsole modconf block sd-encrypt filesystems fsck"
Just that extra
Before rebooting you should also tell
mkinitcpio that you need to load your graphics module. This will
depend on which card you have. I can only vouch for Intel and NVIDIA. You need to edit the
MODULES=(nvidia nvidia_modeset nvidia_uvm nvidia_drm) # for nvidia cards MODULES=(i915) # for intel cards
No, you're not done yet. You need to add yet more kernel options to your
linux.conf is the name I picked, you can choose whatever you like. In the
options line, append:
quiet splash loglevel=3 rd.udev.log_priority=3 vt.global_cursor_default=0
Once that is done,
mkintcpio -P will be enough: you can reboot now and you should be able to see the splash
screen on shutdown already.
This is also something you probably need regardless of whether you're using a laptop.
resume hook between
mkinitcpio.conf which you should be
best mates with by now, and run
You must also tell the bootloader where to resume from, by adding the
resume= kernel option to the
If you're using a swap partition
PLACEHOLDER is of course the
UUID of the swap partition (
sudo blkid to obtain it). If you're using a swap file the logic is
a bit different.
resume should point to the device containing the file, e.g.:
resume=/dev/vg/root # in the lvm example above resume=/dev/mapper/main # in the luks example above
Only one of those two of course. Then you should add a
resume_offset parameter that you obtain
$ sudo filefrag -v /swap Filesystem type is: ef53 File size of /swap is 34359738368 (8388608 blocks of 4096 bytes) ext: logical_offset: physical_offset: length: expected: flags: 0: 0.. 0: 514048.. 514048: 1: 1: 1.. 10239: 514049.. 524287: 10239: unwritten 2: 10240.. 272383: 557056.. 819199: 262144: 524288: unwritten
It should be the first
physical_offset value, i.e. in this case
Since the system hasn't been booted with a kernel supporting hibernation even if you regenerate
the initramfs now (
mkinitcpio -P) you'll need to reboot to be able to use this feature.
This is pretty much it, I hope it's useful.