← james-scott.co.uk

BC-250 Steam Machine with Bazzite

A complete build log for turning the AMD BC-250 mining board into a set-and-forget Steam console — including the fixes for the login-screen freezes, the NVMe crashes, and the two silicon unlocks. Everything here was hit for real and solved on one box in August 2026.

If you searched for one of these, you're in the right place

The build

Board
AMD BC-250 (PS5-derived APU: Zen 2 + RDNA2 “Cyan Skillfish”, gfx1013)
BIOS
Forbidden-Darkness MeiMeiDXEv3 mod (P3.00 base) — permanent 8-core unlock
OS
Bazzite Steam Deck edition, image bazzite-deck-42.20251018 (Fedora 42 Atomic)
Login
Default user bazzite, default password bazzite
Storage
Netac NV3000 1TB NVMe — its firmware locks up on large TRIM commands
End state
8c/16t and 40/40 CUs on every boot, cold boots included; no manual steps after power loss

1 · BIOS flash: permanent 8-core unlock

The BC-250 ships with 6 of its 8 Zen 2 cores enabled. Software unlocks via the SMU mailbox work but revert on every cold power cycle — for a console that must survive power cuts, flash the modded BIOS instead: Forbidden-Darkness / AMD-BC-250-UEFI-v2.2-Firmware-Menu-Script.

USB prep (no OS needed on the box — the stick boots straight into a UEFI shell menu): format FAT32, copy reboot-uefi.sh and release-0.5.0.7z from the release to the root, extract the 7z to the root too. Boot the stick from the BIOS boot menu.

CommandEffect
menu 0fBack up current firmware to \Firmware_Backup\bc250-backup.romdo this first and copy it off the stick
menu 07Flash MeiMeiDXEv3 (AMD boot logo; options 01–14 are the same firmware with different logos)
menu frRestore from your backup

The GPU's compute-unit limit is not in the firmware — that's section 6.

2 · First boot: “dead” ethernet that isn't

After the flashing session's many warm reboots, the onboard Realtek RTL8111H showed no link at all — invisible problem at the worst time, because Bazzite's deck image needs internet at first login. The NIC was fine: the PHY was stuck in a low-power state. Unplug power completely for 30 seconds and it comes back (verify from the installer shell with lspci and ip link — link 1Gbps/Full). Don't chase drivers; it's plug-and-play under Linux.

3 · Blinking-cursor TTYs and the default password

The text consoles (Ctrl+Alt+F2…F6) often show only a blinking cursor — the login prompt doesn't always render on the BC-250's display path. Press Enter to coax the prompt out, or just type the credentials blind. The default login is user bazzite, password bazzite — not obvious anywhere on screen, and easy to mistake for a broken console or a passwordless account. Once in:

passwd                              # change the default password — it's also the sudo and SSH password
sudo systemctl enable --now sshd    # a remote shell saves this whole project

(The installer USB's Anaconda environment separately offers a passwordless root shell on Ctrl+Alt+F2 — useful for rescue work.)

One observation worth knowing: when the machine later “crashed”, existing SSH sessions kept answering (they run from RAM) while the TTYs and any disk-touching command froze — you can SSH in at the Steam login screen, but a session opened after the storage dies is stuck. A half-alive shell with dead consoles means storage trouble, not a kernel panic.

4 · Steam login-screen errors: mostly noise

At the first-boot Steam sign-in, the console/CEF logs filled with this, repeating every ~60 seconds:

Login: Failed to poll auth session. Result 2. Transport Error: 2
RecvMsgClientLogOnResponse() : 'Try another CM' / 'Failure'
ConnectionDisconnected('Disconnected By Remote Host') : 'Failure'
LogonFailure No Connection

Hours of diagnosis later: none of this blocks login. steamcmd logged in fine from the same box, the QR auth API answered over plain HTTPS, and eventually a QR scan simply worked, with those messages still scrolling. If your QR fails, wait for it to refresh (~1 min) and scan again. What actually killed the machine at “Loading user data” was the drive — next section. (Also tried and useless here: steam -tcp is ignored by current clients, and the deck beta channel behaves identically.)

5 · The real killer: NVMe firmware locks up on TRIM

Every hard freeze — during sign-in, at “Loading user data”, TTYs dead, and once the drive vanishing from the BIOS entirely — was one bug. Kernel log streamed to another machine via netconsole caught it:

nvme nvme0: I/O tag 532 (c214) opcode 0x9 (I/O Cmd) QID 6 timeout, aborting req_op:DISCARD(3) size:4294966784
nvme nvme0: I/O tag 443 (d1bb) opcode 0x1 (I/O Cmd) QID 4 timeout, aborting req_op:WRITE(1)
nvme nvme0: I/O tag 532 (c214) opcode 0x9 (I/O Cmd) QID 6 timeout, reset controller
— nothing after this line, ever; then —
BTRFS error (device nvme0n1p3 state EA): run_delalloc_nocow failed … -5

That DISCARD is a ~4 GiB TRIM (2³²−512 bytes). Bazzite's btrfs mounts with discard=async; Steam's first post-login write burst makes btrfs issue huge discards; the Netac NV3000's firmware hangs on them; the controller reset never completes; with the root filesystem on that drive, everything freezes. Wedge it hard enough and the drive won't even enumerate in the BIOS until a long (60 s) cold power-off.

The fix: stop sending TRIM

# live, this boot (on ostree/Bazzite, remount /var — /sysroot refuses; the option is filesystem-wide):
sudo mount -o remount,nodiscard /var
sudo systemctl disable --now fstrim.timer
# permanent — bootloader kernel argument, survives updates:
sudo rpm-ostree kargs --delete='rootflags=subvol=root' --append='rootflags=subvol=root,nodiscard'

After this: /proc/cmdline shows rootflags=subvol=root,nodiscard, no mount lists a discard option, and the exact login sequence that froze the box five times ran clean. Zero NVMe errors since. Trade-off: the SSD never gets TRIM, slightly hurting long-term write performance — the honest fix is a drive whose firmware isn't broken, but nodiscard makes this one dependable. (nvme_core.default_ps_max_latency_us=0 to rule out APST power states is also worth keeping on cheap drives.)

Catching it: netconsole

A machine that freezes with its logs is diagnosable if the kernel streams them elsewhere. On the BC-250 (persistent):

echo netconsole | sudo tee /etc/modules-load.d/netconsole.conf
echo 'options netconsole netconsole=@BOX_IP/enp4s0,6666@DESKTOP_IP/DESKTOP_MAC' | sudo tee /etc/modprobe.d/netconsole.conf

Any UDP listener on port 6666 on the desktop catches every kernel message up to the moment of death.

6 · BC-250 must-do tweaks on Bazzite

# Handheld Daemon misbehaves on this board (it isn't a handheld):
sudo systemctl disable --now hhd && sudo systemctl mask hhd
# GPU governor — the big stability fix for actual gaming — plus umr for the CU unlock:
sudo curl -sL -o /etc/yum.repos.d/filippor-bazzite.repo \
  'https://copr.fedorainfracloud.org/coprs/filippor/bazzite/repo/fedora-42/filippor-bazzite-fedora-42.repo'
sudo rpm-ostree install cyan-skillfish-governor-smu umr && sudo systemctl reboot
sudo systemctl enable --now cyan-skillfish-governor-smu.service
# temperature sensors:
echo nct6683 | sudo tee /etc/modules-load.d/nct6683.conf
echo 'options nct6683 force=true' | sudo tee /etc/modprobe.d/nct6683.conf

Reference: the excellent community BC-250 documentation.

7 · 40/40 compute units

The BC-250 runs 24 of its 40 RDNA2 CUs by default; the limit lives in driver-level dispatch masks. WinnieLV / bc250-cu-live-manager (readable bash, no network calls, writes registers via umr) unlocks them live and installs a boot service so it sticks:

curl -L -O https://raw.githubusercontent.com/WinnieLV/bc250-cu-live-manager/refs/heads/main/bc250-cu-live-manager.sh
chmod +x bc250-cu-live-manager.sh
sudo ./bc250-cu-live-manager.sh status               # dashboard — stock shows 24/40
sudo ./bc250-cu-live-manager.sh -y enable all
sudo ./bc250-cu-live-manager.sh -y write-service-table
sudo ./bc250-cu-live-manager.sh -y install-service
CUs active & routed : 40/40

With the BIOS handling the CPU cores and this service handling the GPU, the box comes back fully unlocked from any power cut with zero manual steps.

8 · “It crashed while idle” — no, it suspended

Bazzite's deck image behaves like a Steam Deck: idle long enough (an active download doesn't count) and it suspends. On the BC-250, s2idle is a one-way trip — the board never wakes, which is indistinguishable from a hard crash: black screen, off the network, only a power cycle brings it back. The journal from the “crashed” boot ends with systemd-sleep: Performing sleep operation 'suspend' / PM: suspend entry (s2idle) rather than any error. This is a plugged-in console, so just forbid sleeping entirely:

sudo systemctl mask sleep.target suspend.target hibernate.target hybrid-sleep.target

Odds and ends

Written August 2026 after doing all of the above on one board. Corrections welcome — github.com/scotjam.