emulator: Starboard type: standalone core_classification: other source: "https://github.com/get-starboard/starboard" upstream: closed-source author: "force9" profiled_date: "2026-10-27" source_commit: "d3a21a9aaeabb90e59d7a48241b293dba3ee9309" core_version: "0.40.0" display_name: "PortMaster library (Starboard)" verification: existence cores: - starboard - STARBOARD - org.force9.starboard systems: [] mode: standalone notes: | Catalogue manager and execution environment for the PortMaster library on Android ARM64 handhelds. PortMaster ports are Linux ARM64 builds, so nothing is emulated: proot opens a userspace chroot into a Debian bookworm root filesystem and the games run there as native binaries against glibc, SDL2 and Mesa. ES-DE reaches it through the ports system, passing a .port file as the port_file extra to org.force9.starboard/.ui.game.GameActivity. The build read here is the signed release Starboard-v0.40.0.apk, sha256 e03173ee119223d3d3321e0684695a0af24dce84be8f440fa0fca0b10cd7806b, matching the digest GitHub records for the asset and signed by the same certificate as v0.23.0. The source is not published, so the readings below cite a jadx decompilation of classes.dex taken with --show-bad-code, where org.force9.starboard.* keeps its names and the rest is r8 output under defpackage. The APK carries its own execution stack in lib/arm64-v8a: libproot.so, libproot_loader.so and libtalloc2.so mirrored from Termux through get-starboard/starboard-prebuilts, libSDL2_starboard.so preloaded ahead of the SDL2 in the rootfs, with libSDL2_dlopen.so as the interposer for a port that opens SDL2 with dlopen and libSDL2_pysdl2.so for the pysdl2 and SDL3 shim paths, libsb_libguard.so as an LD_AUDIT module that keeps a port's bundled GL libraries from loading, libsb_xhelper.so for the Westonpack ports run on Xvfb, libasound_module_pcm_starboard.so as the ALSA output plugin, libGLESv2_wrap.so with libvirgl_vtest.so and libvirglrenderer_sb.so for the per-port GPU path, libandroid-shmem.so, and libgame_bridge.so which starts proot, binds the native library directory at /opt/sb and builds the PortMaster environment. Android installs all of them with the package. What the ports find under /opt/system/Tools/PortMaster is written at launch by libgame_bridge.so: bind_directories.sh, bind_files.sh, the gptokeyb shim, runtimes.json, control.txt and device_info.txt, with patch_ld_preload.sh, seed_retroarch_cfg.sh, audio_cfg.sh, libguard_env.sh, westonwrap.sh and launcher.sh under /tmp/sb. etc/resolv.conf and etc/hosts are seeded straight after extraction, and libgame_bridge.so then patches the extracted tree, setup stopping when it reports a failure. The ES-DE sync writes the .port files it later launches from into the ports folder of the ES-DE ROMs directory, each holding a zip_name and a launcher key, plus a source_id for a port from another catalogue, and adds the entry to gamelists/ports/gamelist.xml. Games install to Starboard/ports on the storage volume picked in the settings, marked by a .starboard_installed file, and come from the PortMaster catalogue rather than from this profile. A catalogue source added by the user installs to Starboard/ports. instead. A port that declares a runtime pulls a squashfs image into Starboard/libs on the same volume on first launch, bound into the rootfs at /opt/system/Tools/PortMaster/libs, named by the port and resolved through the utils index of PortsMaster/PortMaster-New filtered to arch aarch64. Starboard names no runtime of its own and that index is republished with the catalogue, so the set belongs to PortMaster. files: - name: starboard-rootfs.tar.gz aliases: - rootfs.tar.gz path: "rootfs.tar.gz" required: true bundled: true category: game_data storage: large_file validation: [sha256] size: 586984114 sha256: "883f1800eed1018df06e877dca578430e0f32ce954129a7733f23458d2857d54" description: "Debian bookworm ARM64 root filesystem the ports execute in" note: >- Fetched as the asset starboard-rootfs.tar.gz from releases/latest/download of get-starboard/starboard-runtime, written to the cache directory as rootfs.tar.gz, gunzipped into a rootfs directory under internal storage, then deleted. Nothing launches without it: the gate reads usr/bin/env and bin/sh in the extracted tree beside libproot.so in the native library directory. Integrity comes from a .sha256 sidecar requested next to the asset, whose first whitespace token must be 64 hex characters. The file is hashed and dropped on a mismatch, while a missing sidecar logs "No rootfs checksum sidecar available" and the download is kept on TLS trust alone. The release publishes that sidecar, and it carries the hash recorded here. The size and hash identify release starboard-rootfs-20261020.3, the one that URL served at profiling time, and the app follows whatever release is latest: the ETag of the download is kept, a later HEAD request returning another one offers an update named after the latest release tag, and accepting it wipes the rootfs and repeats the download. Its own version is read back from etc/starboard-release, which carries release, commit and built keys. The first-run setup screen starts this download by itself, with no button or file to pick, so the file arrives with the install. source_ref: "Starboard-release ch0.java:82,533-535 (base and asset URL), Starboard-release xh.java:150-156 and Starboard-release zg0.java:57-66 (download, verify, extract, delete), Starboard-release ch0.java:319-425 (sha256 sidecar and comparison), Starboard-release ch0.java:234-248 (gunzip into place), Starboard-release ch0.java:529-531 (install directory), Starboard-release ch0.java:537-539 and Starboard-release xh.java:141 (launch gate), Starboard-release ch0.java:250-271, Starboard-release yg0.java:22-25 and Starboard-release zg0.java:79-84 (ETag update check), Starboard-release ch0.java:611-635 (etc/starboard-release)"