diff --git a/content/posts/todo/bc250/featured-background_amanz-IAAxRtlmD9w-unsplash.jpg b/content/posts/todo/bc-zero-board-testing/featured-background_amanz-IAAxRtlmD9w-unsplash.jpg similarity index 100% rename from content/posts/todo/bc250/featured-background_amanz-IAAxRtlmD9w-unsplash.jpg rename to content/posts/todo/bc-zero-board-testing/featured-background_amanz-IAAxRtlmD9w-unsplash.jpg diff --git a/content/posts/todo/bc-zero-board-testing/images/01-not-fully-convinced.png b/content/posts/todo/bc-zero-board-testing/images/01-not-fully-convinced.png new file mode 100644 index 0000000..91463ff Binary files /dev/null and b/content/posts/todo/bc-zero-board-testing/images/01-not-fully-convinced.png differ diff --git a/content/posts/todo/bc-zero-board-testing/images/02-40cu-unlocked-news.png b/content/posts/todo/bc-zero-board-testing/images/02-40cu-unlocked-news.png new file mode 100644 index 0000000..19b2f90 Binary files /dev/null and b/content/posts/todo/bc-zero-board-testing/images/02-40cu-unlocked-news.png differ diff --git a/content/posts/todo/bc-zero-board-testing/images/03-initial-setup.png b/content/posts/todo/bc-zero-board-testing/images/03-initial-setup.png new file mode 100644 index 0000000..4170d2e Binary files /dev/null and b/content/posts/todo/bc-zero-board-testing/images/03-initial-setup.png differ diff --git a/content/posts/todo/bc-zero-board-testing/images/04-bios-flashing.png b/content/posts/todo/bc-zero-board-testing/images/04-bios-flashing.png new file mode 100644 index 0000000..881d84c Binary files /dev/null and b/content/posts/todo/bc-zero-board-testing/images/04-bios-flashing.png differ diff --git a/content/posts/todo/bc-zero-board-testing/images/05-new-boot-logo.png b/content/posts/todo/bc-zero-board-testing/images/05-new-boot-logo.png new file mode 100644 index 0000000..88a8eac Binary files /dev/null and b/content/posts/todo/bc-zero-board-testing/images/05-new-boot-logo.png differ diff --git a/content/posts/todo/bc-zero-board-testing/images/06-new-advanced-menu.png b/content/posts/todo/bc-zero-board-testing/images/06-new-advanced-menu.png new file mode 100644 index 0000000..9fdcf68 Binary files /dev/null and b/content/posts/todo/bc-zero-board-testing/images/06-new-advanced-menu.png differ diff --git a/content/posts/todo/bc-zero-board-testing/images/07-uma-512m.png b/content/posts/todo/bc-zero-board-testing/images/07-uma-512m.png new file mode 100644 index 0000000..6aed3be Binary files /dev/null and b/content/posts/todo/bc-zero-board-testing/images/07-uma-512m.png differ diff --git a/content/posts/todo/bc-zero-board-testing/images/08-8-core-unlock.png b/content/posts/todo/bc-zero-board-testing/images/08-8-core-unlock.png new file mode 100644 index 0000000..40e8f08 Binary files /dev/null and b/content/posts/todo/bc-zero-board-testing/images/08-8-core-unlock.png differ diff --git a/content/posts/todo/bc-zero-board-testing/images/09-archinstall.png b/content/posts/todo/bc-zero-board-testing/images/09-archinstall.png new file mode 100644 index 0000000..9f70a70 Binary files /dev/null and b/content/posts/todo/bc-zero-board-testing/images/09-archinstall.png differ diff --git a/content/posts/todo/bc-zero-board-testing/images/10-fastfetch.png b/content/posts/todo/bc-zero-board-testing/images/10-fastfetch.png new file mode 100644 index 0000000..9c58e7f Binary files /dev/null and b/content/posts/todo/bc-zero-board-testing/images/10-fastfetch.png differ diff --git a/content/posts/todo/bc-zero-board-testing/images/11-baseline-furmark.png b/content/posts/todo/bc-zero-board-testing/images/11-baseline-furmark.png new file mode 100644 index 0000000..4ca697d Binary files /dev/null and b/content/posts/todo/bc-zero-board-testing/images/11-baseline-furmark.png differ diff --git a/content/posts/todo/bc-zero-board-testing/images/12-dead-psu.jpg b/content/posts/todo/bc-zero-board-testing/images/12-dead-psu.jpg new file mode 100644 index 0000000..408767a Binary files /dev/null and b/content/posts/todo/bc-zero-board-testing/images/12-dead-psu.jpg differ diff --git a/content/posts/todo/bc-zero-board-testing/images/13-furmark-governor.png b/content/posts/todo/bc-zero-board-testing/images/13-furmark-governor.png new file mode 100644 index 0000000..5bd5165 Binary files /dev/null and b/content/posts/todo/bc-zero-board-testing/images/13-furmark-governor.png differ diff --git a/content/posts/todo/bc-zero-board-testing/images/14-furmark-40cu.png b/content/posts/todo/bc-zero-board-testing/images/14-furmark-40cu.png new file mode 100644 index 0000000..5a928ca Binary files /dev/null and b/content/posts/todo/bc-zero-board-testing/images/14-furmark-40cu.png differ diff --git a/content/posts/todo/bc-zero-board-testing/images/15-before-heatsink-mod.jpg b/content/posts/todo/bc-zero-board-testing/images/15-before-heatsink-mod.jpg new file mode 100644 index 0000000..efc40a1 Binary files /dev/null and b/content/posts/todo/bc-zero-board-testing/images/15-before-heatsink-mod.jpg differ diff --git a/content/posts/todo/bc-zero-board-testing/images/16-after-heatsink-mod.jpg b/content/posts/todo/bc-zero-board-testing/images/16-after-heatsink-mod.jpg new file mode 100644 index 0000000..14ac4f7 Binary files /dev/null and b/content/posts/todo/bc-zero-board-testing/images/16-after-heatsink-mod.jpg differ diff --git a/content/posts/todo/bc-zero-board-testing/index.it.md b/content/posts/todo/bc-zero-board-testing/index.it.md new file mode 100644 index 0000000..b800b0e --- /dev/null +++ b/content/posts/todo/bc-zero-board-testing/index.it.md @@ -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. diff --git a/content/posts/todo/bc-zero-board-testing/index.md b/content/posts/todo/bc-zero-board-testing/index.md new file mode 100644 index 0000000..2915845 --- /dev/null +++ b/content/posts/todo/bc-zero-board-testing/index.md @@ -0,0 +1,525 @@ ++++ +title = "BC-Zero - Board Testing" +summary = "From an old mining board to a console and AI server" +date = "2038-01-19" + +tags = ["BC-250", "PS5", "Unlock", "BIOS", "CPU", "GPU"] +categories = ["Projects"] +series = ["BC-Zero"] +series_order = 1 + +draft = true ++++ + +On February 5th, [Soffio](https://t.me/Soffioo), a friend and fellow +[LUGMan](https://lugman.org/) member, made me discover a peculiar board: the +**BC-250**. + +The BC-250 is a board that comes from an [ASRock cryptocurrency mining +rig](https://www.tomshardware.com/news/twelve-ps5-apus-power-asrocks-new-cryptomining-rig), +which housed twelve of them. + +Inside each of these boards there's a *binned* chip derived from the AMD APU of +the PlayStation 5, with 6 of the 8 CPU cores and 24 of the 36 GPU CUs enabled, +along with 16GB of GDDR6 RAM **unified** between CPU and GPU, an M.2 slot (PCIe +2.0x2 or SATA III), and just a few ports: two USB 2.0, two USB 3.0, one Gigabit +Ethernet, and one DisplayPort. Power is supplied through an 8-pin PCIe +connector. + +At first I wasn't really convinced, especially seeing a third of the CUs cut off +and knowing that it's a board with a custom, partially locked chip (on top of +the locked cores, some features like video encoding/decoding are missing), +coming from cryptocurrency mining and with no support or community behind it. +But the price was definitely interesting, and apparently this board has a very +active community that works hard to squeeze 100% of its potential out of it on +Linux. + +![Soffio: "If you want I can give you one, I bought it without the coupon and I +was planning to resell it😂" "So technically I'm getting two😂" Me: "Nah, no +worries" "I wouldn't know what to do with it"](images/01-not-fully-convinced.png +"Me, not fully convinced

**Translation**:
*Soffio*: \"If you want I +can give you one, I bought it without the coupon and I was planning to resell +it😂\" \"So technically I'm getting two😂\"
*Me*: \"Nah, no worries\" \"I +wouldn't know what to do with it\"") + +Things changed when, on the morning of May 30th, I got this message: + +![Soffio: "They managed to unlock all the CUs, went from 24 to 40. Now they're +looking into unlocking the 8 cores😂🌚👌"](images/02-40cu-unlocked-news.png +"
**Translation**:
*Soffio*: \"They managed to unlock all the CUs, went +from 24 to 40. Now they're looking into unlocking the 8 cores😂🌚👌\"") + +And good old Soffio also pointed out that the AliExpress sales were about to +start. Intrigued by the whole thing, I asked him if he could lend me his board +for a few days, just to try it out and see what could be done. + +And *oh boy*, did this board convince me. + +## Step 0: Preparation + +One downside of the BC-250 is that it's not exactly *plug-and-play*. At the very +least, you need to: + +1. Find a power supply that can ***really*** deliver at least 300W on the +12V + rail, with cables that can handle all those amperes; +2. Have a monitor with DisplayPort (or buy an adapter); +3. Find a way to cool the damn thing; +4. Flash the BIOS. + +My test setup was: + +1. The first "*el cheapo*" power supply I could find lying around (which "will + surely be fine, it says 500W"); +2. A passive DP ➜ HDMI adapter; +3. A portable air conditioner for cooling (it was summer and it was starting to + get hot); +4. A CH341 SPI programmer (which I already had). + +![Home setup](images/03-initial-setup.png "If you look closely, the PS_ON ➜ GND +bridge was made with a jumper wire and all the power goes through a SATA ➜ PCIe +adapter. Don't try this at home") + +Not exactly the best setup for testing the board, but you work with what you +have. + +## Step 1: Flashing the BIOS + +The [first step in the community +documentation](https://elektricm.github.io/amd-bc250-docs/getting-started/quick-start/#step-1-bios-flash-critical) +is flashing the BIOS. Without a custom BIOS you don't get essential features +like dynamic VRAM allocation (remember, the 16GB of RAM are shared) and proper +fan control. + +At first I installed the one recommended by the guide, the one by +[TuxThePenguin0](https://gitlab.com/TuxThePenguin0/bc250-bios), but later on I +discovered another BIOS, the one by [Forbidden +Darkness](https://github.com/Forbidden-Darkness/AMD-BC-250-UEFI-v2.2-Firmware-Menu-Script), +which, on top of unlocking the dynamic allocation menu, offers a selection of +custom splash images and, most importantly, **unlocks all 8 CPU cores**. + +"*Wait, weren't they locked down?*" Apparently not enough. + +The APU has all cores on the silicon, they're just disabled via firmware. A +similar principle also applies to the GPU CUs, but we'll get to that later. + +--- + +The installation is even simpler and doesn't require a BIOS flasher: just copy +the files from the `.7z` archive in the releases to a USB stick formatted in +FAT32 and boot from it. The installer asks which splash image we want (the +[`07`](https://github.com/user-attachments/assets/ca23ce6c-08ab-4293-9a70-0e55f66dc93c) +is the best one, *imho*) and proceeds with the flashing. + +![Flashing the BIOS](images/04-bios-flashing.png "Flashing the BIOS") + +{{< alert icon="triangle-exclamation" cardColor="#e6d237" iconColor="#1d3557" +textColor="#1d3557" >}} +Flashing the BIOS is a dangerous operation. Make sure the board doesn't turn +off. +{{< /alert >}} + +Once the flashing is done, you need to reset all the BIOS settings. To do that, +just unplug the power and bridge pin 2 and 3 of the `CLRCMOS1` header for a few +seconds. Once that's done, we can put the header back on pins 1 and 2 and plug +the power back in. By entering the BIOS with the `Del` key at boot we'll see a +lot more options. + +![New boot logo](images/05-new-boot-logo.png "New boot logo") +![New entries in the "Advanced" menu](images/06-new-advanced-menu.png "New +entries in the \"Advanced\" menu") + +First, let's make the VRAM allocation automatic. To do that, we need to go to +`Chipset` > `GFX Configuration` > `GFX Configuration` and set `Integrated +Graphics Controller` to `Forces`, then `UMA Mode` to `UMA_SPECIFIED`, and +finally `UMA Frame buffer size` to `512M`. + +![The correct UMA configuration](images/07-uma-512m.png "The correct UMA +configuration") + +Then in `NB Configuration` disable the IOMMU (it doesn't seem to work on this +board). + +Finally, we enable all the cores by going to `Advanced` > `MeiMeiDXEv3 Menu` and +enabling everything. + +![The configuration to enable all 8 cores](images/08-8-core-unlock.png "The +configuration to enable all 8 cores") + +{{< alert icon="triangle-exclamation" cardColor="#e6d237" iconColor="#1d3557" +textColor="#1d3557" >}} +There's no guarantee that all the cores will work. Damaged cores could cause +sudden crashes. + +To avoid that, we'll run a stress test on all the cores and check that no +`Machine Check Exception` shows up in the kernel logs before enabling this +setting in production. +{{< /alert >}} + +Once the BIOS is properly configured, we're ready to install an operating system +and test this board for real. + +## Step 2: Installing a OS for testing + +To do some CPU stress testing and run some tests on the GPU, I'll install Arch +Linux. + +It won't be the final distro I'll install, but the choice isn't random: +development for this board is bleeding-edge, and for now almost all the scripts +assume you're running Arch or Fedora, so you have the latest package versions. + +![The archinstall configuration I'll use](images/09-archinstall.png "The +archinstall configuration I'll use") +![The installed system](images/10-fastfetch.png "The installed system. As you +can see, all 16 threads already show up") + +### Testing the 8 cores + +First of all, let's test whether all 8 cores work as they should. To do that, +install the `stress-ng` package and run a stress test: + +```sh +stress-ng --cpu 16 --cpu-method all --verify --timeout 2h --metrics +``` + +Then we check that there were no errors with: + +```sh +sudo dmesg | grep -iE "mce|machine check|hardware error" +``` + +If the kernel doesn't report any errors, we've just gone from 6 to 8 cores for +free. If there is an error you can change which cores to enable from the BIOS. + +### Stress-testing the GPU + +Next, let's stress test the GPU to get a performance baseline before installing +the governor or enabling all the CUs. To do that, I installed Furmark and ran +the 1080p test. + +![Furmark (68 FPS)](images/11-baseline-furmark.png) + +I'd say 70 FPS isn't *that* bad for the board *out-of-the-box*, but we can +definitely do better, much better. + +--- + +A small note I feel I should add: if during the stress test the screen goes +black and the board doesn't respond in any way, check your power supply. The +little foreshadowing I did in step 0 about the power supply is because during my +tests I ran Ollama and completely fried the PSU since (apparently) it couldn't +really handle the whole load on the +12V rail. I then bought the PSU recommended +by the community on AliExpress, along with the board, the [Metalfish 500W +FlexATX](https://elektricm.github.io/amd-bc250-docs/hardware/power#option-2-flexatx-psu-500w), +and I haven't had any problems since. + +![Deceased PSU](images/12-dead-psu.jpg "Rest in peace, soldier 🫡") + +### Installing the GPU Governor + +By default the GPU always runs at 1500MHz: a governor lets you raise the clock +when the GPU is under load and lower it when it isn't, to save power. + +We'll install `cyan-skillfish-governor-smu`, a community project that talks +directly to the board's System Management Unit. It's also already packaged in +the AUR, so to install it you just need to run: + +```sh +paru -S cyan-skillfish-governor-smu +systemctl enable --now cyan-skillfish-governor-smu +``` + +We can check that it works with: + +``` +$ cat /sys/class/drm/card1/device/pp_dpm_sclk # If it doesn't work, try card0 +0: 1000Mhz * +1: 1500Mhz +2: 2000Mhz +``` + +The first and last lines are, respectively, the minimum and maximum GPU +frequency, while the middle line can change. The asterisk marks the frequency +currently in use. An example under load: + +``` +$ cat /sys/class/drm/card1/device/pp_dpm_sclk +0: 1000Mhz +1: 1850Mhz * +2: 2000Mhz +``` + +We should see the GPU automatically use a higher frequency under load and a +lower one when idle. + +--- + +**Small note**: unlocking the 8 cores affects how the SMU values are read. It's +a known issue and we'll fix it later on, when we'll deal with the operating +system. Without any fix, the frequency values are wrong, for example: + +``` +$ cat /sys/class/drm/card1/device/pp_dpm_sclk +0: 1000Mhz * +1: 4575Mhz +2: 2000Mhz + +# Not a bad overclock for a chip that tops out at 2230MHz +``` + +With that said, let's run a stress test now, with the governor installed. + +![Furmark (83 FPS)](images/13-furmark-governor.png) + +Now that we can scale up to 1850MHz, our GPU manages to reach 83 FPS at 1080p, +not bad! + +1850MHz is by no means the most this chip can handle, but for now we'll settle +for it. For the curious, the frequency and voltage curves are fully customizable +and live in `/etc/cyan-skillfish-governor-smu/config.toml`. With a bit of trial +and error you can push the hardware to its limits while minimizing power draw, +but we'll do that when we set up the final operating system. + +### Unlocking the 40 CUs + +As we said at the beginning, this board only exposes 24 CUs to the kernel, even +though the PS5 has 36 and there are actually 40 on the silicon. We can verify +this with: + +``` +$ 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 +``` + +To test and then unlock all the CUs, we'll use [duggasco's +repository](https://github.com/duggasco/bc250-40cu-unlock). The mechanism is +similar to the core unlock: here too you just need to change a few values, +because the CUs aren't locked at the hardware level, they're just disabled by +the firmware. + +Two registers in the GPU decide how many CUs are active. What this script does +is patch the `amdgpu` driver and write the right values into those registers +while the driver starts up, waking up the disabled CUs. + +``` +$ 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 + +# Wait for the `amdgpu` module to be recompiled + +$ sudo scripts/bc250-enable-40cu-arch.sh enable +``` + +Once the BC-250 has rebooted, we can check that the patch worked using the same +command as before: + +``` +$ 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 + +``` + +Apparently the script doesn't load the custom module automatically. That's not a +problem: let's regenerate the initramfs and reboot manually: + +``` +$ sudo mkinitcpio -P +$ reboot + +# Once it has rebooted +$ 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 +``` + +Much better! + +--- + +Once the custom module is installed, we can move on to testing the CUs: + +``` +$ sudo scripts/bc250-cu-health-test.sh start +``` + +During the test the PC will automatically reboot twenty times. Once the PC stops +rebooting on its own, we can see the test results with: + +``` +$ 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) +``` + +Apparently I won the silicon lottery and have 8 cores and 40 working CUs. +Hurray! 🎉 + +If there had been any defective CUs I could have masked them using the +`bc250-cu-mask.sh` script. + +--- + +Running the last stress test with Furmark: + +![Furmark (128 FPS)](images/14-furmark-40cu.png) + +We went from the bare board, without any additional software, running at an +average of 70 FPS, to having a governor and all the CUs unlocked, with peaks of +138 FPS, twice as much! + +Of course, this approach to unlocking the 40 CUs has a pretty obvious problem, +especially on rolling distributions like Arch: you have to recompile the module +every time you update the kernel. This is another problem we'll solve later on, +when we stop using a test OS, but if after an update the GPU isn't as fast as +before, it might be worth taking a look. + +### Sensors and Other Essential Configurations + +Once the essentials like CPU and GPU are sorted out, there are still a few small +things to take care of, such as sensor management, fans, swap, VRAM split, +etc... + +I could go on about it for hours, but I'll point you to the [community +documentation](https://elektricm.github.io/amd-bc250-docs/), which is very +thorough. + +What I'd like to do now is point out one thing: using the `sensors` command, we +get very little data 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 +``` + +To get more data we need the `nct6683` module (read-only) or `nct6687` (you can +create custom curves with it, but it's *out of tree*). Since `nct6683` is +already available, we can enable it with: + +``` +$ 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 +``` + +After rebooting we'll see a lot more data: + +``` +$ 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: Hardware Mods + +I want to remind you that for all these tests I was using Soffio's BC-250, just +to see whether it was something I'd be interested in. And since I found myself +pretty hooked I decided to get everything I needed from AliExpress. + +Luckily with the sales and also using TopCashback I managed to bring home +everything I needed for less than €200. I then bought a couple of Arctic P12 +Pros from Amazon. + +Everything arrived on June 24th, so it was time to get to work on: + +* Replacing the thermal paste and pads; +* Installing heatsinks on the back panel, to cool the GDDR6; +* Removing the metal bracket and the I/O shield (they're only needed if the + board is mounted in the rig); +* Re-running the test suite mentioned above to see if I had won the silicon + lottery a second time (luckily I did); +* Modding the heatsink. + +The heatsink mod let me solve one of the problems I was having with the board: +how do I get rid of 200W of heat? So far I had the portable AC, but I couldn't +keep using a heat pump to cool a single board. + +When they're in the mining rig, the BC-250 all have their heatsinks laid out +lengthwise, so a single array of fans is enough to cool all 12 boards at once. +If you want to use one of these boards on its own, you need to get a bit more +creative to get rid of the heat. + +The most common solution in the community is the [heatsink +mod](https://reddit.com/r/BC250Gaming/comments/1rjc3io/), which consists of +literally cutting open the heatsink in the section above the APU to make room +for a fan. + +It's a somewhat long and tedious job, but it's not impossible to do. It's also a +pretty repetitive task, so once you get the hang of it, it goes by farely +quickly. In the end all it took was a pair of scissors, some good music, and an +hour of my time. + +![Before the heatsink mod](images/15-before-heatsink-mod.jpg "The BC-250 as it +comes out of the box, with the metal bracket and I/O shield removed") +![After the heatsink mod](images/16-after-heatsink-mod.jpg "The heatsink after +the mod") + +It's a bit *rough around the edges* (*literally*), but it works. And the hole is +big exactly as a 120mm fan, so one of the two fans can blow directly onto the +APU. + +--- + +Since this article has gotten pretty long, I've decided to split it into +multiple parts. In the next one, we'll design a custom case for my needs. diff --git a/content/posts/todo/bc250/index.it.md b/content/posts/todo/bc250/index.it.md deleted file mode 100644 index aec6fea..0000000 --- a/content/posts/todo/bc250/index.it.md +++ /dev/null @@ -1,12 +0,0 @@ -+++ -title = "BC-Zero" -summary = "Da vecchia scheda da mining a console e server AI" -date = "2038-01-19" - -tags = ["BC-250", "PS5", "AI", "AI Locale", "SteamOS", "CachyOS"] -categories = ["Progetti"] - -draft = true -+++ - -> Hello, world! diff --git a/content/posts/todo/bc250/index.md b/content/posts/todo/bc250/index.md deleted file mode 100644 index 9f3fcc2..0000000 --- a/content/posts/todo/bc250/index.md +++ /dev/null @@ -1,12 +0,0 @@ -+++ -title = "BC-Zero" -summary = "From an old mining card to a console and AI server" -date = "2038-01-19" - -tags = ["BC-250", "PS5", "AI", "Local AI", "SteamOS", "CachyOS"] -categories = ["Projects"] - -draft = true -+++ - -> Hello, world!