Appliance image · drdro-arch

The Raspberry Pi appliance image

A purpose-built Arch Linux ARM image that boots straight into drDRO — full-screen, silent, touch-ready, no desktop. One image covers the Pi 3 / 4 / 5 family. This page explains how it works, how to configure and maintain it, and how to build your own.

Just want to flash it? → Image repo ↗ Verified on Pi 3B & Pi 5

Overview

Rather than install Raspberry Pi OS and hand-configure Python, Kivy, touch, autostart and the serial link, the appliance image ships all of it pre-baked. Power on and you're in the DRO.

  • Boots directly to the app on KMS/DRM (SDL2 kmsdrm) — full-screen, no display server.
  • The UART is left free for the RS-485 board link (no serial console).
  • The app venv ships inside the image, so first boot needs no network.
  • Root is writable, so the in-app updater can pull a newer app or flash firmware in the field.
  • The root filesystem auto-grows to fill the SD card on first boot — any card size works.
  • One universal aarch64 image; the firmware selects the right device tree per board.

Set it up

For end use, there's nothing to assemble — download the release image, flash it, and boot:

  1. Download & flash

    Grab the latest image and write it to an SD card — the full walkthrough (Raspberry Pi Imager or dd, checksum, tested Pi models) is on the Get Started page.

  2. Wire it up

    Connect the drDRO board to the Pi's RS-485/UART and attach the touchscreen.

  3. Boot

    Power on — silent splash, then the app. The root FS grows to the card on the first boot.

🔧

The rest of this page is for people who want to configure, maintain, customise or rebuild the image. If you only want a working DRO, Get Started is all you need.

How it works

The image is assembled by a single build.sh that runs on a native aarch64 host (the GitHub ARM64 runner — no qemu):

  1. Fetch the base rootfs

    Downloads and unpacks the Arch Linux ARM rpi-aarch64 tarball.

  2. Swap in the Raspberry Pi kernel

    In a native chroot, replaces ALARM's mainline kernel + U-Boot with linux-rpi — so it direct-boots kernel8.img, our cmdline.txt is authoritative, and the firmware auto-selects the per-board dtb.

  3. Install the runtime

    pacman -S the packages the Kivy wheel needs: SDL2, mesa (VC4/V3D GL), mtdev (touch), Python, git, NetworkManager, audio, fonts (see packages.txt).

  4. Bake the app venv

    pyenv builds CPython 3.13 and pip installs the app into a venv at /opt/drdro/app/.venv — native aarch64 wheels, so the venv lives inside the image and first boot is offline-clean.

  5. Overlay & configure

    Drops in the launcher, drdro.service and the helper services, and writes config.txt/cmdline.txt.

  6. Assemble the SD image

    Builds a 2-partition image (FAT boot + ext4 root) with mke2fs -d + mtools — no loop mounts.

Boot is silent (Plymouth drDRO splash → app). drdro-growfs.service grows the root partition on first boot; drdro-vt-watch.service hands the screen between the app and the maintenance consoles.


Access & maintenance

Logins dev defaults

  • default / default — in wheel, passwordless sudo.
  • SSH enabled (password login): ssh default@<ip>.
  • Stock ALARM root/root and alarm/alarm also exist.

These are intentionally permissive for setup — change the password (and consider disabling SSH) on a shared network.

On-screen consoles

  • Ctrl+Alt+F2 — a login shell for maintenance.
  • Ctrl+Alt+F3 — a live tail of the app / Kivy log.
  • Ctrl+Alt+F1 — back to the app.

The app takes a couple of seconds to release the screen on a VT switch (SDL teardown).

📁

Where things live: the app is at /opt/drdro/app (a git checkout + its .venv), runs as root via drdro.service, and logs to /var/log/drdro/. The image stamps its version at /etc/drdro-release.

Configure

WhatWhere / how
Serial port to the boardApp config.iniserial_port = /dev/serial0 (the Pi's GPIO UART; set by the build).
Wi-FiFrom the app's Network screen (NetworkManager / nmcli), or nmcli over SSH.
DisplayTargets a 1024×600 USB touch panel; mtdev auto-detects the touch controller — no Kivy config needed.
Boot / kernel optionsboot/config.txt and boot/cmdline.txt (linux-rpi stock + drDRO settings appended).
Pi 5 USB powerShips usb_max_current_enable so a USB touch panel doesn't trip the 600 mA cap.
StorageRoot auto-grows on first boot (drdro-growfs.service); no manual resize.

Build it yourself

Building the image requires a native aarch64 host with root (a Raspberry Pi, an aarch64 VM/cloud instance, or the ARM64 CI runner) — there's no qemu emulation step.

Local build

bash (on an aarch64 host)
git clone https://github.com/bartei/drdro-arch.git
cd drdro-arch
sudo ./build.sh
# -> out/drdro-arch-rpi-aarch64.img

Build-time knobs (environment variables)

VariableDefaultMeaning
APP_REFlatestApp version to bake in — newest release tag, or a tag/branch/rev.
ENABLE_PLYMOUTH1Silent boot + drDRO splash; 0 = verbose boot.
BOOT_MB128Size of the FAT boot partition.
DRDRO_VERSIONdevVersion stamp (CI passes the real release version).
WORK / OUT./work / ./outScratch and output directories.

Build via CI, then flash

bash
gh workflow run build-arch -R bartei/drdro-arch          # or push to main
gh run download <run-id> -R bartei/drdro-arch -n drdro-arch-rpi-aarch64
sudo dd if=drdro-arch-rpi-aarch64.img of=/dev/sdX bs=4M conv=fsync status=progress

What to customise

  • packages.txt — the pacman runtime package list.
  • overlay/ — files copied onto the rootfs: the launcher & drdro.service, growfs / VT-watch / log-tty3 services, the 99-com.rules udev rule (creates /dev/serial0), Wi-Fi modprobe / powersave tweaks.
  • boot/config.txt, boot/cmdline.txt — firmware & kernel settings.
  • plymouth/theme/ — the boot splash.

Rolling release, by design. Each build pulls current Arch packages plus the latest app release (APP_REF=latest), so builds aren't reproducible commit-to-commit — CI is run on demand and images are tested before release. Pin APP_REF to a tag for a repeatable build.

CI & releases

Same tooling as the rest of the project (python-semantic-release, conventional commits): a push to dev cuts a vX.Y.Z-beta.N prerelease; a push to main cuts a stable release. Each release publishes a compressed image and checksum:

bash
zstd -d drdro-arch-vX.Y.Z-rpi-aarch64.img.zst
sha256sum -c SHA256SUMS
sudo dd if=drdro-arch-vX.Y.Z-rpi-aarch64.img of=/dev/sdX bs=4M conv=fsync status=progress

The image stamps its own version — cat /etc/drdro-release on a running board.