Working configuration for:
- Limine bootloader
- LUKS2 encrypted root partition
- btrfs with Snapper snapshots
- dracut (required for btrfs snapshot boot)
- systemd-based initramfs
- Secure Boot enabled
- TPM2 auto-unlock using PCR 0+7
Verify your current setup:
Verify LUKS2 (not LUKS1):
sudo cryptsetup luksDump /dev/nvme1n1p2 | grep VersionExpected output:
Version: 2
Verify btrfs:
df -Th /Expected output (look for "btrfs"):
Filesystem Type Size Used Avail Use% Mounted on
/dev/mapper/luks-3d2966af-234b-424e-a81d-570f9d2299ad btrfs 1.9T 606G 1.3T 33% /
Verify snapper is configured:
snapper list-configsExpected output:
Config │ Subvolume
───────┼──────────
root │ /
Verify TPM2 is available:
systemd-cryptenroll --tpm2-device=listExpected output:
PATH DEVICE DRIVER
/dev/tpmrm0 MSFT0101:00 tpm_crb
# Install from official repos
sudo pacman -S dracut tpm2-tss tpm2-tools
# Install from AUR
paru -S limine-dracut-supportsudo pacman -R limine-mkinitcpio-hookNote: limine-dracut-support and limine-mkinitcpio-hook conflict and cannot coexist.
Create /etc/dracut.conf.d/tpm.conf:
sudo nano /etc/dracut.conf.d/tpm.confAdd this line:
add_dracutmodules+=" tpm2-tss "
Create /etc/dracut.conf.d/cryptsetup.conf:
sudo nano /etc/dracut.conf.d/cryptsetup.confAdd this line (fixes missing TPM2 token library):
install_items+=" /usr/lib/cryptsetup/libcryptsetup-token-systemd-tpm2.so "
Verify the files:
cat /etc/dracut.conf.d/tpm.conf
cat /etc/dracut.conf.d/cryptsetup.confExpected output:
add_dracutmodules+=" tpm2-tss "
install_items+=" /usr/lib/cryptsetup/libcryptsetup-token-systemd-tpm2.so "
Edit /etc/crypttab:
sudo nano /etc/crypttabChange from:
luks-<UUID> UUID=<UUID> none
To:
luks-<UUID> UUID=<UUID> - tpm2-device=auto
Example:
luks-3d2966af-234b-424e-a81d-570f9d2299ad UUID=3d2966af-234b-424e-a81d-570f9d2299ad - tpm2-device=auto
Verify:
cat /etc/crypttabExpected output (look for - and tpm2-device=auto):
luks-3d2966af-234b-424e-a81d-570f9d2299ad UUID=3d2966af-234b-424e-a81d-570f9d2299ad - tpm2-device=auto
Edit /etc/default/limine:
sudo nano /etc/default/limineChange from (mkinitcpio syntax):
KERNEL_CMDLINE[default]+="... cryptdevice=UUID=<UUID>:<mapper-name> ..."To (dracut syntax):
KERNEL_CMDLINE[default]+="... rd.luks.name=<UUID>=<mapper-name> ..."Example:
KERNEL_CMDLINE[default]+="quiet nowatchdog splash rw rootflags=subvol=/@ rd.luks.name=3d2966af-234b-424e-a81d-570f9d2299ad=luks-3d2966af-234b-424e-a81d-570f9d2299ad root=/dev/mapper/luks-3d2966af-234b-424e-a81d-570f9d2299ad"Verify:
cat /etc/default/limineExpected output (look for rd.luks.name= instead of cryptdevice=):
ESP_PATH="/boot"
KERNEL_CMDLINE[default]+="quiet nowatchdog splash rw rootflags=subvol=/@ rd.luks.name=3d2966af-234b-424e-a81d-570f9d2299ad=luks-3d2966af-234b-424e-a81d-570f9d2299ad root=/dev/mapper/luks-3d2966af-234b-424e-a81d-570f9d2299ad"
BOOT_ORDER="*, *lts, *fallback, Snapshots"
sudo limine-dracutThis will:
- Generate new initramfs with dracut
- Update Limine boot entries
- Apply new kernel parameters
Expected output:
dracut: Executing: /usr/bin/dracut --force --hostonly ...
dracut: *** Including module: systemd ***
dracut: *** Including module: tpm2-tss ***
dracut: *** Including module: crypt ***
...
dracut: *** Creating initramfs image file done ***
sudo rebootIMPORTANT: You should still be prompted for your LUKS password. Verify:
- System boots correctly
- Password unlock works
- System fully boots to desktop
If this fails, DO NOT PROCEED. Fix boot issues before enrolling TPM.
After confirming password boot works:
Verify TPM is detected:
systemd-cryptenroll --tpm2-device=listExpected output:
PATH DEVICE DRIVER
/dev/tpmrm0 MSFT0101:00 tpm_crb
Enroll TPM key (replace /dev/nvme1n1p2 with your LUKS partition):
sudo systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+7 /dev/nvme1n1p2Expected output:
🔐 Please enter current passphrase for disk /dev/nvme1n1p2: ****
New TPM2 token enrolled as key slot 1.
PCR Explanation:
- PCR 0: UEFI firmware code
- PCR 7: Secure Boot state
Verify enrollment:
sudo systemd-cryptenroll /dev/nvme1n1p2Expected output:
SLOT TYPE
0 password
1 tpm2
Also verify token:
sudo cryptsetup luksDump /dev/nvme1n1p2 | grep -A 5 "Tokens:"Expected output:
Tokens:
0: systemd-tpm2
tpm2-hash-pcrs: 0+7
tpm2-pcr-bank: sha256
tpm2-pubkey:
(null)
sudo limine-dracutExpected output:
dracut: Executing: /usr/bin/dracut --force --hostonly ...
dracut: *** Including module: tpm2-tss ***
...
dracut: *** Creating initramfs image file done ***
sudo rebootExpected behavior:
- System boots to Limine
- LUKS partition automatically unlocks (no password prompt)
- System boots normally
If TPM unlock fails:
- You'll be prompted for password (fallback still works)
- System is NOT bricked
Check TPM enrollment:
sudo systemd-cryptenroll /dev/nvme1n1p2Expected output:
SLOT TYPE
0 password
1 tpm2
Check LUKS keyslots:
sudo cryptsetup luksDump /dev/nvme1n1p2Expected output (look for Token 0: systemd-tpm2 and Keyslot 1):
LUKS header information
Version: 2
...
Tokens:
0: systemd-tpm2
tpm2-hash-pcrs: 0+7
tpm2-pcr-bank: sha256
...
Keyslots:
0: luks2
Key: 512 bits
...
1: luks2
Key: 512 bits
...
Verify dracut includes TPM modules:
lsinitrd | grep tpm2Expected output (should show TPM-related files):
-rw-r--r-- 1 root root 123456 Nov 19 18:53 usr/lib/systemd/system-generators/systemd-tpm2-generator
drwxr-xr-x 3 root root 0 Nov 19 18:53 usr/lib/cryptsetup
-rwxr-xr-x 1 root root 98765 Nov 19 18:53 usr/lib/cryptsetup/libcryptsetup-token-systemd-tpm2.so
Check journal for errors:
sudo journalctl -b | grep -i tpm
sudo journalctl -b | grep -i cryptLook for errors like:
libcryptsetup-token-systemd-tpm2.so: cannot open shared object file- Missing cryptsetup libraryFailed to unseal- PCR values changedTPM2 token not found- Enrollment failed
Common causes:
- Missing cryptsetup library - verify
/etc/dracut.conf.d/cryptsetup.conf - PCR values changed (firmware update) - re-enroll TPM key
- Secure Boot state changed - re-enroll TPM key
PCR values change when:
- Firmware/BIOS updated
- Secure Boot keys changed
- Boot configuration modified
Solution - Re-enroll TPM:
sudo systemd-cryptenroll --wipe-slot=tpm2 /dev/nvme1n1p2
sudo systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+7 /dev/nvme1n1p2
sudo limine-dracutsudo systemd-cryptenroll --wipe-slot=tpm2 /dev/nvme1n1p2
sudo limine-dracutPassword unlock continues to work.
List TPM devices:
systemd-cryptenroll --tpm2-device=listExpected output:
PATH DEVICE DRIVER
/dev/tpmrm0 MSFT0101:00 tpm_crb
Check TPM in sysfs:
cat /sys/class/tpm/tpm0/device/descriptionExpected output:
TPM 2.0 Device
Check dmesg for TPM:
sudo dmesg | grep -i tpmExpected output (should show TPM initialization):
[ 0.614715] tpm_crb MSFT0101:00: Disabling hwrng
- Password always works - TPM is convenience, not a replacement for your password
- Snapshots remain bootable - With
limine-snapper-sync, btrfs snapshots work with TPM - PCR selection trade-offs:
- PCR 0+7 (recommended): Survives most updates, secure
- PCR 0+2+7: More secure, may break on boot config changes
- PCR 7 only: Most flexible, least secure
- Secure Boot required - PCR 7 measures Secure Boot state
- Recovery is safe - Password fallback always available
For systems with btrfs snapshots (using Snapper/Timeshift), dracut is required because:
- mkinitcpio's systemd hook is incompatible with btrfs-overlayfs
- dracut properly supports bootable snapshot entries via
limine-snapper-sync
If you don't use btrfs snapshots, you can use the simpler mkinitcpio path.
Tested on:
- CachyOS (Arch-based)
- Limine 10.3.0-1
- dracut 109-1
- systemd 258.2-2
- Kernel: linux-cachyos 6.17.8-2
- Hardware: ASUS ROG with Intel PTT (TPM 2.0)
Works perfect on the first 2026 release.
Thank U!