expand explanation of why timeout/watchdog approaches fail for S4 hangs since the process is frozen. document the actual viable mitigations: strict preflight validation, auto-recovery via reset, and BootOrder fallback. add note about testing and post-hang recovery documentation.
20 KiB
Plan de build — FWS « Hibernate‑Swap Dual‑Boot » (Valorant/Vanguard)
Document de build final. Le design est validé et acquis : ce plan le rend buildable, intègre les corrections bloquantes de la revue adversariale et fixe l'ordre d'exécution. Cible réelle : UEFI, Zen 5, 60,45 GiB RAM, 3× NVMe 2 To (Samsung 990 PRO), RTX 5090 Blackwell (pilote propriétaire 610.43.02), TPM 2.0, GRUB, noyau 7.1.2‑arch3‑1, Secure Boot OFF, aucun swap.
1. Résumé & principe
L'utilisateur clique « Jouer à Valorant » dans FWS. FWS hiberne (RAM → swap disque) après avoir armé un boot one‑shot UEFI (BootNext) vers un Windows 11 bare‑metal installé sur une partition NTFS dédiée. Le firmware lance Windows directement (\EFI\Microsoft\Boot\bootmgfw.efi, jamais via GRUB) : Vanguard voit un vrai Windows natif. À la fermeture ou au crash de Valorant, Windows arme BootNext=FWS et reboote, le noyau voit resume= et reprend la session FWS intacte. C'est un dual‑boot bare‑metal des deux côtés — configuration que Vanguard tolère — avec BootOrder[0]=FWS comme filet de sûreté permanent.
2. Prérequis matériels / logiciels
Matériel (vérifié sur cible)
- UEFI en User Mode (SetupMode=0), db d'usine Microsoft présents, TPM 2.0, IOMMU activable au firmware (à confirmer dans le setup).
- 3× NVMe entièrement partitionnés, zéro espace non alloué (à re‑confirmer via
parted … print free). - GPU RTX 5090 : facteur critique d'hibernation (VRAM 32 Go) — voir §7.
Logiciels côté FWS (Arch)
- Paquets à ajouter :
sbsigntools/sbctl,efibootmgr,mokutil,wimlib,ntfs-3g,polkit,python-gobject,gtk3,nvidia/nvidia-utils+nvidia-hibernate/nvidia-resume(hooks S4 NVIDIA). - Interdits (casseraient l'hibernation) :
linux-hardened, patch auto‑lockdown Fedora,lockdown=en cmdline, initramfs systemd non planifié. - Invariants à figer en CI :
/sys/kernel/security/lockdown == [none],/sys/power/statecontientdisk, cmdline sanslockdown=.
Côté Windows (fourni par l'utilisateur, non bundlé)
- ISO Windows 11 légitime, TPM 2.0 + Secure Boot exigés par Riot, VBS/HVCI actifs (défaut 24H2).
3. Roadmap par phases
Phase 0 — Recon disque + firmware (root requis, BLOQUANT avant toute écriture)
for d in /dev/nvme0n1 /dev/nvme1n1 /dev/nvme2n1; do sudo parted "$d" unit MiB print free; sudo sgdisk -p "$d"; done
sudo lsblk -dpno NAME,SIZE,MODEL
Confirmer l'absence réelle d'espace libre → détermine chemin neuf (Anaconda) vs shrink post‑install. Dans le firmware : vérifier IOMMU (VT‑d/AMD‑Vi) actif et BIOS à jour (exigence Vanguard).
Phase 1 — Provisionner l'hibernation (chemin machine réelle : swapfile)
Sizing RAM + VRAM + marge = 96 GiB (et non 64 : la VRAM préservée est recopiée dans l'image — voir §7).
sudo mkswap -U clear --size 96G --file /swapfile
sudo chmod 600 /swapfile
sudo swapon /swapfile && swapon --show
# fstab : ajouter '/swapfile none swap defaults 0 0' ; supprimer la ligne /mnt/games2 dupliquée
N=$(sudo filefrag -v /swapfile | awk '$1=="0:"{print substr($4,1,length($4)-2)}') # resume_offset
sudo chattr +i /swapfile # fige l'offset (anti-dérive silencieuse)
UUID de reprise = FS hôte (racine) 84888eb3-cab9-407b-b407-ea4b3133c4a6, pas l'UUID interne du swap.
Phase 2 — Hook resume + cmdline
# /etc/mkinitcpio.conf : resume APRÈS block, AVANT filesystems (busybox, PAS systemd)
# HOOKS=(base udev autodetect keyboard keymap modconf block resume filesystems fsck)
sudo mkinitcpio -P
sudo lsinitcpio /boot/initramfs-linux.img | grep -i resume # doit matcher
# /etc/default/grub :
# GRUB_CMDLINE_LINUX_DEFAULT="loglevel=3 quiet resume=UUID=84888eb3-cab9-407b-b407-ea4b3133c4a6 resume_offset=N"
# GRUB_DISABLE_OS_PROBER=true (aucune entrée GRUB->Windows -> PCR4/PCR7 propres)
sudo grub-mkconfig -o /boot/grub/grub.cfg
Phase 3 — GPU NVIDIA (sans quoi le resume graphique est cassé)
# /etc/modprobe.d/nvidia-hibernate.conf
# options nvidia NVreg_PreserveVideoMemoryAllocations=1 NVreg_TemporaryFilePath=/var/tmp
sudo systemctl enable nvidia-suspend.service nvidia-hibernate.service nvidia-resume.service
Phase 4 — Valider l'hibernation AVANT de la câbler au bouton « Jouer »
sync; echo test_resume | sudo tee /sys/power/disk; sudo systemctl hibernate # non destructif
echo platform | sudo tee /sys/power/disk
# Puis cycle réel, SESSION GRAPHIQUE CHARGÉE (jeu/desktop lourd) :
sudo systemctl hibernate # rallumer
journalctl -b -1 -k | grep -iE 'PM: hibernation|Image saved|resume|Restarting tasks'
Critère de succès : session préservée et affichage NVIDIA intact au resume. Échec → le flux « Jouer » doit basculer en reboot propre (§7).
Phase 5 — Secure Boot signé, lockdown OFF (§4)
Phase 6 — Installateur : carve NTFS + outillage Windows (§6)
Phase 7 — Orchestrateur one‑shot + GUI (§5)
Phase 8 — Spike end‑to‑end sur ISO réelle : hibernate → BootNext → Windows → Valorant → retour FWS.
4. Point dur Secure Boot ↔ hibernation — SOLUTION RETENUE
Le nœud : Vanguard exige Secure Boot globalement au firmware → FWS doit aussi booter sous SB. Or Fedora/Ubuntu bloquent l'hibernation sous SB via le lockdown.
Fait établi et vérifié : sur noyau mainline Arch, activer Secure Boot n'arme PAS le lockdown. Le patch Garrett/Howells liant SB↔lockdown a été refusé upstream ; il est downstream Fedora/Ubuntu uniquement. Sur la cible : CONFIG_LOCK_DOWN_IN_EFI_SECURE_BOOT absent, CONFIG_LOCK_DOWN_KERNEL_FORCE_NONE=y, pas de LSM_EARLY, /sys/kernel/security/lockdown = [none]. Signer ≠ lockdown : ils sont orthogonaux.
Solution retenue : sbctl (clés db custom), en CONSERVANT les clés Microsoft. Justification : firmware déjà en User Mode avec db Microsoft → Windows boote sans y toucher ; friction minimale ; hook pacman de re‑signature intégré. On garde GRUB (pas d'UKI) : cmdline resume= éditable et PCR4 firmware stable à chaque MAJ noyau (favorable à un futur scellement TPM du swap LUKS). Voie alternative documentée : shim+MOK (modèle Ubuntu/Fedora, plus robuste sur OEM verrouillés, au prix d'un prompt MokManager) — à retenir si le firmware refuse l'enrôlement db custom.
sudo pacman -S sbctl
# PRÉREQUIS NON NÉGOCIABLE : le grubx64.efi installé n'a NI .sbat NI shim_lock -> réinstaller GRUB d'abord :
sudo grub-install --target=x86_64-efi --efi-directory=/boot --bootloader-id=GRUB \
--sbat /usr/share/grub/sbat.csv --modules='normal search part_gpt part_msdos fat ext2 configfile linux echo test true loadenv all_video efi_gop tpm'
objdump -h /boot/EFI/GRUB/grubx64.efi | grep -E 'sbat' # doit exister
# Setup Mode au firmware, puis :
sudo sbctl create-keys
sudo sbctl enroll-keys --microsoft # IMPÉRATIF : réinjecte MS -> Windows/OROM bootent
sudo sbctl sign -s /boot/EFI/GRUB/grubx64.efi
sudo sbctl sign -s /boot/vmlinuz-linux
sudo sbctl verify
ls /usr/share/libalpm/hooks/ | grep sbctl # re-signe après MAJ noyau/grub
Ordre impératif : signer avant d'activer SB au firmware. Après tout grub-install, re‑signer (il régénère un binaire non signé). Vérif post‑activation : bootctl status → SB enabled ; /sys/kernel/security/lockdown → [none] ; /sys/power/state contient disk.
5. Orchestration du boot
Invariant de sûreté : BootOrder[0]=FWS en permanence. BootNext (var UEFI one‑shot 8be4df61-93ca-11d2-aa0d-00e098032b8c) uniquement pour les transitions. Tout crash retombe sur FWS.
Aller FWS → Windows (/usr/local/bin/fws-gameboot to-windows, via pkexec)
Preflight avant toute écriture NVRAM — abort si un test échoue :
grep -q disk /sys/power/state || die 'hibernation indispo'
awk '/^SwapTotal/{s=$2}/^MemTotal/{m=$2}END{exit !(s>=m)}' /proc/meminfo || die 'swap < RAM'
# + garde VRAM (voir §7) : image projetée <= swap
grep -q 'resume=' /proc/cmdline || die 'resume= absent'
bootctl status 2>/dev/null | grep -qi 'Secure Boot: enabled' || die 'Secure Boot inactif'
WIN=$(efibootmgr | sed -n 's/^Boot\([0-9A-Fa-f]\{4\}\)\*\? Windows Boot Manager.*/\1/p' | head -1)
[ -n "$WIN" ] || die 'entrée Windows introuvable'
findmnt -rno TARGET -t ntfs3,ntfs | while read m; do umount "$m" || true; done # NTFS jamais rw persistante
efibootmgr -n "$WIN"
efibootmgr | grep -q "BootNext: $WIN" || { efibootmgr -N; die 'BootNext non écrit'; } # RELECTURE obligatoire
# Watchdog anti-hang (§7) autour de :
timeout 180 systemctl hibernate || { efibootmgr -N; die 'échec/hang hibernation'; }
Retour Windows → FWS (C:\ProgramData\FWS\fws-play.ps1, compte jeu autologin)
& "$PSScriptRoot\fws-return.ps1" -Target Windows # RE-ARME BootNext=Windows au boot -> crash/WU réatterrit sur Windows
Start-Process 'C:\Riot Games\Riot Client\RiotClientServices.exe' -ArgumentList '--launch-product=valorant','--launch-patchline=live'
do { Start-Sleep 5 } until (Get-Process VALORANT-Win64-Shipping -EA SilentlyContinue)
Get-Process VALORANT-Win64-Shipping -EA SilentlyContinue | Wait-Process # quit OU crash
& "$PSScriptRoot\fws-return.ps1" -Target FWS # pose BootNext=FWS
shutdown /r /t 0
Pose de BootNext côté Windows = écriture directe de la variable UEFI (SetFirmwareEnvironmentVariableExW + SeSystemEnvironmentPrivilege), repli bcdedit /set {fwbootmgr} bootsequence. Belt‑and‑suspenders : tâche ONSTART (SYSTEM) qui arme BootNext=FWS dès le boot (couvre les crashs), + hook GPO shutdown, + powercfg /h off (reboot plein, NTFS jamais sale).
À chaque boot FWS — fws-gameboot-bootfix.service (oneshot, ConditionPathExists=!/run/archiso)
Réasserte BootOrder[0]=FWS (auto‑guérison anti Windows Update) et réécrit le marqueur FAT <ESP>/EFI/FWS/return.json = {fws_bootnum, windows_bootnum} (les Boot#### bougent avec efibootmgr).
Filet ultime : même mécanisme Windows HS → BootOrder[0]=FWS ramène à FWS, image d'hibernation intacte (Windows ne touche jamais l'ext4).
6. Intégration installateur FWS
Deux chemins (la cible réelle est déjà installée, sans espace libre).
Chemin NEUF (Anaconda). Nouveau spoke fws_windows.py (clone exact de fws_desktop.py, découvert au runtime, aucun rebuild) : case « Dual‑boot Windows (Valorant) », combo disque, spin taille (défaut 200 GiO — Win11 ~40 + Valorant ~40 + updates ; min 100). Écrit /tmp/fws-windows. Le partitionnement NTFS se fait en %pre (blivet ne sait pas créer du NTFS) :
# %pre — REMPLACE le clearpart --all destructeur (voir §7). UEFI + enabled=1 requis :
sgdisk --zap-all "$DISK"
sgdisk -n1:0:+1GiB -t1:ef00 -c1:EFI "$DISK" # ESP >=1 GiO
sgdisk -n2:0:+96GiB -t2:8200 -c2:swap "$DISK" # swap DÉDIÉ = RAM+VRAM -> pas de resume_offset
sgdisk -n3:0:+${WIN_GIB}GiB -t3:0700 -c3:WINDOWS "$DISK" # slot NTFS (Microsoft basic data)
sgdisk -n4:0:0 -t4:8300 -c4:FWSROOT "$DISK"
partprobe "$DISK"; udevadm settle
mkfs.fat -F32 ${DISK}p1; mkswap ${DISK}p2; mkfs.ntfs -Q -L WINDOWS ${DISK}p3
ignoredisk --only-use=nvme2n1 # protège nvme0n1/nvme1n1 (games)
clearpart --none
part /boot --onpart=nvme2n1p1 --fstype=efi --noformat
part swap --onpart=nvme2n1p2 --noformat
part / --onpart=nvme2n1p4 --fstype=ext4
# nvme2n1p3 NON référencé -> NTFS intact ; en %post : resume=UUID=<swap> (partition dédiée, pas d'offset)
Chemin POST‑INSTALL (machine réelle) — fws-windows-setup. Shrink hors‑ligne, ordre load‑bearing (cibler un NVMe games pour garder la racine intacte) :
e2fsck -f /dev/nvme1n1p1
resize2fs /dev/nvme1n1p1 1550G # FS sous la taille finale
parted /dev/nvme1n1 resizepart 1 1560GiB # puis la partition
resize2fs /dev/nvme1n1p1 # re-remplit
sgdisk -n0:0:0 -t0:0700 -c0:WINDOWS /dev/nvme1n1
mkfs.ntfs -Q -L WINDOWS /dev/nvme1n1p2
Outillage Windows (aucun bundling).
fws-windows-media: clé USB Secure‑Boot‑propre depuis l'ISO de l'utilisateur.install.wim>4 GiO illégal en FAT32 → FAT32 +wimlib-imagex split install.wim /usb/sources/install.swm 3800(pas de uefi‑ntfs,bootmgfw.efisigné MS).fws-windows-postinstall: lit leBoot####« Windows Boot Manager » →/etc/fws/windows-boot-id;efibootmgr -o <FWS>,…,<Windows>(Setup Windows se remet en tête) ; vérifie SB/TPM2/VBS ; rappels DANS Windows :powercfg /h off, NE PAS activer BitLocker (ou suspendre aux bascules).
7. Risques & mitigations (revue adversariale intégrée)
| # | Sévérité | Problème | Mitigation retenue |
|---|---|---|---|
| 1 | BLOQUANT | clearpart --all --disklabel=msdos inconditionnel dans interactive-defaults.ks → efface les 3 NVMe (dont games) + force MBR sur UEFI. |
Ne jamais livrer l'ISO en l'état. %pre conditionné /sys/firmware/efi + ignoredisk --only-use + clearpart --none + part --onpart sur layout sgdisk. Protéger nvme0/1 explicitement. Tester sur ISO. |
| 2 | BLOQUANT | Resume GPU cassé : RTX 5090 Blackwell sans PreserveVideoMemoryAllocations → écran noir/corruption au S4. Design muet sur le GPU. |
NVreg_PreserveVideoMemoryAllocations=1 + NVreg_TemporaryFilePath ; nvidia-hibernate/resume actifs ; tester le resume session chargée AVANT de câbler le bouton ; fallback reboot obligatoire si échec (Phase 4). |
| 3 | Majeur | Swap = RAM ignore la VRAM recopiée (jusqu'à 32 Go) → image 75‑90 GiO > swap 64 → échec. | Swap = RAM + VRAM + marge = 96 GiO. Preflight : estimer VRAM en usage (nvidia-smi), refuser/basculer reboot si image projetée > swap. Tester pire cas (jeu déjà lancé côté Linux). |
| 4 | Majeur | Brick FWS par révocation dbx/SBAT poussée par Windows Update (précédents BootHole/SBAT réels). Windows booté fréquemment ici → risque élevé. | shim/grub à jour et re‑signés ; différer/figer Windows Update sur ce Windows gaming minimal ; tester bascule après chaque MAJ Windows/Vanguard ; fournir un média de récupération FWS (ré‑enrôlement/re‑signature). |
| 5 | Majeur | BitLocker auto‑activé par TPM+SB (Win11 24H2 Device Encryption) : le flip SB OFF→ON change PCR7 → écran de récupération, clé dans le compte MS. | Activer Secure Boot AVANT d'installer Windows (PCR7 stable dès l'install, pas de flip). Documenter : suspendre/désactiver BitLocker, sauvegarder la clé, powercfg /h off. Vérifier device‑encryption au postinstall et alerter. Nuance : les bascules BootNext récurrentes ne touchent PAS PCR7 (bootmgfw chargé à l'identique). |
| 6 | Majeur | systemctl hibernate qui hang (driver refuse S4) : machine allumée, session ni sauvée ni basculée, BootNext=Windows resté armé → départ surprise. |
⚠️ NON mitigeable en userspace : pendant un hang S4 le process (et tout watchdog) est gelé — un timeout est impossible (il tuerait aussi les hibernations réussies, qui ne rendent la main qu'au resume). Parades réelles : préflight strict (élimine les causes courantes) + auto-guérison au reset (BootNext=Windows → Windows → tâche ONSTART arme FWS → retour) + filet BootOrder[0]=FWS. Tester la robustesse S4 sur la carte ; documenter la récupération post-hang. |
| 7 | Majeur | Resume silencieux en échec (offset dérivé/image corrompue) → cold boot, session perdue sans notification. Incohérence swapfile+offset (fragile) vs partition dédiée (robuste). | Unifier sur partition swap dédiée dès que possible (chemin installeur) ; chattr +i sur tout swapfile résiduel ; revalider l'offset au preflight ET au retour ; notifier explicitement « session non restaurée » au cold boot post‑hibernation. |
| 8 | Majeur | Politique de fallback contradictoire entre docs (`hibernate | |
| 9 | Majeur | Sémantiques BootNext/BootOrder non validées (Windows pas installé) : firmware peut ignorer BootNext, réordonner, purger l'entrée FWS. Mapping bcdedit {fwbootmgr} → BootNext non documenté MS. |
Valider empiriquement dès la 1re install (écrire BootNext côté Windows, relire via efibootmgr côté Linux). Entrée de secours \EFI\BOOT\BOOTX64.EFI (grub-install --removable). Ne pas dépendre que de BootNext. |
| 10 | Majeur | Prérequis SB non résolu : grubx64.efi sans .sbat ni shim_lock → shim refuse GRUB ; grub-install régénère non signé. |
Réinstall GRUB (--sbat + modules) + signature avant d'activer SB ; hooks re‑signature couvrant linux + LTS/fallback ; vérifier objdump 'sbat' ; ne jamais activer SB sans sbverify OK (§4). |
| 11 | Mineur | Fondement « bit CPUID hyperviseur = 0 » FAUX : Zen 5 + Win11 24H2 → VBS/Hyper‑V actif, bit=1, toléré par Vanguard. | Ne pas combattre VBS. Corriger la doc : Vanguard vérifie SB actif + TPM présent + absence d'hyperviseur TIERS, pas un bit à 0. Valider que Valorant lance avec VBS on par défaut. |
| 12 | Mineur | SB sans lockdown côté Linux = conformité, pas défense : initramfs non signé, grub.cfg éditable, image d'hibernation en clair sur ext4. |
Assumer honnêtement (SB ici = case Vanguard). Durcissement hors‑MVP : UKI cmdline scellée, LUKS+TPM sur le swap (impose repartition). |
| 13 | Mineur | Risque fournisseur Vanguard (changement de politique) + overhead ~3‑5 min/session. | Compat annoncée best‑effort, re‑test après chaque bump. Offrir un mode « reboot simple » (sans hibernation) comme voie robuste par défaut, hibernation en confort opt‑in → réduit drastiquement la surface de brick/perte de session. |
8. Décisions ouvertes à trancher avec l'utilisateur
- Hibernation vs reboot simple par défaut. La couche hibernation ajoute VRAM/offset/resume fragiles pour ~3‑5 min gagnées. Recommandation revue : reboot simple robuste par défaut, hibernation opt‑in. À arbitrer (c'est un choix produit majeur).
- Swap : partition dédiée (repartition, robuste, sans offset) vs swapfile 96 GiO (aucun repartition, offset fragile). Sur la machine déjà pleine, swapfile pragmatique ; sur install neuve, partition dédiée. Unifier ?
- Chiffrement de l'image d'hibernation (MVP en clair vs LUKS+TPM d'emblée). Conditionne planning et gestion PCR.
- Voie Secure Boot :
sbctl(db custom, reco) vs shim+MOK (plus robuste OEM, prompt MokManager). Dépend de l'acceptation du firmware pour l'enrôlement db custom. - Disque Windows : shrink de la racine nvme2n1 (même NVMe que l'ESP) vs un NVMe games (nvme1n1, boot cross‑disque). Quel disque l'utilisateur sacrifie ?
- ESP partagée 512 MiO vs ESP Windows dédiée lors du carve‑out (512 MiO très juste avec bootmgfw + noyaux + marqueur
return.json). - NTFS pré‑formaté (
mkfs.ntfs -Q) vs espace non alloué + MSR pour des mesures PCR/BitLocker les plus propres (à trancher par test). - Retour auto (watcher WMI, risque heuristique AV) vs bouton manuel (défaut reco = manuel).
- Bootstrap Windows : FWS pilote l'install (autounattend/SetupComplete, le plus propre) vs RunOnce offline sur Windows existant.
- Politique clé de signature FWS : commune dans l'ISO (simple, fuite = compromission de flotte) vs générée par machine (sûre, non industrialisable en masse).
- Taille NTFS par défaut : 150 vs 200 GiO (recommandation : 200).
- Différer/figer Windows Update sur le Windows gaming (mitigation brick dbx/SBAT #4) — acceptable pour l'utilisateur ?
Portes bloquantes avant tout ship : (a) kickstart rendu non destructif et testé sur ISO ; (b) resume GPU NVIDIA validé session chargée ; (c) swap ≥ RAM+VRAM ; (d) GRUB signé+
.sbatavant activation SB ; (e)BootNextvalidé empiriquement sur la carte mère ; (f) média de récupération FWS prêt.