fer's brain dump

Armbian on Geniatech XPI-S905x3

March 16, 2025 // , , , ,
Filed under tinker

I’m writing this for me, for my own sanity if I need to do it again, but if it helps someone, better.

A few years back I was reading through the CNX Software RSS feed and I saw this board. It really tempted me to buy it. The Geniatech XPI-S905X3 is a Raspberry Pi form-format SBC, with a reasonably powerful chipset (Amlogic S905x3), 2 GB of RAM, USB3, gigabit ethernet, and so on. At the time of writing it goes for 52 EUR for a sample, but back when I ordered it in 2021 it was a mere 37 USD. It came with Android 9.

I didn’t check compatibility or anything (common mistake on my part, as my gigantic dust-gathering SBC collection can testify), but I was thrilled to have my own tiny Kubernetes cluster running petty homelab stuff, and it blasted everything else out of the water at the time in either price, performance, or both (and even now, with the original price). So I bought two.

Anyway when I got it and finally had some time to play with it, there was no way to make this thing run Linux, just Android.

Armbian wouldn’t boot, *ELEC wouldn’t boot, nothing would.

So excuse the notes below as they’re meant to me, but if you struggled with this device you won’t need much other context.

  1. Prepare a Micro-SD card with Armbian community build for Amlogic S9xx TV Box.

  2. One mistake is trying to use a manline u-boot to boot the thing, I’m not u-boot expert but at some point I spent way too many hours to make it boot the kernel. It wouldn’t work on this board. So here you have replacements for aml_autoscript, s905_autoscript and emmc_autoscript that use the board’s u-boot to do the loading instead. Replace them in your /boot directory from the SD card.

  3. The XPI-S905X3 u-boot doesn’t load aml_autoscript for… reasons. It tries to load other files (and fails because they aren’t there) and it either boots to Android or recovery. So run cp aml_autoscript factory_update_param.ubt, because that factory_update_param.ubt is one of the files it tries.

  4. Device tree. None of the device trees included is fully functional. For me the critical parts were ethernet, USB, and HDMI output. But a few of them were working mostly, some were missing USB, others HDMI, other’s would have ethernet stop working if HDMI is disconnected… the one that worked the best among them, meson-sm1-x96-air-gbit.dtb, had an issue, the issue being it only detected 1GB of memory instead of 2GB. Decompiling the dtb file is a dead end due to missing labels and numerical phandlers. So we’ll generate it from the kernel sources.

    • Boot the board with that device tree (adjusting armbianEnv.txt however it is necessary).
    • Install the sources and the GNU C++ compiler apt install linux-source g++.
    • Preprocess the file: cpp -nostdinc -I /usr/src/linux-source-6.8.0/linux-source-6.8.0/include/ -I arch -undef -x assembler-with-cpp meson-sm1-x96-air-gbit.dts xpi.dts.preprocessed (adjust paths, etc).
    • Edit the preprocessed outputfile from the Linux sources; find the memory node. memory@0 { device_type = "memory"; reg = <0x0 0x0 0x0 0x40000000>; }; Replace the 0x40000000 with 0x80000000
    • Compile it with dtc (in device-tree-compiler package if you don’t have it already): dtc -O dtb -I dts xpi.dts.preprocessed -o xpi.dtb.
    • Update armbianEnv.txt with the new dtb file.

Save, plug (pressing the flash/reset button) and boom, all that I need is there.

Now, there’s plenty of things I haven’t tried: eMMC (I prefer to leave dual booting), Wayland/X (it’s gonna be mostly headless server), so you might need to try other dtbs and see what works, and bring along adjustments from other boards/tv boxes to the preprocessed file. For that it’s fine to do dtc decompilation and explore the device tree, but the decompiled files can’t easily be recompiled again (at least the Armbian ones lack labels).

Happy hacking!