+++ title = "BC-Zero - Board Testing" summary = "From an old mining board to a console and AI server" date = "2026-11-08" tags = ["BC-250", "PS5", "Unlock", "BIOS", "CPU", "GPU"] categories = ["Projects"] series = ["BC-Zero"] series_order = 1 +++ 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.