Skip to main content

How the PS5 Bazzite Deck image is built

PS5 Bazzite Deck has two parts: a kernel package, built with the official ps5-linux-image builder from a recent stable kernel, rmuxnet's PS5 patch set and its own patches on top; and a bootc image, Bazzite's Steam Deck image with that kernel, the PS5 services and its own Vulkan driver (RADV) build. This page is for anyone making an image: the kernel config changes it needs, the patch order, and the upstream repositories it tracks. Users don't need any of it.

Patch base

The stable kernel named in the patch set's .config, plus rmuxnet/ps5-linux-patches-1 at a pinned commit, then the image's patches in the order of patches/series. Each release ships a VERSIONS.md with the exact pins and a local-changes.diff with the changes to the builder.

Why Game Mode needs the BPF LSM and kernel BTF​

Bazzite's Game Mode starts Steam through the cardwired service, which loads an eBPF program. That needs two kernel features:

  1. The BPF LSM. CONFIG_BPF_LSM=y on its own does nothing; bpf has to be in CONFIG_LSM, or lsm=landlock,lockdown,yama,integrity,apparmor,bpf on the command line.
  2. Kernel BTF. CONFIG_DEBUG_INFO_BTF=y, so that /sys/kernel/btf/vmlinux exists.

Without them cardwired crash-loops with CardwireEbpfError(LSMNotEnabled) or error parsing /sys/kernel/btf/vmlinux, Gamescope is killed a second after it starts, and after five attempts Bazzite drops to the desktop. The same applies to any image that runs Bazzite's or SteamOS's Game Mode session. Confirmed; this was the reason Bazzite Game Mode never worked on the PS5 before.

CONFIG_MODULE_ALLOW_BTF_MISMATCH=y lets a kernel-only hotfix load the release's modules.

Kernel config changes​

Applied to the patch set's .config before the build:

OptionValueWhy
CONFIG_SUSPENDySuspend-to-idle
CONFIG_LSMlandlock,lockdown,yama,integrity,apparmor,bpfGame Mode, above
CONFIG_DEBUG_INFO_BTFyGame Mode, above
CONFIG_MODULE_ALLOW_BTF_MISMATCHyHotfix kernels keep loading release modules
CONFIG_MT7921EmMediaTek Wi-Fi on the Slim (the official config has it now too)
CONFIG_USB_AUTOSUSPEND_DELAY-1USB never sleeps: the Bluetooth chips and the Salina xHCI don't survive it
CONFIG_LOG_BUF_SHIFT201 MiB boot log, so the early HDMI chip and Pro firmware lines don't scroll out of reports
CONFIG_PS5_GPUFREQnot setrmuxnet's GPU clock driver, replaced by the upstream governor
CONFIG_LOGITECH_FF and the other Logitech _FF optionsyWheel force feedback

Patch order​

The order matters: later patches are written against the tree state the earlier ones leave. build.sh first gives the out-of-tree IW620 Wi-Fi driver its compatibility patches for the kernel version, then applies rmuxnet's linux.patch and the files in patches/series in this order:

  1. Suspend-to-idle: Dasloh's pull request.
  2. Display: the FLAVA3 and VERDE display stack: 4K120 over FRL, 1440p, VRR. Explained on Display and HDMI.
  3. 100 Hz modes behind hdmi.modes_100hz=1.
  4. GPU: the thermal GPU clock governor.
  5. Fan: no fan spike at shutdown, then firmware fan control with an 80 °C target by default and the kernel curve as an option. See Fan control.
  6. PS5 Pro: Bluetooth and the CPU clock. See PS5 Pro.
  7. MediaTek Bluetooth: no ISO interface setup.

Every patch file starts with a description of what it does and why.

Not in the image any more: the IW620 legacy LE workaround

rmuxnet's repository has a change that marks the IW620's extended LE commands as broken so keyboards and mice reconnect. On that chip it stops Bluetooth from finding new devices, because the scan then uses the legacy commands while advertising still uses the extended ones, see Bluetooth. The image dropped it; an image that takes rmuxnet's patch set as is inherits it.

Files baked into the image​

Not kernel changes, but an image needs them too: a stable MAC for NetworkManager on the IW620, udev rules that keep the Bluetooth chips and the Salina xHCI powered, the DefaultDependencies=no drop-in for ps5-stage-firmware.service (see Modules or sysctl settings not loading), the Linux-only Bluetooth address and connectable services (see Bluetooth), hidp loaded at boot, the warm-reboot units (see Warm reboots), and the Pro firmware staging (see PS5 Pro). All under files/.

Upstream repositories to track​

RepositoryWhat it carries
ps5-linux/ps5-linux-patchesThe official kernel patches, a package per commit: Pro GPU and governor, fan curve, HDMI work, VCN
rmuxnet/ps5-linux-patches-1The port to the newer stable kernel the image builds on. His default branch has the fan curve on by default, reworked clock drivers, his Bluetooth patches and build.sh, see Kernel setup
Slip-Up/ps5-linux-patchesThe HDMI work: native FRL, ALLM, modes
ps5-linux/ps5-linux-mwifiexThe IW620 Wi-Fi driver
ps5-linux/ps5-linux-imageThe image builder, including Pro GPU firmware staging
QuartConz/ps5-pro-viola-bluetooth, WizGery/ps5-mediatek-fixesPro and Slim Bluetooth

The bootc image​

bootc/Containerfile starts from ghcr.io/ublue-os/bazzite-deck:stable and:

  • swaps Bazzite's kernel for the kernel package above, the way Bazzite's own build scripts do;
  • installs the PS5 scripts, services and udev rules from files/;
  • builds RADV, Mesa's Vulkan driver, from Bazzite's Mesa version with Terra's patches plus Borchev's PS5 Pro patch, 64- and 32-bit, and installs it over Bazzite's;
  • checks the result with bootc container lint.

ps5-bootc-sync then copies the current kernel, initrd and command line to the USB drive's boot partition at every start and shutdown, because the loader knows nothing about bootc.

Build it yourself​

Linux or WSL with Docker, Podman and about 60 GB free. The kernel takes a couple of hours:

git clone https://github.com/VivaLaVent/ps5-bazzite-deck
cd ps5-bazzite-deck
bash build.sh

It writes the linux-ps5 RPM to ~/ps5-build-7.3/linux-bin/. Then build the image from the repository root:

mkdir -p bootc/kernel && cp ~/ps5-build-7.3/linux-bin/linux-ps5-*.rpm bootc/kernel/
podman build -f bootc/Containerfile -t ps5-bazzite-bootc .

bootc/docs/building.md has the details: pinned inputs, signing and how the release workflow builds the disk image.