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.
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
.
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 scp
ed 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!
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.
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!
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.
Roms/PORTS
folder.