BC-250 Ultimate Setup
Bring an AMD BC-250 board from a fresh Linux install to a stable, tuned system.
The BC-250 is an ex-crypto-mining board built around AMD's "Cyan Skillfish" APU:
6× Zen 2 cores, 24 RDNA2 CUs (gfx1013), and 16 GB of GDDR6 shared between
CPU and GPU. It runs Linux only. Out of the box it is unstable in specific,
predictable ways — every one of them has a known fix.
Mental model — the six things that make this board different
- No GPU governor exists by default, so the GPU is pinned at 1500 MHz and idles around 105 W. Adding one is the single highest-impact change.
- No CPU C-states or P-states are exposed by stock firmware. Idle power stays high and the CPU never scales. A community ACPI override fixes it.
- Unified memory. The "VRAM split" is a minimum carve-out; the dynamic ceiling needs a kernel parameter, and there are two distinct crash modes.
- IOMMU is broken. It must be disabled in BIOS or the board crashes.
- The GPU is usually
card1, notcard0. Never hardcode a card index or a/sys/class/drm/card0path. Find it by PCI device id0x13fe. - A GPU crash is a system crash. CPU and GPU share one die — there is no isolating reset. Stability work is therefore about avoiding crashes: kernel version, voltage curve, and thermals.
Non-negotiables
- Never enable IOMMU in BIOS.
- Never set the GPU minimum voltage below 700 mV — it locks the GPU at 1500 MHz and silently defeats the governor.
- Never use
Smokeless_UMAF— it has bricked boards. - Avoid kernels 6.15.0–6.15.6 and 6.17.8–6.17.10 (GPU init fails).
- Clear CMOS after every BIOS flash, and keep a fallback boot entry.
- Never change RAM timings without a hardware flasher available.
Workflow
Always run detection first; never assume the machine's state.
detect → stage 1 → verify → stage 2 (reboot) → verify → optional tuning
0. Detect (always, read-only, no root)
bash scripts/detect.sh # or --json for machine-readable output
It reports distro, bootloader, initramfs, kernel, Mesa, the real GPU card index, VRAM split, C/P-states, swap/ZRAM/zswap, governor and sensor status, then prints the next steps that apply. Decide from this output, not from assumptions.
Decision rules:
kernel_broken: true→ stop, get off that kernel before anything else.bootloader/initramfsdetermine whichstage2-boot.shbranch runs. If either isunknown, do not run stage 2 — readreferences/distro-notes.mdand apply the boot changes by hand.gpu_governor_running: false→ stage 1 is required.zram_active: trueorttm_pages_limitunset → stage 2 is worth doing.
1. Core must-haves (no reboot)
sudo bash scripts/stage1-core.sh --dry-run # preview
sudo bash scripts/stage1-core.sh # apply
Installs monitoring tooling, loads the NCT6686D board sensors (nct6683,
read-only), and installs + enables cyan-skillfish-governor-smu with an
annotated conservative config. Idempotent; an existing governor config is
backed up, never overwritten.
Do not use the project's own install.sh: the release tarball omits the
files it tries to copy. The script installs the binary and writes the unit.
2. Verify stage 1
bash scripts/verify.sh
The GPU clock should read 1000 MHz at idle and rise above 1500 MHz under load.
If it stays at 1500, see references/troubleshooting.md. Note that a light
workload legitimately stays at 1000 MHz — the default load target only ramps
above 65 % GPU busy.
3. Boot-affecting changes (reboot required)
sudo bash scripts/stage2-boot.sh # PREVIEW ONLY (default, safe)
sudo bash scripts/stage2-boot.sh --yes # apply
Because this edits the bootloader, the default is a no-op preview. It:
- installs the ACPI override (
SSDT-CST= C-states,SSDT-PST= P-states, 800–3200 MHz) using whichever mechanism the detected initramfs needs; - adds
ttm.pages_limit(≈12 GB dynamic VRAM) and zswap parameters to the kernel cmdline via the detected bootloader; - optionally replaces ZRAM with zswap(lz4) over a 16 GB swapfile — the swapfile is created and activated before ZRAM is disabled, so you are never left without swap;
- backs every file it touches up to
/root/bc250-backup-<timestamp>/.
Useful overrides:
ENABLE_ZSWAP=0 sudo bash scripts/stage2-boot.sh --yes # leave swap alone
TTM_PAGES=3145728 sudo bash scripts/stage2-boot.sh --yes # different VRAM cap
Then reboot, and if it does not come up pick the fallback / LTS entry in the boot menu.
4. Verify stage 2, and keep verifying
bash scripts/verify.sh # exits non-zero if a hard requirement failed
Expect: C-states on every CPU, P-states 800 MHz–3.2 GHz, zswap enabled, no
ZRAM swap device, GPU governor running, and nct6686 sensors visible.
Optional tuning (only after the baseline is stable)
- GPU ceiling — the default caps at 1850 MHz. To go higher, edit
[frequency-range] maxand add[[safe-points]], then test 30+ minutes per step. Readreferences/governor-tuning.mdfirst; the method (freeze → find voltage floor → widen) matters more than the numbers. - Fan curves — needs the out-of-tree
nct6687driver plus CoolerControl;references/cooling-and-power.md. - 40 CU unlock / 8-core unlock / CPU OC — real gains, real risk. The 8-core
unlock requires swapping to the 16-thread ACPI tables. See
references/kernel-matrix.md.
Worked example (real numbers)
Reference run on CachyOS, kernel 7.2.4, limine, btrfs, stock cooling:
| before | after stage 1 | after stage 2 | |
|---|---|---|---|
| GPU @ idle | 1500 MHz pinned | 1000 MHz @ 799 mV, ~40 W | same |
| GPU @ load | 1500 MHz | 1850 MHz, 80–86 W, 61–64 °C | same |
| CPU | no cpufreq at all | no cpufreq | idle 0.93 GHz ↔ load 3.49 GHz |
| swap | ZRAM 14.8 GB | ZRAM 14.8 GB | zswap(lz4) + 16 GB swapfile |
dmesg resets/panics |
— | 0 | 0 |
The ACPI override shows up at boot as
ACPI: Table Upgrade: install [SSDT- HACK- P_CST3] / [SSDT- HACK- PSTATES].
Troubleshooting
Symptom → cause → fix lives in references/troubleshooting.md. The highest
yield checks are always: kernel version, IOMMU, and whether CMOS was cleared.
Where the detail lives
| Read this | When |
|---|---|
references/kernel-matrix.md |
kernel choice, pinning, the optional unlocks |
references/bios-and-vram.md |
BIOS musts, VRAM split, the two crash modes, ttm.pages_limit |
references/governor-tuning.md |
governor options, config schema, voltage-curve method, hard limits |
references/cooling-and-power.md |
PSU, temps, fans, sensors, CoolerControl |
references/troubleshooting.md |
anything is broken |
references/distro-notes.md |
non-Arch distros, what is tested vs documented |
references/credits.md |
upstream projects and community links |
assets/governor-smu-config.toml |
annotated starting config |
Safety
These scripts change the boot configuration. stage2-boot.sh is preview-first
for that reason, backs up before writing, and prints its rollback steps. Review
what it will do (--dry-run) before applying, and keep a bootable fallback
entry. Numbers in the references are community defaults, not guarantees —
silicon varies per board.