Skip to content
This repository was archived by the owner on Oct 4, 2026. It is now read-only.

Build the USB image

60plus edited this page Oct 3, 2026 · 12 revisions

Manual home

Build the USB image

Complete build

This is the default build. Download and unpack Valve's current SteamOS recovery image, then get the full repository: Get the repository below has the commands. Setup instructions follow after that. Windows users can start with Build on Windows, and Bazzite users with Build on Bazzite.

The complete builder prepares the disposable SteamOS environment and builds all four artifacts automatically. Run it from the repository root on your Linux build host:

sudo bash tools/build-complete.sh /absolute/path/to/recovery.img

Use the original recovery image Valve publishes, whichever release that currently is. You do not need to prepare a chroot or call each artifact builder yourself. The default includes MangoApp, the corrected Gamescope build with both the capture color fix and the Game Mode menu fix, Remote Play receiver support, NVENC, built-in controller support and the GitHub updater configured with this project's public signing key. It selects the NVIDIA driver recorded in config/build-baselines.json and requests compute-library trimming. See the CUDA note below before using trimming in a custom streaming configuration.

The builder prints the recovery release it found. Releases this project has validated are listed in config/build-baselines.json; anything else produces a warning and the build continues. The check that does refuse is a build root whose package repositories come from another SteamOS line, because the compiled artifacts would then target libraries the image does not ship.

Allow at least 50 GiB free on the Linux work filesystem after downloading the input. The script creates a new work directory next to it; choose another existing parent with --workdir /path/to/new-build-directory. The directory itself must not already exist. The output image and .sha256 file are written next to the input. Existing output is refused, not overwritten.

The recovery root is mounted read-only; compilation changes go into a separate OverlayFS layer. Package signatures remain enabled. On success, compilation residue is removed after unmounting; artifact directories, driver cache and build.log remain. On failure, the script stops, detaches its mounts and retains the work directory for diagnosis. Do not flash incomplete output or remove a work directory until mounts and loop devices have been checked.

For another trusted updater configuration, use --source /path/to/source.json. The default public package's supported OS list is unchanged by this builder. Run --help for driver selection and other options.

The complete wrapper has built an image from the original 3.8.14 recovery image in an Arch Linux QEMU guest on Windows. All four artifacts were compiled during that run. Read-only output checks passed for the driver, addon integrity, 32-bit/64-bit NVIDIA libraries and updater configuration, with xpadneo absent. The output checksum was generated by the wrapper. The tester subsequently confirmed installation, the OS update, controller operation and Remote Play in both directions. HEVC Video was enabled manually in Advanced Client Options; see Remote Play client settings. These results cover the tested setup, not every client or hardware configuration.

A small real Btrfs/OverlayFS fixture also checks failure cleanup, unchanged input hashes and refusal to overwrite an existing output. Build-root background agents are stopped before unmounting; unrelated host services are not stopped.

Build on ext4 with casefold

If the host check reports case-insensitive capable filesystem ... not supported, the kernel cannot use that filesystem as the writable OverlayFS layer. Renaming the folder does not change the filesystem feature. Do not disable casefold on your existing home partition.

Create a separate ext4 filesystem inside a file and use it for the build work. Allow at least 100 GiB of actual free disk space before this example. The 80 GiB file is sparse: it grows as the builder writes data, so its apparent size does not reserve free space. Keep the original recovery image outside this file.

Run these commands in one terminal, from the unpacked repository directory:

build_area=$(mktemp -d "$HOME/steamos-build.XXXXXXXX")
truncate -s 80G "$build_area/work.img"
mkfs.ext4 -O ^casefold -m 0 "$build_area/work.img"
mkdir "$build_area/work"
sudo mount -o loop "$build_area/work.img" "$build_area/work"
sudo bash tools/build-complete.sh --workdir "$build_area/work/complete" /absolute/path/to/recovery.img

Use source release 0.1.3 or newer when checking out or exporting the source on Windows. It enforces LF line endings for patches and VERSION regardless of Git's autocrlf setting. Older Windows checkouts/exports can fail on patch application or Invalid installer VERSION; ZIP archives downloaded directly from GitHub are not affected by that Windows conversion.

The output image and checksum are next to the input recovery image. Once the builder has finished and detached its child mounts, unmount the workspace:

sudo umount "$build_area/work"

Keep work.img if you want to retain logs, artifacts and the driver cache. If unmount reports that it is busy, inspect remaining mounts and processes before removing anything. Do not reformat or delete your home partition.

The casefold rejection and the file-backed ext4 workaround were tested on SteamOS kernel 6.16.12. A full complete build using this filesystem layout also passed in an Arch Linux VM. The VM test does not establish that every installed SteamOS system has all required build dependencies; the host check still applies.

A user also completed the full build on an installed SteamOS system using this workspace, then confirmed that the image booted after being written with Etcher and that changing the NVIDIA driver worked. This does not confirm an OS update or every hardware configuration.

Get the repository

Download and extract Source code (zip) or Source code (tar.gz) from Releases and keep the whole archive, or clone the repository on Linux:

git clone https://github.com/60plus/steamos-nvidia-installer.git
cd steamos-nvidia-installer

Keep the full checkout. The main script needs the files in lib and scripts. The three installer-* assets on the Releases page are for Installer Update, not source archives and not bootable images.

Download the recovery image

Get the image through Valve's recovery instructions. Unpack the archive to obtain an .img file. Use the recovery/repair image, not an image of an already installed system. Replace the example paths below with yours.

Base-only build (advanced)

The basic command below builds NVIDIA support and the standard installer helpers. It does not compile or add the corrected overlay, the corrected Gamescope, the Remote Play artifacts, the NVENC bridge or the desktop updater automatically. The corrected Gamescope is the part that repairs the corrupted Game Mode menus on NVIDIA, so an image built with the basic command alone does not carry that fix. That command also sets up no updater, so an installation made from such an image cannot be sent the fix later. You can include these components; to build the complete configuration, build the artifacts described below and supply all relevant options together.

sudo ./steamos-nvidia-installer.sh /path/to/recovery.img

The script creates a copy ending in -nvidia-usbinstall.img. It keeps the original image unchanged and prints the output path when finished. While the build runs the file ends in -nvidia-usbinstall.partial.img instead, and it is renamed only when the build has succeeded, so a file with the flashable name is always a finished build.

An image from an earlier build is left alone until the new one succeeds. That means that after a failed build, an -nvidia-usbinstall.img sitting next to your input is the older image, not the one you just tried to make. Check the time on the file before flashing it. The unfinished .partial.img is removed by the next run.

The default selects the driver recorded in config/build-baselines.json, which is the version this project tests on hardware. To select a different build:

sudo ./steamos-nvidia-installer.sh --driver 610.57.04-1 --trim-cuda /path/to/recovery.img

--driver latest resolves whatever Arch ships on the day you build. That is a deliberate choice, not the default: the newest packaged driver has not been tested by this project and has carried regressions in the past. Choose a driver compatible with both your GPU and the image kernel. --trim-cuda removes CUDA, OpenCL and OptiX libraries; omit it if your applications need them.

Options

Option Purpose
--driver SPEC Select a version prefix or an exact package version, or latest for the current Arch package. Default: the tested version in config/build-baselines.json.
--installer-update-source FILE Include the desktop updater with a maintainer-supplied source and public signing key.
--mangoapp-dir DIR Include the corrected performance overlay artifact.
--gamescope-dir DIR Include the corrected Gamescope build: the capture color correction and the fix for corrupted Game Mode menus. Leaving it out leaves out both.
--remote-play-dir DIR Include the SDR receiver and decoder color correction.
--nvenc-dir DIR Include the 32-bit to 64-bit hardware-encoding bridge.
--workdir DIR Choose a reusable build cache.
--trim-cuda Reduce the driver payload by removing compute libraries.
--xpadneo Add the optional Xbox Bluetooth driver.
--no-xpadneo Use built-in controller support, the default.
--xpadneo-version TAG Select an exact xpadneo tag; default v0.10.4.
--experimental-preview Select Valve's Preview channel for a separate test installation. Self-healing mode only; cannot be combined with beta.
--experimental-beta Select Valve's beta channel for first setup and OS updates. Experimental, self-healing mode only.
--hold-updates Freeze OS updates; Steam reports the system as up to date.
--no-hold-updates Use stock updates, which remove the added NVIDIA driver.
--no-installer Produce a patched bootable image without desktop installation shortcuts.
--skip-sigcheck Disable package signature checks during building. Avoid for normal use.
--preflight Run the host checks and stop. Nothing is built and nothing is changed.

The normal update mode repairs NVIDIA after OS updates. No extra flag is needed. The older build-xpadneo.sh wrapper explicitly enables xpadneo and forwards other options to the main script. Start without xpadneo unless your controller needs it. When enabled, xpadneo also changes system-wide Bluetooth settings.

For package signature failures, check the clock, keyring and failing package before considering a bypass. See Troubleshooting.

Include the desktop updater

For a base-only or manual build, use the included public configuration with --installer-update-source config/github-stable.json. This enables SteamOS NVIDIA Installer Update in the installed system. It requires the normal self-healing update mode. Without this option, the desktop updater is not included. Do not replace the source or signing key with one from an untrusted download.

Write the USB

Use an image-writing tool to write the entire output image to the USB device.

Etcher has been confirmed to write a working installer USB. Select the completed .img, choose the correct USB drive and let writing and verification finish. If booting through Ventoy fails, write the image directly to the USB drive with Etcher or the dd command printed by the builder. One reported setup failed with Ventoy and booted after a direct write with Etcher; this is not a claim that Ventoy fails on every setup.

Copying the file onto a formatted USB drive is not enough. Verify the destination by capacity and model; writing the image erases the USB.

On Linux, list devices with:

lsblk -o NAME,SIZE,MODEL,TRAN,MOUNTPOINTS

Wait for writing and verification to finish before removing the drive. You can record the image checksum with sha256sum /path/to/output.img.

Continue with Install and first boot.

Including the corrected performance overlay

Maintainers can build the pinned MangoApp artifact with:

sudo bash tools/build-mangoapp.sh /path/to/disposable-steamos-root /path/to/new-mangoapp-output

Use a disposable SteamOS build root with /proc, /dev and DNS prepared. The script installs build dependencies there. Do not pass an installed system or the root filesystem of a running PC. The output directory must not already exist. Use the same SteamOS library baseline as the target image.

Add --mangoapp-dir /path/to/new-mangoapp-output to the image build command. The release packer accepts the same option for an integration update. Include all three output files together: mangoapp, mangoapp-build.json and MangoHud-LICENSE. See How it works.

Experimental beta and Preview images

Use --experimental-beta or --experimental-preview only for a separate test installation. Choose one. The recovery image's original OS remains the installation base; the selected channel supplies subsequent OS updates, including first setup. These options do not copy individual experimental packages into the older system. Valve's server chooses the downloaded version, which can change after the image is built.

Keep a working stable installer and use a separate test disk. Neither option enables main or establishes compatibility with every future experimental build.

A Preview installation runs SteamOS's own Gamescope rather than this project's build. That is deliberate. The build is matched to one exact Gamescope package on the SteamOS 3.8 line, and it steps aside rather than put an older compositor on a newer system. Preview is the newer 3.9 line. The capture color correction is a backport of a change Valve's newer Gamescope already contains, so Remote Play colors from this machine are unaffected. What is not in Valve's build is this project's own fix for the corrupted Game Mode menus, so that fix is not active on Preview. Nothing on screen says so. The diagnostic report names the Gamescope selection, and on Preview it reads stock. Applying a project release on the 3.9 line has not been tested, and it would not change this selection.

Building the corrected Gamescope

An image built with all components in the build guide already includes the Gamescope, receiver and NVENC artifacts described below. These sections explain how to reproduce that build. The options are optional for custom builders; users of that image do not need to build or enable the fixes themselves.

The artifact carries two corrections. The first fixes the colors that a Remote Play host and a screenshot capture produce on an NVIDIA GPU. The second stops Gamescope handing a layer that needs alpha blending to a hardware plane on an NVIDIA display, which is what corrupted the Game Mode menus. The second correction switches itself on only for a display the kernel reports as nvidia-drm, and GAMESCOPE_NVIDIA_COMPOSITE_ALPHA=0 turns it off again if you need to compare.

Use a disposable stable SteamOS build root with /proc, /dev, /sys and DNS available. The tool reinstalls build dependencies there because recovery images remove development headers while retaining their package database entries. Never use / or the installed system you are testing as the build root.

sudo bash tools/build-gamescope.sh /path/to/disposable-steamos-root /path/to/new-gamescope-output

The output directory must not exist. The tool stages files under root/ and records provenance in gamescope-build.json. It does not install them into the running system. Keep the license files with the artifact. Compilation and pixel conversion checks do not replace a physical Remote Play and screenshot test.

To include the artifact in an installer, add --gamescope-dir /path/to/new-gamescope-output to the normal image build command. The release packer accepts --gamescope-dir as well, so an integration update can deliver a new Gamescope build to a system that is already installed, with no new USB image. That reaches a system whose installed release is 0.1.9 or newer, because an update writes only the files the installed copy of the update tool already knows about, and Gamescope joined that list in 0.1.9. The recovery desktop keeps its original Gamescope. The corrected build is activated once the installed system ships the Gamescope package the artifact was built from, on the SteamOS 3.8 line. An image may carry the artifact on any channel; the selection happens at install and repair time and returns to Valve's build whenever the package does not match.

Building Remote Play receiver support

Build the decoder and receiver environment helper in a disposable stable SteamOS 3.8 build root, then pass the artifact directory to the installer:

sudo bash tools/build-remote-play.sh /path/to/build-root /path/to/remote-play-artifact
sudo ./steamos-nvidia-installer.sh --remote-play-dir /path/to/remote-play-artifact /path/to/recovery.img

The artifact includes source revision, patch hashes, binary hashes and the decoder license. It adds SDR receiving support without replacing files inside Steam's user installation. Combine it with --gamescope-dir to include the corrected Gamescope build, which carries the sending-side capture correction. Test both directions after installation and again after the first SteamOS update. The receiver policy uses SDR; HDR receiving is not provided by this configuration.

Building the NVENC encoding bridge

Build the pinned encoding driver and helper in the same kind of disposable stable SteamOS root used for the receiver build:

sudo bash tools/build-nvenc.sh /path/to/build-root /path/to/nvenc-artifact
sudo ./steamos-nvidia-installer.sh --nvenc-dir /path/to/nvenc-artifact /path/to/recovery.img

The builder records the source revision and file hashes and includes the upstream license. The bridge is optional. Combine it with the capture and receiver artifacts when testing Remote Play in both directions. It installs a 32-bit VAAPI encoding driver and a 64-bit user service. It does not replace the private receiver decoder. Test streaming, reconnect, reboot, suspend and the first OS update before distributing an image. Hardware tests of a separately installed prototype do not validate a new image.

Manual component build

Release downloads do not contain Valve's recovery image or a complete SteamOS image. Obtain the recovery image directly from Valve using the link above. The commands below combine all of this project's integration components.

First prepare a disposable, writable SteamOS 3.8 build root on a Linux filesystem. It must contain the system's /etc, /usr and package database, have working package repositories and DNS, and have /proc, /dev and /sys mounted inside it. Use a copy for building, never your running installation or your only recovery image. Do not substitute an ordinary Arch root: the resulting binaries need the target SteamOS library versions.

tools/prepare-build-root.sh creates one from an unpacked recovery image. It is the same code the complete build uses, so the two cannot drift apart:

sudo bash tools/prepare-build-root.sh /path/to/recovery.img /path/to/new-workdir

It mounts the image read only, stacks a writable overlay on it, mounts /proc, /dev and /sys, gives the chroot a working resolver, initializes a private package keyring and syncs the databases. It prints the path of the prepared root.

Preparing a work directory that already holds an upper layer keeps the packages installed last time, which turns a repeated artifact build from an hour into minutes. When you are finished with it:

sudo bash tools/prepare-build-root.sh --cleanup /path/to/new-workdir

That unmounts everything and detaches the loop device while keeping the upper layer for the next rebuild.

From the repository root, replace the two absolute paths below. Keep each output directory new; artifact builders refuse to overwrite existing outputs.

build_root=/absolute/path/to/disposable-steamos-root
artifacts=/absolute/path/to/new-artifacts
mkdir -p "$artifacts"
sudo bash tools/build-mangoapp.sh "$build_root" "$artifacts/mangoapp"
sudo bash tools/build-gamescope.sh "$build_root" "$artifacts/gamescope"
sudo bash tools/build-remote-play.sh "$build_root" "$artifacts/remote-play"
sudo bash tools/build-nvenc.sh "$build_root" "$artifacts/nvenc"

sudo ./steamos-nvidia-installer.sh \
  --driver 610.57.04-1 --trim-cuda \
  --mangoapp-dir "$artifacts/mangoapp" \
  --gamescope-dir "$artifacts/gamescope" \
  --remote-play-dir "$artifacts/remote-play" \
  --nvenc-dir "$artifacts/nvenc" \
  --installer-update-source config/github-stable.json \
  /absolute/path/to/recovery.img

The pinned configuration uses a SteamOS 3.8.14 recovery image and the normal stable update path to 3.8.16. It does not import a beta kernel. Check the image's reported version before building; a different recovery or target OS version requires fresh compatibility testing. Omit --trim-cuda if you need compute libraries.

Keep the artifact metadata and license files together with each artifact. After a successful build, calculate the output checksum, write the image to USB and test installation, the first OS update, suspend/resume, the overlay and both Remote Play directions. Successful compilation alone does not verify those functions.

CUDA trimming and Remote Play

--trim-cuda filters CUDA, OpenCL, NVVM and OptiX paths from the main builder's payload list. It is not a switch to disable Remote Play or NVENC. However, the project's 64-bit NVENC helper dynamically loads libcuda.so.1, so removing that runtime library can prevent hardware encoding. A normal loader dependency check does not cover all libraries loaded dynamically at runtime.

Inspection of the complete test image confirmed that matching libcuda, libnvidia-encode and libnvcuvid libraries are present despite trimming being requested. Do not interpret the flag as proof that the final image contains no CUDA runtime, or assume every streaming implementation works without it. Use --keep-cuda with the complete builder, or omit --trim-cuda with the base builder, when retaining compute libraries. Validate both Remote Play directions after installation and OS updates.

SteamOS NVIDIA manual

Start here

Build the installer

Install and run

When something is wrong

Under the bonnet

Clone this wiki locally