GPU driver
The two GPU stacks in the image, which one boots, and how to change it
The image carries two ways of driving the Mali-G31: the ARM binary driver (libmali in user space, mali_kbase in the kernel) and Mesa 26.1.3 with the Panfrost Gallium driver. Both are built and installed, and only one is active at a time.
The system boots libmali. That is the current default, not Panfrost.
Why libmali is the default right now
gpu.driver is not written into the shipped system.cfg, so on a fresh install the boot script finds it empty and sets it to libmali itself.
The picker is also hidden on purpose. EmulationStation shows a GPU DRIVER row only when /usr/bin/gpudriver exists, and ArchR installs that helper at /usr/lib/archr/gpudriver instead. The reason recorded in the package is that the Panfrost path is still unreliable on RK3326 clone boards: the probe can hang the kernel on some of them, and mali_kbase cannot be unloaded safely to recover. Until that is fixed the switch stays out of the menu.
Changing it anyway
Over SSH, edit /storage/.config/system/configs/system.cfg and set:
gpu.driver=panfrostThen reboot. Set it back to libmali the same way. There is nothing else to change: the boot script reads that one key.
What happens at boot
An autostart hook runs /usr/lib/archr/gpudriver --start, which:
- Reads
gpu.driver, defaulting tolibmaliwhen it is empty. - Loads the matching kernel module,
mali_kbaseorpanfrost. - Bind-mounts the matching user-space GL libraries into place. For libmali that means
/usr/lib/mali/*over Mesa'slibEGL.so,libGLESv2.soand friends, plus/dev/nulloverlibGL.soso nothing picks up Mesa by accident. For Panfrost it unmounts all of that so Mesa is visible again. - Checks that the driver really attached: a DRM card exists, the driver-specific node is there (
/sys/bus/platform/drivers/panfrost/*.gpuor/dev/mali0), and at least one connector readsconnected. - If that check fails, it loads the other driver and saves it as the new
gpu.driver, so you end up with a working screen rather than a black one.
Everything it does is logged to /storage/.config/gpudriver.log, which survives reboots. When Panfrost is selected it also drops the kernel messages from around the probe next to it.
Boot-loop protection
Before touching the driver, the script writes the driver name to /storage/.config/gpudriver.attempting with a synchronous write, and removes it once the driver is up. If that file is still there on the next boot, the previous attempt crashed the board before it could recover, so the script forces libmali and rewrites the setting. That is what keeps a bad Panfrost probe from turning into an endless reboot cycle.
Differences that matter
| libmali | Panfrost | |
|---|---|---|
| Source | ARM binary driver, version g24p0 for the G31 | Mesa 26.1.3, open source |
| Kernel side | mali_kbase, out of tree | panfrost, in the mainline kernel |
| API | OpenGL ES | OpenGL and OpenGL ES |
| Vulkan | not on this board | not on this board |
| Updates | whatever the vendor drop contains | follows Mesa releases |
No Vulkan driver is built for RK3326 either way. Mesa is configured with an empty -Dvulkan-drivers=, and the libmali package only installs Vulkan libraries on other SoCs. Emulators that probe for Vulkan here will not find it and fall back to GLES.
Mesa tuning
/etc/profile.d/041-panfrost is sourced by /etc/profile, so these reach every emulator launched through runemu.sh and the start_*.sh scripts:
PAN_MESA_DEBUG=forcepack # pack vertex attributes, fewer draw calls on G31
MESA_NO_ERROR=1 # emulators do not check glGetError
MESA_SHADER_CACHE_DIR=/var/cache/mesa
MESA_SHADER_CACHE_MAX_SIZE=128MB/var/cache/mesa is a symlink onto /storage/.cache/mesa_shader_cache, so the shader cache survives reboots.
/etc/profile.d/mali-priority.sh sets MALI_SCHED_RT_THREAD_PRIORITY=95 for the libmali path.
Troubleshooting
Black screen after setting gpu.driver=panfrost. Power off, take the card out, mount the storage partition on a PC and set gpu.driver=libmali back. If the board managed to reboot at all, the sentinel should have done that for you already.
You set panfrost but the system came up on libmali. The bind check failed and the fallback ran. /storage/.config/gpudriver.log says which of the three conditions (card, bind, display) was not met, with the relevant dmesg lines under it.
Switching does not seem to take effect immediately. It cannot. Neither module can be unloaded safely while the other is running, so the change only applies on the next boot.