If you're aiming for a seamless Arch Linux installation in UEFI mode, follow along as this guide will walk you through the process step by step. We'll be using LUKS (Linux Unified Key Setup) and LVM (Logical Volume Manager) partitions on LUKS to achieve full disk encryption.
Note: I have updated this doc for UEFI mode. For those with BIOS/MBR systems, you can refer to the previous version, but keep in mind that it might be outdated and no longer accurate.
If you're only interested in installing Linux and not setting up dual boot with Windows, feel free to skip the Windows-related sections.
Before we dive into the installation process, let's ensure that your system is ready:
- Data Backup: Make sure you've backed up all your important data. We're about to make significant changes, and it's always wise to have a safety net.
- UEFI Mode: In your system's BIOS settings, set the boot mode to UEFI.
- Ventoy Installation: Start by installing Ventoy on your USB drive. Ventoy is a versatile tool that allows you to easily create a multi-boot USB drive.
- Download Arch ISO: Head to Arch Linux's official website and download the Arch ISO image. Copy it to your USB drive.
- Optional Windows 11: If you plan to set up a dual boot with Windows 11, download the Windows 11 ISO image and also copy it to your USB drive.
Here is an example to give you a clear picture of what the final disk partition structure will look like. If you're not interested in installing Windows, you can simply ignore the green parts.
For better flexibility, I do not reuse the Windows EFI for Linux. Instead, I create a distinct EFI partition dedicated solely to Linux, resulting in the presence of two EFI partitions. I also use separate partitions for EFI and Boot.
In the context of this guide, I've designated the disk device and Linux partitions with names according to the table below. Please be aware that these names should be substituted with the actual device paths relevant to your system configuration:
Device | In this Doc | Examples |
---|---|---|
Disk Device | /dev/<your-disk> |
/dev/sda , /dev/nvme0n1 |
EFI Partition | /dev/<your-disk-efi> |
/dev/sda5 , /dev/nvme0n1p5 |
Boot Partition | /dev/<your-disk-boot> |
/dev/sda6 , /dev/nvme0n1p6 |
LUKS Partition | /dev/<your-disk-luks> |
/dev/sda7 , /dev/nvme0n1p7 |
- Boot from the Windows 11 ISO and install Windows. If you want to use BitLocker for disk encryption, ensure that you install the Windows Pro version.
- In Windows, open the start menu and search for "BitLocker".
Open the BitLocker settings and enable BitLocker for the
C
drive. - Important: Store the BitLocker recovery key in a safe place. You will need it later.
-
Connect the USB drive and boot from the Arch Linux ISO.
-
Make sure the system is booted in UEFI mode. The following command should display the directory contents without error.
ls /sys/firmware/efi/efivars
-
Connect to the internet. A wired connection is preferred since it's easier to connect. More info
-
Run
fdisk
to create Linux partitions.fdisk /dev/<your-disk>
If you have installed Windows, you already have a GPT partition table. Otherwise, create an empty GPT partition table using the
g
command. (WARNING: This will erase the entire disk.)# WARNING: This will erase the entire disk. Command (m for help): g Created a new GPT disklabel (GUID: ...).
Create the EFI partition (
/dev/<your-disk-efi>
):Command (m for help): n Partition number: <Press Enter> First sector: <Press Enter> Last sector, +/-sectors or +/-size{K,M,G,T,P}: +100M Command (m for help): t Partition type or alias (type L to list all): uefi
Create the Boot partition (
/dev/<your-disk-boot>
):Command (m for help): n Partition number: <Press Enter> First sector: <Press Enter> Last sector, +/-sectors or +/-size{K,M,G,T,P}: +512M Command (m for help): t Partition type or alias (type L to list all): linux
Create the LUKS partition (
/dev/<your-disk-luks>
):Command (m for help): n Partition number: <Press Enter> First sector: <Press Enter> Last sector, +/-sectors or +/-size{K,M,G,T,P}: <Press Enter> Command (m for help): t Partition type or alias (type L to list all): linux
Print the partition table using the
p
command and check that everything is OK:Command (m for help): p
Write changes to the disk using the
w
command. (Make sure you know what you're doing before running this command).Command (m for help): w
-
Format the EFI and Boot Partitions.
mkfs.fat -F 32 /dev/<your-disk-efi> mkfs.ext4 /dev/<your-disk-boot>
-
Set up the encrypted partition. You can choose any other name instead of
cryptlvm
.cryptsetup --use-random luksFormat /dev/<your-disk-luks> cryptsetup luksOpen /dev/<your-disk-luks> cryptlvm
-
Create an LVM volume group. You can choose any other name instead of
vg0
.pvcreate /dev/mapper/cryptlvm vgcreate vg0 /dev/mapper/cryptlvm
-
Create LVM partitions (logical volumes).
(Update: I don't create swap volume on disk anymore. Instead, I create a zram device as swap space after finishing the installation process.)
We create logical volumes for swap, root (
/
), and home (/home
). Leave 256MiB of free space in the volume group because thee2scrub
command requires the LVM volume group to have at least 256MiB of unallocated space to dedicate to the snapshot.lvcreate --size 8G vg0 --name swap lvcreate --size 100G vg0 --name root lvcreate -l +100%FREE vg0 --name home lvreduce --size -256M vg0/home
-
Format logical volumes.
mkswap /dev/vg0/swap mkfs.ext4 /dev/vg0/root mkfs.ext4 /dev/vg0/home
-
Mount new filesystems.
mount /dev/vg0/root /mnt mount --mkdir /dev/<your-disk-efi> /mnt/efi mount --mkdir /dev/<your-disk-boot> /mnt/boot mount --mkdir /dev/vg0/home /mnt/home swapon /dev/vg0/swap
-
Install the base system. We also install some useful packages like
git
,vim
, andsudo
.pacstrap -K /mnt base linux linux-firmware openssh git vim sudo
-
Generate
/etc/fstab
. This file can be used to define how disk partitions, various other block devices, or remote filesystems should be mounted into the filesystem.genfstab -U /mnt >> /mnt/etc/fstab
-
Enter the new system.
arch-chroot /mnt /bin/bash
-
Set TimeZone.
# See available timezones: ls /usr/share/zoneinfo/ # Set timezone: ln -s /usr/share/zoneinfo/Asia/Tehran /etc/localtime
-
Run hwclock(8) to generate
/etc/adjtime
.hwclock --systohc
-
Set Locale.
vim /etc/locale.gen (uncomment en_US.UTF-8 UTF-8) locale-gen echo LANG=en_US.UTF-8 > /etc/locale.conf
-
Set hostname.
echo yourhostname > /etc/hostname
-
Create a user.
useradd -m -G wheel --shell /bin/bash yourusername passwd yourusername visudo # ---> Uncomment "%wheel ALL=(ALL) ALL"
-
Configure
mkinitcpio
with modules needed to create the initramfs image.pacman -S lvm2 vim /etc/mkinitcpio.conf # ---> Add 'encrypt' and 'lvm2' to HOOKS before 'filesystems'
Recreate the initramfs image:
mkinitcpio -P
-
Setup GRUB.
pacman -S grub efibootmgr grub-install --target=x86_64-efi --efi-directory=/efi --bootloader-id=GRUB
In
/etc/default/grub
edit the line GRUB_CMDLINE_LINUX as follows. Don't forget to replace/dev/<your-disk-luks>
with the appropriate path.GRUB_CMDLINE_LINUX="cryptdevice=/dev/<your-disk-luks>:cryptlvm root=/dev/vg0/root"
If you have installed Windows and want to add Windows to the GRUB menu, edit
/etc/grub.d/40_custom
:#!/bin/sh exec tail -n +3 $0 # This file provides an easy way to add custom menu entries. Simply type the # menu entries you want to add after this comment. Be careful not to change # the 'exec tail' line above. if [ "${grub_platform}" == "efi" ]; then menuentry "Windows 11" { insmod part_gpt insmod fat insmod search_fs_uuid insmod chain # After --set=root, add the Windows EFI partition's UUID. # (can be found with "blkid" command) search --fs-uuid --set=root $FS_UUID chainloader /EFI/Boot/bootx64.efi } fi
In the above script, replace
$FS_UUID
with Windows EFI partition UUID. You can find this UUID usinglsblk
command. It should be something like8E12-69DD
.Now generate the main GRUB configuration file:
grub-mkconfig -o /boot/grub/grub.cfg
-
Install
networkmanager
package and enableNetworkManager
service to ensure you have Internet connectivity after rebooting.pacman -S networkmanager systemctl enable NetworkManager
-
Exit new system and unmount all filesystems.
exit umount -R /mnt swapoff -a
Arch is now installed 🎉. Reboot.
reboot
-
Open BIOS settings and set
GRUB
as first boot priority. Save and exit BIOS settings. After booting the system, you should see the GRUB menu. -
If you have installed Windows, select "Windows 11" in GRUB menu. If you have previously enabled Bitlocker, BitLocker will ask for your recovery key when you try to boot Windows through GRUB for the first time. Enter your BitLocker recovery key.
-
Reboot again and log in to Arch linux with your username and password.
-
Check internet connectivity.
ping google.com
-
If you want to use Gnome desktop, install
gnome
andgdm
packages:sudo pacman -S gnome gdm
And enable
gdm
service:sudo systemctl enable gdm
-
Reboot!
It is important to make a backup of LUKS header so that you can access your data in case of emergency (if your LUKS header somehow gets damaged).
Create a backup file:
sudo cryptsetup luksHeaderBackup /dev/<your-disk-luks> --header-backup-file luks-header-backup-$(date -I)
Store the backup file in a safe place, such as a USB drive. If something bad happens, you can restore the backup header:
sudo cryptsetup luksHeaderRestore /dev/<your-disk-luks> --header-backup-file /path/to/backup_header_file
If you want to use the same NTFS drive in both Windows and Linux (for example an NTFS partition on your internal disk or external hard drive), consider disabling "Hibernate" and "Fast Startup" features in Windows.
You can check the current settings on
Control Panel > Hardware and Sound > Power Options > System Setting > Choose what the power buttons do
.
The box Turn on fast startup
should either be disabled or missing.
- https://gist.github.com/mattiaslundberg/8620837
- https://wiki.archlinux.org/index.php/Installation_guide
- https://wiki.archlinux.org/title/Dm-crypt/Encrypting_an_entire_system#LVM_on_LUKS
- https://wiki.archlinux.org/title/GRUB
- https://joshrosso.com/docs/2020/2020-2-16-arch-windows-install/
Take a look at my dotfiles repo.
I noticed a typo in:
vreduce --size -256M vg0/home
should belvreduce --size -256M vg0/home
Thanks for the great work though @mjnaderi !