Dual Booting Arch Linux and Windows 11

Introduction

Setting up a dual boot system with Arch Linux and Windows 11 can be challenging, especially when you want to maintain full disk encryption on both operating systems while keeping Secure Boot enabled. This guide documents my journey and the solutions I found to create a secure, encrypted dual boot setup on two separate NVMe drives.

Hardware Configuration

My system consists of:

  • nvme0n1 (953.9GB): Windows 11 drive
  • nvme1n1 (1.8TB): Arch Linux drive
  • UEFI firmware with Secure Boot enabled

Initial Setup

Both operating systems were already installed:

  • Windows 11: Pre-installed with BitLocker encryption enabled
  • Arch Linux: Freshly installed with LUKS encryption and LVM

Linux Partition Layout

nvme1n1 (1.8TB)
├─ nvme1n1p1 (1GB)     → /boot (EFI System Partition)
└─ nvme1n1p2 (1.8TB)   → LUKS encrypted
   └─ mimir (LVM)
      ├─ swap (8GB)
      ├─ root (256GB)   → /
      └─ home (1.6TB)   → /home

The Challenge

The main challenge was getting systemd-boot to recognize both operating systems and allow seamless switching between them, while maintaining:

  1. Secure Boot functionality
  2. BitLocker encryption on Windows
  3. LUKS encryption on Linux
  4. Proper boot order management

Step-by-Step Solution

1. Installing systemd-boot with Secure Boot

Since Secure Boot was enabled, I used shim as the signed bootloader that chainloads systemd-boot:

# Install systemd-boot
sudo bootctl install

# Create UEFI boot entry for Arch with shim
sudo efibootmgr --create --disk /dev/nvme1n1 --part 1 \
    --loader /EFI/arch/shimx64.efi --label "Arch Linux" --unicode

I had signing hooks already configured in /etc/pacman.d/hooks/:

  • 999-sign-kernel.hook
  • 999-sign-systemd-boot.hook

2. Configuring systemd-boot

Created the main loader configuration at /boot/loader/loader.conf:

timeout 3
default arch.conf
console-mode max
editor no
auto-entries 0
auto-firmware 0

Important: The auto-entries 0 and auto-firmware 0 lines prevent systemd-boot from auto-detecting duplicate boot entries, which was causing multiple Windows entries to appear.

3. Creating Boot Entries

Arch Linux Entry

File: /boot/loader/entries/arch.conf

title   Arch Linux
linux   /vmlinuz-linux
initrd  /intel-ucode.img
initrd  /initramfs-linux.img
options root=/dev/mapper/mimir-root rw

Windows 11 Entry

File: /boot/loader/entries/windows.conf

title   Windows 11
efi     /EFI/Microsoft/Boot/bootmgfw.efi
options root=PARTUUID=ca9e76ae-3308-4731-9eab-289b2f443762

To find your Windows partition PARTUUID:

sudo blkid /dev/nvme0n1p1

4. Setting Boot Order

Configure the UEFI boot order to prioritize Arch Linux:

# Check current boot entries
efibootmgr -v

# Set boot order (example with boot numbers)
sudo efibootmgr -o 0007,0003,0002,0004

Where:

  • 0007 = Arch Linux (with shim)
  • 0003 = Windows Boot Manager
  • Others = Network boot options

5. Fixing BitLocker Issues

When first attempting to boot Windows through systemd-boot, BitLocker requested a recovery key. This happened because BitLocker’s TPM measurements detected a change in the boot chain.

Solution:

  1. Boot Windows directly (via BIOS boot menu selecting Windows Boot Manager)

  2. Open PowerShell as Administrator and suspend BitLocker:

    manage-bde -protectors -disable C: -RebootCount 2
    
  3. Reboot and boot Windows through systemd-boot

  4. Once Windows boots successfully, re-enable BitLocker:

    manage-bde -protectors -enable C:
    

This allows BitLocker to record the new boot path measurements and accept future boots through systemd-boot.

Recovery from Boot Issues

During setup, my boot partition got wiped. Here’s how I recovered:

1. Boot from Arch Linux Live USB

# Decrypt LUKS partition
cryptsetup open /dev/nvme1n1p2 mimir

# Activate LVM
vgchange -ay

# Mount partitions
mount /dev/mimir/root /mnt
mount /dev/mimir/home /mnt/home
mount /dev/nvme1n1p1 /mnt/boot

# Chroot into system
mount --bind /dev /mnt/dev
mount --bind /proc /mnt/proc
mount --bind /sys /mnt/sys
mount --bind /run /mnt/run
chroot /mnt

2. Reinstall Boot Components

# Reinstall systemd-boot
bootctl install

# Reinstall kernel
pacman -S linux

# Reinstall microcode (for Intel CPUs)
pacman -S intel-ucode

3. Recreate Boot Entries

Recreate the boot entry configuration files as shown in Step 3 above.

Final Boot Configuration

After completing all steps, the system boots with:

UEFI Boot Order

Boot0007* Arch Linux (shimx64.efi) - Default
Boot0003* Windows Boot Manager

systemd-boot Menu

Arch Linux (default, 3-second timeout)
Windows 11

Troubleshooting Tips

Remove Duplicate Boot Entries

# List all boot entries
efibootmgr

# Remove unwanted entry (replace XXXX with boot number)
sudo efibootmgr -b XXXX -B

Change Boot Order from Windows

If you need to access Arch but Windows is booting by default:

# In PowerShell as Administrator
bcdedit /set '{fwbootmgr}' displayorder '{GUID}' '{GUID}' ...

Use the GUIDs from bcdedit /enum firmware output.

Access UEFI Settings Directly

# From Linux
sudo systemctl reboot --firmware-setup
# From Windows
shutdown /r /fw /t 0

Security Considerations

This setup maintains strong security:

Secure Boot: Enabled with signed shim bootloader
LUKS Encryption: Full disk encryption on Linux partitions
BitLocker: Full disk encryption on Windows
TPM Integration: Both encryption systems use TPM
Separate Drives: Physical isolation between operating systems

Conclusion

Setting up a dual boot system with two encrypted operating systems and Secure Boot enabled requires careful configuration, but the result is a secure and functional multi-OS environment. The key challenges were:

  1. Getting systemd-boot to work with Secure Boot (solved with shim)
  2. Preventing duplicate Windows boot entries (solved with auto-entries 0)
  3. Making BitLocker accept the new boot chain (solved by suspending and re-enabling)

The final setup provides a clean boot menu with just two options and maintains full encryption on both sides.

Useful Commands Reference

# View boot entries
efibootmgr -v

# Create new boot entry
sudo efibootmgr --create --disk /dev/nvmeXnY --part Z \
    --loader /path/to/bootloader.efi --label "Label"

# Remove boot entry
sudo efibootmgr -b XXXX -B

# Set boot order
sudo efibootmgr -o 0001,0002,0003

# Update systemd-boot
sudo bootctl update

# Check systemd-boot status
sudo bootctl status

Resources

my DevOps Odyssey

“Σα βγεις στον πηγαιμό για την Ιθάκη, να εύχεσαι να ‘ναι μακρύς ο δρόμος, γεμάτος περιπέτειες, γεμάτος γνώσεις.” - Kavafis’ Ithaka.