ARCH R

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=panfrost

Then 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:

  1. Reads gpu.driver, defaulting to libmali when it is empty.
  2. Loads the matching kernel module, mali_kbase or panfrost.
  3. Bind-mounts the matching user-space GL libraries into place. For libmali that means /usr/lib/mali/* over Mesa's libEGL.so, libGLESv2.so and friends, plus /dev/null over libGL.so so nothing picks up Mesa by accident. For Panfrost it unmounts all of that so Mesa is visible again.
  4. Checks that the driver really attached: a DRM card exists, the driver-specific node is there (/sys/bus/platform/drivers/panfrost/*.gpu or /dev/mali0), and at least one connector reads connected.
  5. 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

libmaliPanfrost
SourceARM binary driver, version g24p0 for the G31Mesa 26.1.3, open source
Kernel sidemali_kbase, out of treepanfrost, in the mainline kernel
APIOpenGL ESOpenGL and OpenGL ES
Vulkannot on this boardnot on this board
Updateswhatever the vendor drop containsfollows 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.

On this page