content: added the "BC-Zero - Board Testing" article
Build and Publish / build (push) Successful in 1m16s

This commit is contained in:
2026-11-08 15:58:19 +01:00
parent 8bf559d13e
commit e693645bb9
21 changed files with 1057 additions and 24 deletions
@@ -0,0 +1,532 @@
+++
title = "BC-Zero - Testing della scheda"
summary = "Da vecchia scheda da mining a console e server AI"
date = "2038-01-19"
tags = ["BC-250", "PS5", "Sblocco", "BIOS", "CPU", "GPU"]
categories = ["Progetti"]
series = ["BC-Zero"]
series_order = 1
draft = true
+++
Il 5 febbraio [Soffio](https://t.me/Soffioo), amico e socio
[LUGMan](https://lugman.org/), mi ha fatto scoprire una scheda particolare: la
**BC-250**.
La BC-250 è una scheda proveniente da un [rig per il mining di criptovalute di
ASRock](https://www.tomshardware.com/news/twelve-ps5-apus-power-asrocks-new-cryptomining-rig),
che ne ospitava dodici.
Dentro ognuna di queste schede c'è un chip *binned* derivato dall'APU AMD della
PlayStation 5, con 6 degli 8 core CPU e 24 delle 36 CU GPU attivi, insieme a
16GB di RAM GDDR6 **unificati** tra CPU e GPU, uno slot M.2 (PCIe 2.0x2 o SATA
III) e poche porte: due USB 2.0, due USB 3.0, una Ethernet Gigabit e una
DisplayPort. L'alimentazione è fornita da un connettore PCIe a 8 pin.
All'inizio non ero proprio convinto, soprattutto nel vedere un terzo delle CU
tagliate via così e nel sapere che è una scheda con un chip custom, parzialmente
bloccato (oltre ai core bloccati, alcune funzionalità come l'enconding/decoding
video non sono presenti), derivante dal mining e senza alcun tipo di supporto o
community dietro. Ma il prezzo era decisamente interessante, e a quanto pare
questa scheda ha una community molto attiva che si impegna per tirarne fuori il
100% del potenziale su Linux.
![Soffio: "Oh se vuoi te ne do una, perché l'avevo presa senza coupon e avevo
intenzione di rivenderla😂" "Quindi tecnicamente me ne arrivano due😂" Io: "Ma
no tranqui" "Non saprei che farmene"](images/01-not-fully-convinced.png "Io non
pienamente convinto")
Le cose cambiano però quando la mattina del 30 maggio ricevo questo messaggio:
![Soffio: "Sono riusciti a sbloccare tutte le CU, passato da 24 a 40. Adesso
stanno guardando per sbloccare gli 8
core😂🌚👌"](images/02-40cu-unlocked-news.png)
E sempre il caro Soffio mi fa presente che da li a breve sarebbero iniziati i
super sconti AliExpress. Incuriosito dalla faccenda gli chiedo se può prestarmi
la sua scheda per un po' di giorni, giusto per provarla e vedere cosa si può
fare.
E *oh boy* se questa scheda mi ha convinto.
## Step 0: Preparazione
Una pecca della BC-250 è che non è proprio *plug-and-play*. Bisogna come minimo:
1. Trovare un alimentatore in grado di fornire ***realmente*** almeno 300W sul
rail +12V e con dei cavi che sappiano gestire tutti quegli ampere;
2. Avere un monitor con DisplayPort (o comprare un adattatore);
3. Trovare un modo per raffreddare la maledetta;
4. Flashare il BIOS.
Il mio setup di prova era:
1. Il primo alimentatore marchiato "*el cheapo*" che ho trovato sottomano (che
"sicuramente andrà bene, c'è scritto 500W");
2. Adattatore passivo DP ➜ HDMI;
3. Climatizzatore portatile per il raffreddamento (era estate e iniziava a fare
caldo);
4. Programmatore SPI CH341 (che avevo già).
![Setup casalingo](images/03-initial-setup.png "Se guardate attentamente, il
bridge PS_ON ➜ GND è stato fatto con un cavetto e tutta la potenza passa per un
convertitore SATA ➜ PCIe. Non fatelo a casa")
Non proprio il setup migliore per testare la scheda, ma si lavora con quello che
si ha.
## Step 1: Flashare il BIOS
Il [primo punto sulla documentazione della
community](https://elektricm.github.io/amd-bc250-docs/getting-started/quick-start/#step-1-bios-flash-critical)
è il flashing del BIOS. Senza un BIOS custom non si hanno funzionalità
essenziali come l'allocazione dinamica della VRAM (voglio ricordare che i 16GB
di RAM sono condivisi) e una corretta gestione delle ventole.
All'inizio ho installato quello consigliato dalla guida, quello di
[TuxThePenguin0](https://gitlab.com/TuxThePenguin0/bc250-bios), ma più avanti ho
scoperto un altro BIOS, quello di [Forbidden
Darkness](https://github.com/Forbidden-Darkness/AMD-BC-250-UEFI-v2.2-Firmware-Menu-Script)
che, oltre allo sblocco del menù per l'allocazione dinamica offre una selezioni
di immagini di splash custom e, soprattutto, **lo sblocco di tutti gli 8 core
CPU**.
"*Ma come, non erano bloccati?*" A quanto pare non abbastanza.
L'APU ha tutti i core presenti sul silicio, sono solo disattivati via firmware.
Un principio simile vale anche per le CU della GPU, ma lo vedremo dopo.
---
L'installazione è anche più semplice e non richiede un flasher BIOS: basta
copiare i file contenuti nell'archivio `.7z` delle release in una chiavetta
formattata in FAT32 e farci il boot. L'installer chiede che splash image
vogliamo (la
[`07`](https://github.com/user-attachments/assets/ca23ce6c-08ab-4293-9a70-0e55f66dc93c)
è la migliore *imho*) e procede a flashare.
![Flashing del BIOS](images/04-bios-flashing.png "Flashing del BIOS")
{{< alert icon="triangle-exclamation" cardColor="#e6d237" iconColor="#1d3557"
textColor="#1d3557" >}}
Il flashing del BIOS è un operazione pericolosa. Assicuratevi che la scheda non
si spenga nel mentre.
{{< /alert >}}
Una volta terminato il flashing bisogna resettare tutte le impostazioni del
BIOS. Per farlo basta staccare l'alimentazione e bridgare i pin 2 e 3
dell'header `CLRCMOS1` per qualche secondo. Una volta fatto possiamo
ripristinare l'header sui pin 1 e 2, ricollegare l'alimentazione ed entrando nel
BIOS premendo `Canc` all'avvio vedremo molte più opzioni.
![Nuovo logo al boot](images/05-new-boot-logo.png "Nuovo logo al boot")
![Nuove entry nel menù "Advanced"](images/06-new-advanced-menu.png "Nuove entry
nel menù \"Advanced\"")
Per prima cosa facciamo in modo che l'allocazione di VRAM sia automatica. Per
farlo dobbiamo andare nella sezione `Chipset` > `GFX Configuration` > `GFX
Configuration` e impostare `Integrated Graphics Controller` a `Forces`, poi `UMA
Mode` a `UMA_SPECIFIED` e infine `UMA Frame buffer size` a `512M`.
![La configurazione corretta per l'UMA](images/07-uma-512m.png "La
configurazione corretta per l'UMA")
Poi in `NB Configuration` disabilitiamo l'IOMMU (su questa scheda sembra non
essere funzionante)
Infine abilitiamo tutti i core andando nella sezione `Advanced` > `MeiMeiDXEv3
Menu` e abilitando tutto.
![La configurazione per l'attivazione degli 8 core](images/08-8-core-unlock.png
"La configurazione per l'attivazione degli 8 core")
{{< alert icon="triangle-exclamation" cardColor="#e6d237" iconColor="#1d3557"
textColor="#1d3557" >}}
Nulla garantisce che i tutti core siano funzionanti. Core danneggiati potrebbero
causare crash improvvisi.
Per evitare ciò faremo uno stress-test su tutti i core e controlleremo che nei
log del kernel non appaia nessun `Machine Check Exception` prima di abilitare
questa impostazione in produzione
{{< /alert >}}
Una volta che abbiamo configurato correttamente il BIOS siamo pronti per
installare un sistema operativo e testare per bene questa scheda.
## Step 2: Installazione di un OS di prova
Per fare un po' di stress testing CPU e per fare dei test con la GPU installerò
Arch Linux.
Non sarà la distro finale che andrò ad installare, ma la scelta non è casuale:
lo sviluppo di questa scheda è bleeding-edge e per ora quasi tutti gli script
assumono che sia installato Arch o Fedora per avere le ultime versioni dei
pacchetti.
![La configurazione di archinstall che userò](images/09-archinstall.png "La
configurazione di archinstall che userò")
![Il sistema installato](images/10-fastfetch.png "Il sistema installato. Come
vedete si possono già vedere i 16 thread")
### Test degli 8 core
Per prima cosa testiamo se tutti gli 8 core funzionano come dovrebbero. Per
farlo installiamo il pacchetto `stress-ng` e facciamo uno stress test:
```sh
stress-ng --cpu 16 --cpu-method all --verify --timeout 2h --metrics
```
Verifichiamo poi che non ci siano stati errori con:
```sh
sudo dmesg | grep -iE "mce|machine check|hardware error"
```
Se il kernel non segnala alcun errore siamo appena passati da 6 a 8 core
gratuitamente. In caso di errore invece è possibile modificare quali core
attivare e quali no dal BIOS.
### Stress-testing della GPU
Facciamo poi uno stress testing della GPU per avere una baseline delle
performance prima di installare il governor o abilitare tutte le CU. Per farlo
ho installato Furmark e ho fatto il test 1080p
![Furmark (68 FPS)](images/11-baseline-furmark.png)
Direi che 70 FPS non sono *così* male per la scheda *out-of-the-box*, ma si può
sicuramente fare di meglio, molto meglio.
---
Piccola nota che mi sento di aggiungere: se durante lo stess test lo schermo
diventa nero e la scheda non risponde in alcun modo, controllate
l'alimentazione. Il piccolo *foreshadowing* che ho fatto nello step 0 riguardo
all'alimentatore riguarda il fatto che durante i miei test ho fatto girare
Ollama e ho completamente bruciato la power supply dato che (a quanto pare) non
riusciva a gestire davvero tutto il carico sul rail +12V. Ho successivamente
comprato su AliExpress, insieme alla scheda, il PSU consigliato dalla community,
il [Metalfish 500W
FlexATX](https://elektricm.github.io/amd-bc250-docs/hardware/power#option-2-flexatx-psu-500w)
e da li non ho più avuto problemi.
![PSU deceduta](images/12-dead-psu.jpg "Riposa in pace, soldato 🫡")
### Installazione del Governor GPU
Di default la GPU gira sempre a 1500MHz: un governor permette di alzare il clock
quando la GPU è sotto carico e di abbassarlo quando non lo è per consumare meno.
Installeremo `cyan-skillfish-governor-smu`, progetto della community che
comunica direttamente con la System Management Unit della scheda. È anche già
pacchettizzato nella AUR, quindi per installarlo basta lanciare un:
```sh
paru -S cyan-skillfish-governor-smu
systemctl enable --now cyan-skillfish-governor-smu
```
Possiamo contollare che funzioni con:
```
$ cat /sys/class/drm/card1/device/pp_dpm_sclk # Se non funziona prova con card0
0: 1000Mhz *
1: 1500Mhz
2: 2000Mhz
```
La prima e l'ultima riga sono rispettivamente la frequenza minima e massima
della GPU, mentre il valore centrale è variabile. L'asterisco indica la
frequenza attualmente in uso. Un esempio sotto sforzo:
```
$ cat /sys/class/drm/card1/device/pp_dpm_sclk
0: 1000Mhz
1: 1850Mhz *
2: 2000Mhz
```
Dovremmo vedere che la GPU usa automaticamente una frequenza più alta sotto
sforzo e più bassa a riposo.
---
**Piccola nota**: lo sblocco degli 8 core influisce sulla lettura dei valori
dell'SMU. È un problema noto ed andremo a risolverlo più avanti, quando ci
preoccuperemo del sistema operativo. Senza alcun fix i valori di frequenza
risultano sbagliati, ad esempio:
```
$ cat /sys/class/drm/card1/device/pp_dpm_sclk
0: 1000Mhz *
1: 4575Mhz
2: 2000Mhz
# Per un chip che può andare al massimo a 2230MHz non è male come overclock
```
Detto ciò facciamo uno stress test adesso, con il governor installato.
![Furmark (83 FPS)](images/13-furmark-governor.png)
Adesso che riusciamo a scalare fino a 1850MHz la nostra GPU riesce ad arrivare a
83 FPS in 1080p, niente male!
1850MHz non è assolutamente il massimo che questo chip può gestire, ma per
adesso ci accontenteremo di questo. Per i più curiosi la curva delle frequenze e
delle tensioni è completamente personalizzabile e si trova in
`/etc/cyan-skillfish-governor-smu/config.toml`. Con un po' di prove si può
spingere al massimo l'hardware minimizzando i consumi, ma lo faremo sempre
quando andremo a configurare il sistema operativo definitivo.
### Sblocco delle 40 CU
Come abbiamo detto all'inizio questa scheda presenta al kernel solamente 24 CU,
nonostante nella PS5 ce ne siano 36 e sul silicio ce ne siano effettivamente 40.
Possiamo verificarlo con:
```
$ sudo dmesg | grep active_cu_number
[ 6.882856] amdgpu 0000:01:00.0: SE 2, SH per SE 2, CU per SH 10, active_cu_number 24
```
Per testare e successivamente sbloccare tutte le CU useremo il [repository di
duggasco](https://github.com/duggasco/bc250-40cu-unlock). Il meccanismo è simile
a quello dello sblocco dei core: anche qui basta cambiare qualche valore, perché
le CU non sono bloccate a livello hardware, ma solo disattivate dal firmware.
A decidere quante CU sono attive sono due registri della GPU. Quello che fa
questo script è patchare il driver `amdgpu` e scrivere i valori giusti nei
registri mentre il driver si avvia, avviando le CU spente.
```
$ git clone https://github.com/duggasco/bc250-40cu-unlock.git
$ cd bc250-40cu-unlock/
$ sudo pacman -S linux-headers vulkan-headers
$ sudo scripts/bc250-enable-40cu-arch.sh build
# Attendi la ricompilazione del modulo `amdgpu`
$ sudo scripts/bc250-enable-40cu-arch.sh enable
```
Una volta che la BC-250 si sarà riavviata possiamo verificare che la patch ha
funzionato usando sempre il comando di prima:
```
$ sudo dmesg | grep active_cu_number
[ 8.004012] amdgpu 0000:01:00.0: SE 2, SH per SE 2, CU per SH 10, active_cu_number 24
```
A quanto pare il modulo custom non viene caricato in automatico dallo script.
Non è un problema: rigeneriamo l'initramfs e riavviamo a mano:
```
$ sudo mkinitcpio -P
$ reboot
# Una volta che si è riavviato
$ sudo dmesg | grep active_cu_number
[ 8.058999] amdgpu 0000:01:00.0: SE 2, SH per SE 2, CU per SH 10, active_cu_number 40
```
Molto meglio!
---
Una volta installato il modulo custom possiamo procedere con il testing delle
CU:
```
$ sudo scripts/bc250-cu-health-test.sh start
```
Durante il test il PC si riavvierà automaticamente una ventina di volte. Una
volta che il PC smette di riavviarsi in automatico possiamo vedere i risultati
del test con:
```
$ scripts/cu_map.sh
BC-250 CU Map + Health
SE0 SH0: ■■■■■■■■■■
SE0 SH1: ■■■■■■■■■■
SE1 SH0: ■■■■■■■■■■
SE1 SH1: ■■■■■■■■■■
40/40 CUs active, 0 harvested
BC-250 CU Map + Health
SE0 SH0: ■■■■■■✓✓✓✓
SE0 SH1: ■■■■■■✓✓✓✓
SE1 SH0: ■■■■■■✓✓✓✓
SE1 SH1: ■■■■■■✓✓✓✓
40/40 CUs usable (0 defective, masked)
```
A quanto pare ho vinto la lotteria del silicio e ho 8 core e 40 CU funzionanti.
Urrà! 🎉
In caso però ci fossero state delle CU difettose avrei potuto mascherarle usando
lo script `bc250-cu-mask.sh`.
---
Facendo l'ultimo stress test con Furmark:
![Furmark (128 FPS)](images/14-furmark-40cu.png)
Siamo passati dalla scheda nuda e cruda, senza alcun software aggiuntivo, che
girava mediamente a 70 FPS ad avere un governor e tutte le CU sbloccate per
avere dei picchi da 138 FPS, il doppio!
Ovviamente questo approccio per lo sblocco delle 40 CU ha un problema abbastanza
evidente soprattutto su distribuzioni rolling come Arch: bisogna ricordarsi di
ricompilare il modulo ogni volta che si aggiorna il kernel. Anche questo è un
problema che risolveremo più avanti, quando smetteremo di usare un OS di prova,
ma se dopo un aggiornamento la GPU non va più veloce quanto prima forse è meglio
buttarci un occhio.
### Sensori e altre configurazioni indispensabili
Una volta sistemate le cose essenziali come CPU e GPU rimangono alcune piccole
accortezze, come ad esempio la gestione dei sensori, delle ventole, la swap, lo
split della VRAM, ecc...
Potrei starne per ore a parlarne, ma rimando alla [documentazione della
community](https://elektricm.github.io/amd-bc250-docs/), che è ben fornita.
Quello che mi sento di fare adesso è far notare una cosa: usando il comando
`sensors` abbiamo pochi dati OOTB:
```
$ sensors
amdgpu-pci-0100
Adapter: PCI adapter
vddgfx: 799.00 mV
vddnb: 799.00 mV
edge: +39.0°C
PPT: 41.41 W (avg = 40.85 W)
sclk: 1000 MHz
k10temp-pci-00c3
Adapter: PCI adapter
Tctl: +41.6°C
```
Per avere più dati abbiamo bisogno del modulo `nct6683` (read-only) o `nct6687`
(si possono creare curve custom, ma è *out of tree*). Dato che `nct6683` è già
disponibile possiamo abilitarlo con:
```
$ echo 'options nct6683 force=true' | sudo tee /etc/modprobe.d/sensors.conf
$ echo 'nct6683' | sudo tee /etc/modules-load.d/99-sensors.conf
$ sudo mkinitcpio -P
$ reboot
```
Dopo aver riavviato vedremo molti più dati:
```
$ sensors
k10temp-pci-00c3
Adapter: PCI adapter
Tctl: +46.9°C
amdgpu-pci-0100
Adapter: PCI adapter
vddgfx: 799.00 mV
vddnb: 799.00 mV
edge: +41.0°C
PPT: 42.61 W (avg = 40.75 W)
sclk: 1000 MHz
nct6686-isa-0a20
Adapter: ISA adapter
VIN0: 800.00 mV (min = +0.00 V, max = +0.00 V)
VIN1: 1.01 V (min = +0.00 V, max = +0.00 V)
VIN2: 992.00 mV (min = +0.00 V, max = +0.00 V)
VIN6: 1.39 V (min = +0.00 V, max = +0.00 V)
VIN7: 800.00 mV (min = +0.00 V, max = +0.00 V)
VIN16: 896.00 mV (min = +0.00 V, max = +0.00 V)
fan1: 0 RPM (min = 0 RPM)
fan2: 1709 RPM (min = 0 RPM)
fan3: 0 RPM (min = 0 RPM)
fan4: 0 RPM (min = 0 RPM)
fan5: 0 RPM (min = 0 RPM)
AMD TSI Addr 98h: +47.0°C (low = +0.0°C)
(high = +0.0°C, hyst = +0.0°C)
(crit = +0.0°C) sensor = AMD AMDSI
Thermistor 14: +37.0°C (low = +0.0°C)
(high = +0.0°C, hyst = +0.0°C)
(crit = +0.0°C) sensor = thermistor
Thermistor 15: +37.0°C (low = +0.0°C)
(high = +0.0°C, hyst = +0.0°C)
(crit = +0.0°C) sensor = thermistor
pwm1: 64%
pwm2: 64%
pwm3: 64%
pwm4: 64%
pwm5: 64%
intrusion0: OK
beep_enable: disabled
```
## Step 3: Modifiche hardware
Vorrei ricordare che per tutti questi test stavo utilizzando la BC-250 di
Soffio, giusto per vedere se mi potesse interessare. E dato che ormai ero
abbastanza preso, decido di prendermi tutto l'occorrente da AliExpress.
Per fortuna con i saldi e anche grazie a TopCashback riesco a portarmi a casa
tutto il necessario per meno di 200€. Compro poi un paio di Arctic P12 Pro da
Amazon.
In data 24 giugno mi arriva il tutto, e quindi ci si mette all'opera per fare:
* Cambio pasta e pad termici;
* Installazione dei dissipatori sul pannello posteriore, in modo da raffreddare
le GDDR6;
* Rimozione della linguetta metallica e dell'I/O shield (servono solo se la
scheda viene montata nel rig);
* Rifare la suite di test sopracitati per vedere se avevo vinto la lotteria del
silicio per la seconda volta (per fortuna sì);
* Modifica del dissipatore.
La modifica del dissipatore mi permette di risolvere uno dei problemi che stavo
avendo con la scheda, ovvero: come rimuovo 200W di calore? Per adesso avevo il
pinguino, ma non potevo continuare ad usare una pompa di calore per raffreddare
una singola scheda.
Quando sono nel rig da mining, le BC-250 hanno tutti il dissipatore disposto
longitudinalmente, quindi basta un array di ventole per raffreddare tutte e 12
le schede contemporaneamente. Se si vuole usare una di queste schede
indipendentemente bisogna diventare un po' più creativi per rimuovere il calore.
La soluzione più comune nella community è la [heatsink
mod](https://reddit.com/r/BC250Gaming/comments/1rjc3io/), che consiste di aprire
letteralmente il dissipatore nella sezione sopra l'APU per avere un posto dove
mettere la ventola.
È un operazione un po' lunga e tediosa, ma nulla di impossibile. È anche un
compito abbastanza ripetitivo, quindi una volta che si è presa la mano finisce
presto. Alla fine mi ci è voluta solo una forbice, buona musica e un'ora del mio
tempo.
![Prima della modifica al dissipatore](images/15-before-heatsink-mod.jpg "La
BC-250 appena rimossa dalla confezione, senza linguetta metallica e I/O shield")
![Dopo la modifica al dissipatore](images/16-after-heatsink-mod.jpg
"Il dissipatore dopo la modifica")
È un lavoro un po' *rough around the edges* (*literally*), ma funziona. E il
foro è grande esattamente quando una ventola da 120mm, quindi una delle due
ventole porta soffiare direttamente sopra all'APU.
---
Dato che questo articolo si è fatto abbastanza lungo mi sento di spezzettarlo in
più parti. Nella prossima andremo a progettare un case custom per il mio use
case.