
π Dual Booting Arch Linux & Windows with Secure Boot, TPM, and Disk Encryption
π Dual Booting Arch Linux & Windows with Secure Boot, TPM, and Disk Encryption
How I set up a seamless dual boot with Arch Linux and Windows 11 using Secure Boot, LUKS encryption, and TPM for password-less unlocks π
β οΈ Warning: Weβll be messing with bootloaders and secure boot. Windows might ask you for the Bitlocker recovery key β ensure it's backed up on your Microsoft account before proceeding. Write it down somewhere easily accessible just in case as well.
π§° Preparing the Disks While Installing Arch Linux
Note: Secure Boot must be disabled to boot the Arch install USB (it's unsigned with Microsoft keys).
I have two partitions:
nvme0n1p6
: UEFI partition (512MB, vfat)nvme0n1p7
: Root partition (1TB, encrypted)
From the Arch Linux USB:
1cryptsetup --use-random luksFormat /dev/nvme0n1p7 2cryptsetup luksOpen /dev/nvme0n1p7 cryptlvm
Note: replace nvme0n1p7 with your partition identifier
Then LVM setup (optional if only one partition):
1pvcreate /dev/mapper/cryptlvm 2vgcreate vg0 /dev/mapper/cryptlvm 3lvcreate -l +100%FREE vg0 --name root 4mkfs.ext4 /dev/vg0/root
Mount everything:
1mount /dev/vg0/root /mnt 2mount --mkdir /dev/nvme0n1p6 /mnt/boot/efi 3mount --mkdir /dev/nvme0n1p1 /mnt/boot/efiwin # Windows EFI
Then proceed with pacstrap
and regular install steps...
π§© Configuring Bootloader, Secure Boot & Unified Kernel Image
Install needed tools:
1pacman -S sbctl efibootmgr edk2-shell tpm2-tss
Copy UEFI shell to Windows EFI partition:
1cp /usr/share/edk2-shell/x64/Shell_Full.efi /boot/efiwin/shellx64.efi
mkinitcpio Config
Here we will configure mkinitcpi so that it created a unified kernel image (UKI).
Edit /etc/mkinitcpio.conf
:
1HOOKS=(base systemd autodetect microcode modconf kms keyboard sd-vconsole block sd-encrypt lvm2 filesystems fsck)
Edit /etc/kernel/cmdline
:
1rw rd.luks.name=<UUID>=cryptlvm rd.luks.options=<UUID>=tpm2-device=auto root=/dev/vg0/root loglevel=3 quiet bgrt_disable
Replace
<UUID>
with your LUKS partition UUID (blkid -o list
to find it).
The rd.luks.options
part is to tell systemd to use tpm2 if available, otherwise it will default to password.
Edit /etc/mkinitcpio.d/linux.preset
:
1# mkinitcpio preset file for the 'linux' package 2 3ALL_config="/etc/mkinitcpio.conf" 4ALL_kver="/boot/vmlinuz-linux" 5ALL_microcode="/boot/*-ucode.img" 6 7PRESETS=('default' 'fallback') 8 9#default_config="/etc/mkinitcpio.conf" 10default_image="/boot/initramfs-linux.img" 11default_uki="/boot/efi/EFI/Linux/arch-linux.efi" 12default_options="--splash /usr/share/systemd/bootctl/splash-arch.bmp" 13 14#fallback_config="/etc/mkinitcpio.conf" 15fallback_image="/boot/initramfs-linux-fallback.img" 16fallback_uki="/boot/efi/EFI/Linux/arch-linux-fallback.efi" 17fallback_options="-S autodetect"
Create EFI dir & generate UKI:
1mkdir -p /boot/efi/EFI/Linux 2mkinitcpio -p linux
π§± Installing systemd-boot on Windows EFI Partition
Now that we have our unified kernel image, let's install and configure our bootloader (systemd-boot). I'm installing the bootloader on Windows' EFI partition because it breaks Bitlocker if Windows is not booted from a bootloader on the same partition as it's own bootloader. It's not a problem for Linux though, so we will chainload our UKI from Windows's EFI partition.
1bootctl --esp-path=/boot/efiwin install
/boot/efiwin/loader/loader.conf:
1timeout 3 2default @saved 3console-mode max
/boot/efiwin/loader/entries/arch.conf:
1title Arch 2efi /shellx64.efi 3options -nointerrupt -nomap -noversion HD0g:EFI\Linux\arch-linux.efi
HD0g
corresponds to disk 0, partition 7 (g = 7th letter of the alphabet). You can also boot to the UEFI shell and issue themap
command to find out what's your identifier for your luks partition.
You donβt need to manually configure Windows β systemd-boot detects it.
Create UEFI boot entry:
1efibootmgr --create --disk /dev/nvme0n1 --part 1 --label "Systemd-boot" --loader 'EFI\systemd\systemd-bootx.efi' --unicode
That's it, now systemd-boot is installed and configured. We now need to set up secure boot.
π Secure Boot: Creating & Enrolling Keys
1sbctl create-keys 2sbctl enroll-keys -m # Keep Microsoft keys too
Sign boot-related binaries:
1sbctl sign -s -o /usr/lib/systemd/boot/efi/systemd-bootx64.efi.signed /usr/lib/systemd/boot/efi/systemd-bootx64.efi 2sbctl sign -s /boot/efiwin/EFI/systemd/systemd-bootx64.efi 3sbctl sign -s /boot/efi/EFI/Linux/arch-linux.efi 4sbctl sign -s /boot/efi/EFI/Linux/arch-linux-fallback.efi 5sbctl sign -s /boot/efiwin/shellx64.efi
Verify everything:
1sbctl verify
We have signed all the components of our boot chain, so we should be good to go.
π§ Enabling TPM Unlock for Encrypted Disk
We do this so that we don't have to type a password to unlock our LUKS partition at every boot of Linux.
Check current slots:
1systemd-cryptenroll /dev/nvme0n1p7
Enroll TPM:
1systemd-cryptenroll --tpm2-device=auto /dev/nvme0n1p7 --tpm2-pcrs=7
(Optional) Enroll a recovery key:
1systemd-cryptenroll /dev/nvme0n1p7 --recovery-key
Now, Linux should be able to boot without asking us a password, unless the secure boot configuration is messed up with. If that happens, you may need to enroll tpm again. Note also that you can vary the pcrs values to change the conditions when the tpm key will be erased.
π₯³ Final Tips
- Reboot and select your
Systemd-boot
entry - You should see both Windows and Arch entries + the UEFI shell
- Try to boot in Arch. If it fails to boot, use
e
to edit entry manually (e.g., fix HD0g), or boot back into your USB key to review above config.
If Arch boots, you can then try to enable Secure Boot again and to boot into Windows as well. If Windows asks for the Bitlocker key, provide it once, and it should be fine after that.
Happy dual-booting! ππ§πͺ