Posts

First published: Feb 1, 2025, 2:26pm -0400
Last edited: Feb 1, 2025, 3:02pm -0400

Python 3, Pygame, and Debian Bookworm on the Miyoo A30

What if I told you you can get a full Linux computer with WiFi and a GPU in a small, pocket form factor for about $30 USD on AliExpress? You might say “but what about the new tariffs?” and I’d say “oof, oh right, okay who knows, but it’s probably still pretty cheap!” (Edit: looks like you can get one for about $40 now).

It wasn’t a big hit with the retro handheld gaming community, but the Miyoo A30 has a 4 core Cortex A7 with a Mali-400 MP GPU, 512 MB of RAM, WiFi, and an incredible little 640x480 IPS screen. It has enough power to emulate many Nintendo 64 games, but that’s not what I bought it for. In fact, I bought two so my son and I could make networked multiplayer games together.

I already have a game I made in Pygame back in college, so naturally, I wanted to first get modern Python 3 and Pygame working on it.

If you want to ignore my work log and just skip to the files, at the bottom I have premade files for you so you can install Python programs on your Miyoo A30 by just copying some things onto your SD card.

Game plan

Upgrading the Miyoo A30

First step, the software that comes on this little device is garbage, so you want to replace that.

The internet seems to think that spruceOS is currently the best custom image you can get for the A30, and it is quite nice. It doesn’t come with Python or Pygame, but it does come with firmware upgrade software (so that your WiFi drivers are the latest), and also comes with all of the latest and greatest emulators optimally configured if that’s your thing.

The only downside with running spruceOS is it still uses a Linux 3.x kernel. Using the provided kernel is a good call since it has the best driver support for the hardware, but Linux 3.x is missing some syscalls some Debian Bookworm software now takes for granted. This means that Debian Bookworm’s apt-get won’t work, but that’s okay, many other things still work, including venv and pip.

Debian in a chroot

On my laptop, I used debootstrap to create a folder with a Debian system ready to be configured.

sudo debootstrap --arch=armhf --foreign --variant=minbase --include python3,python3-venv,python3-pip,python3-requests,python3-pygame,nano bookworm ~/miyoo-bookworm/

Since apt-get doesn’t work, if you’re doing this yourself, make sure to include any packages you want in your Debian installation in the list above.

Then, on the Miyoo A30, in spruceOS’s advanced configuration, I enabled SSH, SSHed to the device, then created an ext4 filesystem on the SD card and mounted it:

dd if=/dev/zero of=bookworm-python.img bs=4096 count=$((1024*256))
mkfs.ext4 bookworm-python.img
mkdir bookworm-python
mount -o loop bookworm-python.img bookworm-python

Then, I scped all of the contents of my laptop’s miyoo-bookworm folder into that new loopback mountpoint.

Finally, I ran this on the Miyoo to finish the Debian installation:

chroot bookworm-python
/debootstrap/debootstrap --second-stage

Tada! Debian works! Python works!

Graphics and input drivers

Okay, so Pygame doesn’t really work yet, since the Debian installation doesn’t have the right SDL drivers or GPU drivers. The spruceOS installation does though.

Inside the Debian filesystem, I made /usr/local/lib/miyoo-overrides. Then I copied the following libraries from the spruceOS parent filesystem’s /usr/lib/miyoo folder into the Debian filesystem’s miyoo-overrides folder that I just made: libEGL.so*, libGLESv1_CM.so*, libGLESv2.so*, libMali.so, libSDL2-2.0.so*, and libudev.so*. Note that all of the libEGL and libGLES libraries are actually just symlinks to libMali.so.

I reentered the chroot and ran:

echo /usr/local/lib/miyoo-overrides/ > /etc/ld.so.conf.d/00-miyoo-overrides.conf
ldconfig

This makes it so all programs inside the chroot can find the spruceOS provided video and input libraries.

Get the Python apps to show up in spruceOS

First we need a tool for safely entering the chroot while still having all of the kernel devices and filesystems show up appropriately. Here is run-inside.sh which will start a program inside the chroot, making sure it is set up right.

#!/bin/sh

BASE=/mnt/SDCARD/bookworm-python3.img
ROOT=/mnt/SDCARD/bookworm-python3

mount > /tmp/current-mounts
if ! grep -q $ROOT /tmp/current-mounts; then
  mkdir -p $ROOT
  mount -o loop $BASE $ROOT
  for dir in /dev /proc /sys /tmp /dev/pts /mnt/SDCARD; do
    mkdir -p $ROOT$dir
    mount -o loop $dir $ROOT$dir
  done
  mkdir -p $ROOT/mnt/root
  mount -o loop / $ROOT/mnt/root
fi

rm /tmp/current-mounts

command="$1"
shift
if [ "x$command" == "x" ]; then
  command="/bin/bash"
fi

exec chroot $ROOT/ /usr/bin/env \
  LD_LIBRARY_PATH= \
  PATH=/usr/sbin:/usr/bin:/sbin:/bin \
  SHELL=/bin/bash \
  "$command" "$@"

Now, we need a sample Pygame app. I used this one for testing. I put this project’s app.py on my SD card.

Finally, you need to make a script on the SD card inside Roms/PORTS. Here is hello-miyoo.sh:

#!/bin/sh

exec /mnt/SDCARD/run-inside.sh python3 /mnt/SDCARD/app.py

When you next open your Miyoo spruceOS UI, There will be an entry named after this script (hello-miyoo) in the “Ports” section of the “Games” category!

What doesn’t work

Mostly, this works great! All of the buttons are recognized by Pygame, Pygame gets GPU acceleration, sound works, etc.

Unfortunately, the screen is rotated 90 degrees. With some other spruceOS provided builds of libSDL2, the screen isn’t rotated, but GPU acceleration is disabled and many other things are broken.

If anyone has an idea of how to fix this, please let me know!

For now, I am simply using Pygame to rotate my screen another 90 degrees.

All the files