
disclaimer: claude ai generated

# Void Linux Full Install Guide
### LUKS2 + BTRFS + glibc + KDE Plasma (Wayland-only) + AMD graphics + full multimedia/audio + NetworkManager (Ethernet + Wi-Fi 7 + Bluetooth) + HP printing + Secure Boot + TPM2 + zero-maintenance kernel updates

Official reference: https://docs.voidlinux.org/

> Read this whole document once before typing anything. Disk commands below are destructive. Replace every placeholder (`/dev/sdX`, UUIDs, usernames, hostnames) with your real values. Where a step depends on your hardware (which NVMe/SATA device, which AMD GPU generation) I call it out.

---

## 0. Important design decisions (read first)

**LUKS2 vs GRUB.** GRUB's cryptodisk support only understands the PBKDF2 key-derivation function, not LUKS2's default Argon2id. If GRUB itself has to unlock your root partition, you are forced onto LUKS1. To get you *real* LUKS2 (Argon2id) as you asked for, this guide uses the standard workaround: a small **unencrypted `/boot`** partition holds the kernel + initramfs, GRUB only ever touches that unencrypted partition, and **dracut** (which fully supports LUKS2) does the actual decryption inside the initramfs before switching to your encrypted BTRFS root. This is the same architecture Fedora/Ubuntu use by default. Your passphrase still protects everything except the kernel image and initramfs blob itself (which are signed under Secure Boot anyway, see §8).

**No systemd.** Void uses **runit**. This matters for two things you asked about:
- TPM-backed auto-unlock will use **clevis + tpm2-tools** (works from dracut, not `systemd-cryptenroll`, which doesn't exist here).
- Automatic kernel-update hooks are **already built into Void** via `/etc/kernel.d/{pre,post}-install`, run automatically by `xbps-reconfigure` whenever a kernel package is installed/updated. You don't need to build this yourself — see §11.

**"No Xorg" — what's actually true and what isn't.** You will run a pure Wayland *session* (`startplasma-wayland` via KWin's own compositor, no X server rendering your desktop). Two honest caveats so nothing surprises you:
- Void's `sddm` package currently has a real dependency on `xorg-server` due to a packaging quirk (tracked upstream as void-packages#21862) — it gets pulled onto disk regardless, but it is **not used** to draw your session; SDDM's greeter and your Plasma session both run on Wayland via `startplasma-wayland`. There is no way around this dependency on Void today without dropping SDDM for something like `greetd` — not worth the hassle for what's essentially a few MB of idle binaries.
- **XWayland** (package `xorg-server-xwayland`) will be pulled in as a dependency of KWin regardless. This is not "running Xorg" — it's a compatibility shim so the handful of apps that still haven't ported to native Wayland (some older Java/Electron apps, screen-sharing tools, etc.) can still run inside your Wayland session. Nothing about your actual desktop, compositing, or input runs through a real X server.

If literally zero X-related binaries on disk is a hard requirement, that's not achievable with KDE+SDDM on Void today — say so and I'll point you to a `greetd`+`tuigreet`+`sway`/pure-wlroots alternative instead, which is a materially different setup than what's below.

**Verify package names before you fly blind.** Void's repo changes over time. Before installing anything unfamiliar, check it actually exists:
```
xbps-query -Rs <name>
```
I've marked the packages worth double-checking this way (clevis, tpm2-tools, sbctl) with ⚠.

---

## 1. Prepare install media

1. Download the current glibc live ISO (KDE flavor is fine, or the base ISO) from https://voidlinux.org/download/
2. Verify checksum (`sha256sum`) against the published `sha256sum.txt`.
3. Write it to a USB stick:
   ```
   dd if=void-live-x86_64-<date>.iso of=/dev/sdX bs=4M status=progress oflag=sync
   ```
4. In your BIOS/UEFI: enable UEFI boot, **disable Secure Boot for now** (you'll re-enable it in §8 with your own keys), make sure TPM2 is enabled, boot the USB.
5. Log in as `root` (password `voidlinux`), get networking up:
   ```
   ip link set up <interface>
   # wired: dhcpcd <interface>
   # wifi:
   wpa_passphrase <SSID> <password> > /etc/wpa_supplicant/wpa_supplicant-<interface>.conf
   wpa_supplicant -B -i <interface> -c /etc/wpa_supplicant/wpa_supplicant-<interface>.conf
   dhcpcd <interface>
   ```

---

## 2. Partition the disk

Identify your target disk with `lsblk`. Examples below use `/dev/nvme0n1`; if you're on SATA it'll be `/dev/sda` and partitions are `/dev/sda1` etc. (drop the `p`).

Layout:
| Partition | Size | Type | Purpose |
|---|---|---|---|
| p1 | 512 MiB | EFI System Partition | GRUB/UEFI |
| p2 | 1 GiB | ext4 | unencrypted `/boot` (kernel+initramfs) |
| p3 | remainder | LUKS2 container | BTRFS root |

```
wipefs -af /dev/nvme0n1
fdisk /dev/nvme0n1
```
In fdisk: `g` (GPT) → `n` (default, +512M) → `t` `1` (EFI System) → `n` (default, +1G) → `n` (default, rest of disk) → `w`

Format ESP and /boot:
```
mkfs.vfat -F32 -n EFI /dev/nvme0n1p1
mkfs.ext4 -L boot /dev/nvme0n1p2
```

---

## 3. LUKS2 encryption

```
cryptsetup luksFormat --type luks2 --cipher aes-xts-plain64 --key-size 512 \
  --hash sha512 --pbkdf argon2id --label cryptroot /dev/nvme0n1p3
```
Type `YES` (uppercase), set a strong passphrase — this is your master passphrase, keep it memorable, you'll seal a duplicate key to the TPM later so day-to-day you won't type it.

Open it:
```
cryptsetup open /dev/nvme0n1p3 cryptroot
```

---

## 4. BTRFS and subvolumes

```
mkfs.btrfs -L void /dev/mapper/cryptroot
mount /dev/mapper/cryptroot /mnt
btrfs subvolume create /mnt/@
btrfs subvolume create /mnt/@home
btrfs subvolume create /mnt/@snapshots
btrfs subvolume create /mnt/@var_log
btrfs subvolume create /mnt/@var_cache_xbps
btrfs subvolume create /mnt/@var_tmp
btrfs subvolume create /mnt/@srv
umount /mnt
```

Remount using the real subvolumes:
```
BTRFS_OPTS="rw,noatime,compress=zstd:1,ssd,space_cache=v2"

mount -o ${BTRFS_OPTS},subvol=@ /dev/mapper/cryptroot /mnt
mkdir -p /mnt/{home,.snapshots,var/log,var/cache/xbps,var/tmp,srv,boot,efi}
mount -o ${BTRFS_OPTS},subvol=@home        /dev/mapper/cryptroot /mnt/home
mount -o ${BTRFS_OPTS},subvol=@snapshots   /dev/mapper/cryptroot /mnt/.snapshots
mount -o ${BTRFS_OPTS},subvol=@var_log     /dev/mapper/cryptroot /mnt/var/log
mount -o ${BTRFS_OPTS},subvol=@var_cache_xbps /dev/mapper/cryptroot /mnt/var/cache/xbps
mount -o ${BTRFS_OPTS},subvol=@var_tmp     /dev/mapper/cryptroot /mnt/var/tmp
mount -o ${BTRFS_OPTS},subvol=@srv         /dev/mapper/cryptroot /mnt/srv

mount /dev/nvme0n1p2 /mnt/boot
mkdir -p /mnt/boot/efi
mount /dev/nvme0n1p1 /mnt/boot/efi
```
Drop `ssd` from `BTRFS_OPTS` if you're on a spinning disk. If this is a laptop with only one NVMe drive, `ssd` is correct.

---

## 5. Install the base system (glibc)

Pick a nearby mirror from https://xmirror.voidlinux.org/ or just use the default:

```
xbps-install -Sy -R https://repo-default.voidlinux.org/current -r /mnt \
  base-system btrfs-progs cryptsetup grub-x86_64-efi
```
This is the **glibc** repo path (not `/current/musl`), matching your requirement.

Copy your live-session's package signing keys so the chroot trusts the repo without re-fetching:
```
mkdir -p /mnt/var/db/xbps/keys
cp /var/db/xbps/keys/* /mnt/var/db/xbps/keys/
```

---

## 6. Chroot and configure the base system

```
mount -t proc proc /mnt/proc
mount -t sysfs sys /mnt/sys
mount --rbind /dev /mnt/dev
mount --rbind /run /mnt/run
cp -L /etc/resolv.conf /mnt/etc/
chroot /mnt /bin/bash
```

Inside the chroot:
```
passwd root
echo myhostname > /etc/hostname
```

`/etc/rc.conf`:
```
cat <<'EOF' > /etc/rc.conf
HARDWARECLOCK="UTC"
TIMEZONE="Europe/Berlin"
KEYMAP="us"
EOF
```
(swap `Europe/Berlin` and `KEYMAP` for your own; timezones live under `/usr/share/zoneinfo`.)

Locales (glibc needs this explicitly):
```
echo 'en_US.UTF-8 UTF-8' >> /etc/default/libc-locales
echo 'LANG=en_US.UTF-8' > /etc/locale.conf
xbps-reconfigure -f glibc-locales
```

fstab — get the UUIDs first:
```
EFI_UUID=$(blkid -s UUID -o value /dev/nvme0n1p1)
BOOT_UUID=$(blkid -s UUID -o value /dev/nvme0n1p2)
ROOT_UUID=$(blkid -s UUID -o value /dev/mapper/cryptroot)

cat <<EOF > /etc/fstab
UUID=$ROOT_UUID / btrfs ${BTRFS_OPTS},subvol=@ 0 1
UUID=$ROOT_UUID /home btrfs ${BTRFS_OPTS},subvol=@home 0 2
UUID=$ROOT_UUID /.snapshots btrfs ${BTRFS_OPTS},subvol=@snapshots 0 2
UUID=$ROOT_UUID /var/log btrfs ${BTRFS_OPTS},subvol=@var_log 0 2
UUID=$ROOT_UUID /var/cache/xbps btrfs ${BTRFS_OPTS},subvol=@var_cache_xbps 0 2
UUID=$ROOT_UUID /var/tmp btrfs ${BTRFS_OPTS},subvol=@var_tmp 0 2
UUID=$ROOT_UUID /srv btrfs ${BTRFS_OPTS},subvol=@srv 0 2
UUID=$BOOT_UUID /boot ext4 defaults,noatime 0 2
UUID=$EFI_UUID /boot/efi vfat defaults,noatime 0 2
tmpfs /tmp tmpfs defaults,nosuid,nodev 0 0
EOF
```
Note `$BTRFS_OPTS` needs to be re-exported inside the chroot shell too (`export BTRFS_OPTS="rw,noatime,compress=zstd:1,ssd,space_cache=v2"`) since it's a new shell.

---

## 7. dracut config so LUKS2 + BTRFS unlock correctly

```
LUKS_UUID=$(blkid -s UUID -o value /dev/nvme0n1p3)

mkdir -p /etc/dracut.conf.d
cat <<EOF > /etc/dracut.conf.d/10-crypt-btrfs.conf
add_dracutmodules+=" crypt btrfs "
hostonly="yes"
EOF
```
Kernel command line needs to know where the encrypted root is. Edit `/etc/default/grub`:
```
GRUB_CMDLINE_LINUX_DEFAULT="rd.luks.name=$LUKS_UUID=cryptroot root=/dev/mapper/cryptroot rootflags=subvol=@"
```
`rd.luks.name=<uuid>=<name>` both tells dracut which LUKS container to unlock *and* what to call the resulting `/dev/mapper/<name>` device, in one directive — that's why `root=/dev/mapper/cryptroot` matches up correctly. (Some guides also add a separate `rd.luks.uuid=` line; don't — combined with `rd.luks.name` for the same UUID it's redundant, and if you accidentally prefix the UUID with `luks-` there it's simply wrong syntax and will fail to activate at boot. One directive is enough.)

You do **not** need `GRUB_ENABLE_CRYPTODISK=y` — that's only for when GRUB itself must read an encrypted `/boot`, which isn't the case here since `/boot` is plain ext4.

You do not need to run `dracut` by hand right now — it happens automatically in the next step when you install the kernel package (see §11 for why this stays automatic forever after).

---

## 8. Install kernel, GRUB, and set up Secure Boot + TPM2

```
xbps-install -Sy linux linux-firmware
```
This pulls in the `linux` metapackage, triggers dracut, and builds your first initramfs automatically.

Install GRUB to the ESP:
```
grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id="Void" --recheck
grub-mkconfig -o /boot/grub/grub.cfg
```

### Secure Boot with your own keys (sbctl)

Void ships `sbctl` (Foxboron's tool) for this. ⚠ verify it's present: `xbps-query -Rs sbctl`.
```
xbps-install -Sy sbctl
```
Reboot is required to put the firmware in **Setup Mode** (clear the Platform Key) — do this after you finish the base install and can reboot into firmware settings (`Reboot to Firmware`/`Setup Mode` in your BIOS Secure Boot menu, or from a booted system: `systemctl reboot --firmware-setup` doesn't exist here without systemd, so do it manually from the firmware menu).

Once in Setup Mode, back in Void:
```
sbctl create-keys
sbctl enroll-keys -m        # -m also enrolls Microsoft's keys, needed on most boards
                             # for option-ROMs / dGPU firmware to still validate
sbctl sign -s /boot/vmlinuz-<version>          # replace <version> with your actual kernel version, e.g. ls /boot/vmlinuz-*
sbctl sign -s /boot/efi/EFI/Void/grubx64.efi   # the GRUB EFI binary that grub-install placed on the ESP
```
Run `sbctl verify` afterward — it lists every EFI-chain file it's tracking and shows a ✘/✔ per file, so you can confirm nothing is left unsigned before you re-enable enforcement. Then run `sbctl status` to confirm Secure Boot is active. Reboot and re-enable Secure Boot enforcement in the firmware.

Because kernels get replaced on every update, you need re-signing to happen automatically too — see §11, which wires an `/etc/kernel.d/post-install` hook to call `sbctl sign` on every new kernel.

### TPM2 auto-unlock (clevis)

⚠ verify availability first: `xbps-query -Rs clevis tpm2-tools`.
```
xbps-install -Sy clevis clevis-luks tpm2-tools
```
Bind your LUKS2 volume to the TPM, tying the unlock to PCR 7 (Secure Boot state) — this means the disk will *only* auto-unlock while Secure Boot is intact and your keys haven't changed, and will refuse (falling back to passphrase) if someone tampers with the boot chain:
```
clevis luks bind -d /dev/nvme0n1p3 tpm2 '{"pcr_bank":"sha256","pcr_ids":"7"}'
```
Enter your LUKS passphrase when prompted. This adds a new key slot; your original passphrase remains valid as a fallback (keep it — TPM state can change on firmware/BIOS updates and lock you out of auto-unlock until you rebind).

Enable the clevis dracut module and rebuild the initramfs:
```
cat <<EOF > /etc/dracut.conf.d/20-clevis.conf
add_dracutmodules+=" crypt clevis "
EOF
dracut --force --hostonly
```

At boot, dracut will try clevis/TPM first and silently fall back to a passphrase prompt if the TPM refuses to release the key — you're never locked out, just back to typing the passphrase.

---

## 9. Create your user, reboot into the installed system

```
xbps-install -Sy shadow
useradd -m -G wheel,audio,video,input,kvm -s /bin/bash <username>
passwd <username>
EDITOR=nano visudo   # uncomment the %wheel line
xbps-reconfigure -fa
exit
```
Back in the live environment:
```
umount -R /mnt
reboot
```
Remove the USB stick before it boots. If you skipped Secure Boot enrollment above, do it now while things are simple; if you already enrolled, this boot should just work under Secure Boot.

---

## 10. KDE Plasma (Wayland-only), AMD graphics, networking, Bluetooth, printing, and multimedia

Log in as root or use `sudo` from your new user for everything below.

### 10.1 Extra repos (firmware + 32-bit for gaming/Wine if relevant)
```
xbps-install -Sy void-repo-nonfree void-repo-multilib
xbps-install -Sy
```

### 10.2 AMD graphics (Mesa/amdgpu — Wayland needs no Xorg driver at all)
```
xbps-install -Sy linux-firmware-amd mesa-dri mesa-vulkan-radeon vulkan-loader mesa-vaapi libva-utils
```
- `linux-firmware-amd` — required GPU firmware blobs (won't POST past a black screen without this on most RDNA/GCN cards).
- `mesa-vulkan-radeon` — RADV Vulkan driver.
- `mesa-dri` — provides the KMS/DRM GBM backend KWin's Wayland compositor talks to directly. On Wayland you do **not** install `xf86-video-amdgpu` at all — that package is purely an Xorg driver and is irrelevant to a Wayland session.
- `mesa-vaapi` + set `LIBVA_DRIVER_NAME=radeonsi` in your shell profile — hardware video decode (used by mpv, Firefox, VLC).

If you have a very new AMD GPU (RDNA3/4-era) and the live kernel is too old to recognize it, install a newer kernel series first (`xbps-query -Rs linux6` to see what's on offer) before you fight black-screen issues.

### 10.3 KDE Plasma, Wayland-only
```
xbps-install -Sy kde-plasma kde-baseapps sddm dbus elogind polkit xorg-server-xwayland
```
Notice there's no `xorg`/`xorg-minimal` in that list. `xorg-server-xwayland` is the compatibility shim discussed in §0 — it lets stray X11-only apps run inside your Wayland session; it never provides your actual desktop rendering. `sddm` will still quietly depend on `xorg-server` per §0's caveat — that's a dependency resolution artifact, not something you configure or run.

Force SDDM to default to the Wayland session (otherwise it defaults to X11 on Void):
```
mkdir -p /etc/sddm.conf.d
cat <<'EOF' > /etc/sddm.conf.d/10-wayland.conf
[General]
DisplayServer=wayland

EOF
```
This alone is enough to make the greeter default to Wayland — confirm the session dropdown says "Plasma (Wayland)" and not "Plasma (X11)" the first time you log in, and switch it manually if it doesn't. (If you want unattended autologin later, that's a separate `[Autologin]` block with a `Session=` value taken from the actual filename in `/usr/share/wayland-sessions/` on your system — check that directory rather than guessing the name, since it can differ slightly by SDDM/Plasma version.)

Enable the runit services:
```
ln -s /etc/sv/dbus /var/service/
ln -s /etc/sv/sddm /var/service/
ln -s /etc/sv/polkitd /var/service/ 2>/dev/null || true
```
(If your Void install uses `/etc/runit/runsvdir/default` instead of `/var/service`, symlink there instead — check with `ls -ld /var/service` first; both point to the same place on modern Void.)

### 10.4 Networking: NetworkManager for Ethernet + Wi-Fi 7, on your NVMe/RJ45+wireless setup

You mentioned wired RJ45 as primary with a Wi-Fi 7 card for some scenarios — NetworkManager handles switching between and prioritizing both natively, no separate config needed for the "sometimes wifi" use case.

```
xbps-install -Sy NetworkManager network-manager-applet
ln -s /etc/sv/NetworkManager /var/service/
```
Void's base system already ships `wpa_supplicant` (installed by default), and NetworkManager uses it as its Wi-Fi backend out of the box — this is the simpler, better-supported path and what this guide uses. **Do not** also enable the standalone `wpa_supplicant` or `dhcpcd` runit services — NetworkManager runs its own internal supplicant instance and the two will fight over the interface if both are enabled as separate services.

Wi-Fi 7 (802.11be) support is a function of your **kernel + card driver + firmware**, not of NetworkManager/wpa_supplicant, which are protocol-version-agnostic. Identify your card and check its driver has the firmware installed:
```
lspci -k | grep -A3 -i network      # PCIe/M.2 wifi cards
lsusb -v 2>/dev/null | grep -i wireless   # USB wifi cards
```
Common Wi-Fi 7 chipsets and the firmware package each needs:
- Intel (BE200/BE202) → `linux-firmware-intel` (uses `iwlwifi`, in-tree, no separate driver package needed).
- MediaTek (MT7925/MT7927) → `linux-firmware-network` (uses `mt7925e`/`mt76` family, in-tree).
- Qualcomm/Atheros → `linux-firmware-network`.
If `lspci -k` doesn't show a `Kernel driver in use` line for your card, you're on a kernel too old for that chipset — check `xbps-query -Rs linux6` for a newer series before assuming the card is broken.

WPA3/SAE (used by most Wi-Fi 7 APs by default) works out of the box through NetworkManager+wpa_supplicant with no extra config — just connect via `nmtui`, `nmcli`, or the Plasma network widget once you're in KDE.

Manage connections from the console before you have a desktop, if needed:
```
nmtui
```

### 10.5 Bluetooth
```
xbps-install -Sy bluez libspa-bluetooth
ln -s /etc/sv/bluetoothd /var/service/
usermod -aG bluetooth <username>
```
`libspa-bluetooth` is the PipeWire-side plugin — it's what actually lets Bluetooth headsets/speakers show up as PipeWire audio sinks; `bluez-alsa` (mentioned in some guides) is only for plain ALSA setups and not needed here since you're on PipeWire. Pair devices with `bluetoothctl`, or from Plasma's Bluetooth widget once logged in (KDE's `bluedevil` component is pulled in by `kde-plasma` already).

### 10.6 Printing (HP)
```
xbps-install -Sy cups cups-filters hplip avahi nss-mdns system-config-printer cups-pk-helper
ln -s /etc/sv/cupsd /var/service/
ln -s /etc/sv/avahi-daemon /var/service/
usermod -aG lpadmin <username>
```
- `hplip` is HP's own driver/toolchain — required for HP printers per Void's own printing docs.
- `avahi` + `nss-mdns` give you automatic discovery of network/Wi-Fi printers (mDNS/Bonjour) — without this you'd have to type the printer's IP manually.
- Run the guided setup once your printer is powered on and networked (Wi-Fi, Ethernet, or USB all work):
  ```
  hp-setup
  ```
  Accepting the tool's defaults is normally correct. For a plugin-requiring HP model (some LaserJets need a proprietary plugin blob), the same tool will offer to fetch it — allow it if prompted.
- Alternatively, once CUPS is running, open `http://localhost:631` in a browser and add the printer via the web UI (log in with a user in the `lpadmin` group).
- Most HP printers from the last ~10 years also support driverless **IPP Everywhere**, in which case plain `cups`+`cups-filters`+`avahi` finds and configures them with no driver package at all — try that first via the CUPS web UI before reaching for `hplip`.

### 10.7 Audio (PipeWire, replacing PulseAudio entirely)
```
xbps-install -Sy pipewire wireplumber alsa-pipewire pulseaudio-utils pavucontrol-qt
```
Route ALSA through PipeWire:
```
mkdir -p /etc/alsa/conf.d
ln -s /usr/share/alsa/alsa.conf.d/50-pipewire.conf /etc/alsa/conf.d
ln -s /usr/share/alsa/alsa.conf.d/99-pipewire-default.conf /etc/alsa/conf.d
```
Enable the PulseAudio-compatibility server (most apps still speak PulseAudio, not raw PipeWire) and WirePlumber:
```
mkdir -p /etc/pipewire/pipewire.conf.d
ln -s /usr/share/examples/pipewire/20-pipewire-pulse.conf /etc/pipewire/pipewire.conf.d/
ln -s /usr/share/examples/wireplumber/10-wireplumber.conf /etc/pipewire/pipewire.conf.d/
```
KDE's Plasma session starts a D-Bus user session and will autostart `pipewire` via the XDG Desktop Application Autostart entry the package ships (`/usr/share/applications/pipewire.desktop`) — no manual runit service needed for a per-user desktop session. Reboot, log into Plasma via SDDM (confirm it's the Wayland session), open the KDE audio widget, and it should show your outputs immediately.

### 10.8 Full multimedia (codecs, video, hardware playback)
```
xbps-install -Sy gst-plugins-base1 gst-plugins-good1 gst-plugins-bad1 gst-plugins-ugly1 \
  gst-libav1 ffmpeg libdvdcss mpv vlc
```
- The four `gst-plugins-*` tiers cover the practical entirety of everyday container/codec support (MP4/H.264/H.265/AV1/VP9/Opus/AAC/MP3, etc.) for GStreamer-based apps (most GTK media players, some Electron apps' video paths).
- `gst-libav1` + `ffmpeg` — broadest possible decode/encode coverage, including formats the other tiers don't ship for licensing reasons.
- `libdvdcss` — only relevant if you actually play encrypted DVDs; skip it otherwise.
- `mpv`/`vlc` both use `mesa-vaapi` (already installed in §10.2) automatically for hardware-accelerated decode on your AMD GPU under Wayland — verify with `mpv --hwdec=auto your_file.mp4` and check `Using hardware decoding` in the mpv OSD/console output.

---

## 11. Making updates fully hands-off (kernel, initramfs, GRUB, Secure Boot signatures)

This is the part you specifically asked about. Good news: most of it is **already automatic** in Void; you only need to add one hook for Secure Boot re-signing.

**Already automatic, no action needed:** Void's kernel packages ship hooks in `/etc/kernel.d/{pre-install,post-install,pre-remove,post-remove}`. Every time you run `xbps-install -Su` and it pulls a new `linux6.x` kernel, `xbps-reconfigure` runs these hooks for you: it rebuilds the initramfs with dracut and refreshes `grub.cfg`. You never have to run `dracut` or `grub-mkconfig` by hand after a normal update.

**What you must add yourself: re-signing for Secure Boot.** sbctl doesn't yet have an official Void kernel hook, so wire one up:

```
cat <<'EOF' > /etc/kernel.d/post-install/95-sbctl-sign
#!/bin/sh
# Re-sign every installed kernel and the GRUB EFI binary for Secure Boot.
# Deliberately glob over /boot instead of relying on a positional argument for the
# kernel version — Void's kernel.d hook argument-passing isn't guaranteed stable
# across versions, and a glob is simple, idempotent, and can't silently skip a kernel.
if command -v sbctl >/dev/null 2>&1; then
    for k in /boot/vmlinuz-*; do
        [ -f "$k" ] && sbctl sign -s "$k" || true
    done
    sbctl sign -s /boot/efi/EFI/Void/grubx64.efi || true
fi
EOF
chmod +x /etc/kernel.d/post-install/95-sbctl-sign
```
Test it once by hand right after creating it (`/etc/kernel.d/post-install/95-sbctl-sign`) and run `sbctl verify` afterward to confirm it actually signed things — don't just trust it blindly the first time. Now `xbps-install -Su` → new kernel → dracut rebuild → grub.cfg refresh → sbctl re-sign, all in one command, every time.

**Your regular update command, going forward, is just:**
```
sudo xbps-install -Su
```
Reboot when it pulls a new kernel. That's it — no separate dracut/grub-mkconfig/sbctl steps.

**One manual gotcha to know about:** if you ever *rebind* the TPM (§8, after a firmware update invalidates PCR 7), that step is inherently manual — nobody can automate "trust this new boot state" without defeating the point of measured boot. You'll simply be prompted for your LUKS passphrase at boot until you rerun `clevis luks bind`.

**Old kernel cleanup:** since `/boot` is a separate 1 GiB partition, old kernels will eventually fill it and updates will start failing. Periodically remove old `linux6.x` series you're not using:
```
xbps-remove linux6.<old-minor>
```
or just size `/boot` larger up front (2 GiB) if you'd rather not think about it.

---

## 12. Sanity checks after everything is set up

```
lsblk -f                          # confirms crypto_LUKS + btrfs subvolumes mounted correctly
cryptsetup luksDump /dev/nvme0n1p3     # confirms LUKS2 + argon2id + your clevis token slot
sbctl status                      # confirms Secure Boot enrolled + enforcing
clevis luks list -d /dev/nvme0n1p3     # confirms TPM binding present
wpctl status                      # confirms PipeWire sees your audio devices
echo $XDG_SESSION_TYPE            # must print "wayland", not "x11" — confirms you're actually in the Wayland session
vulkaninfo --summary | grep deviceName   # confirms RADV/amdgpu is the active Vulkan device
eglinfo | grep "OpenGL renderer"  # Wayland-native equivalent of glxinfo; xf86-video-amdgpu is not installed so glxinfo/Xorg tools aren't relevant here
nmcli device status               # confirms both Ethernet and Wi-Fi interfaces are managed by NetworkManager
bluetoothctl show                 # confirms the Bluetooth controller is powered and visible
lpstat -p -d                       # confirms CUPS sees your HP printer as configured
```

If `eglinfo`/`vulkaninfo` shows `llvmpipe`/software rendering instead of your GPU name, `linux-firmware-amd` or the kernel version is the usual culprit — check `dmesg | grep amdgpu` for firmware load failures.

---

### Summary of what you now have
- BTRFS root on a genuine **LUKS2** (Argon2id) container, unlocked by dracut, not GRUB.
- Subvolume layout with snapshots directory ready for `btrfs subvolume snapshot` or `snapper`.
- glibc userland, KDE Plasma running its native **Wayland** session via SDDM (XWayland present only as an X11-app compatibility shim, not driving your desktop).
- AMD Mesa/RADV/amdgpu stack, Vulkan + VA-API hardware video decode, no Xorg driver package installed.
- NetworkManager handling both your wired RJ45 connection and Wi-Fi 7 card (WPA3/SAE out of the box), Bluetooth via `bluez` + PipeWire's `libspa-bluetooth`.
- CUPS + `hplip` for your HP printer, with Avahi/mDNS network discovery.
- Full multimedia codec coverage (GStreamer tiers + ffmpeg) with hardware-accelerated playback in mpv/VLC.
- PipeWire fully replacing PulseAudio, wired for KDE's autostart.
- Secure Boot enforced with your own keys via `sbctl`.
- TPM2-sealed auto-unlock via `clevis`, with passphrase fallback.
- `xbps-install -Su` alone regenerates initramfs, GRUB config, and Secure Boot signatures on every kernel update — nothing else to remember.
