Aus dem Gerätelauf: proot-distro trägt die Shebang-Zeile python3.13, und dieser Interpreter fehlt. proot-distro ist inzwischen ein Python-Programm — der klassische Termux-Teilupgrade-Fehler, bei dem ein Paket gegen eine Fassung gebaut wurde und eine andere installiert ist. Die Reparatur läuft in drei Stufen, von der saubersten zur unsaubersten: python nachziehen, dann Vollupgrade (die eigentliche Lösung, denn Termux verträgt keine Teilupgrades), und erst als Notnagel ein Verweis der fehlenden auf eine vorhandene Python-Fassung. Der Notnagel gilt ausdrücklich nur für Python und nur weil proot-distro reines Python ohne kompilierte Erweiterungen ist; bei anderen Interpretern wäre das grob fahrlässig. Bleibt es defekt, nennt das Skript die Handgriffe einzeln, statt nur aufzugeben. Ebenfalls aus dem Lauf: mesa-vulkan-icd-wrapper gibt es unter dem Namen nicht mehr. Die Paketnamen haben in Termux mehrfach gewechselt, deshalb werden jetzt mehrere Kandidaten der Reihe nach probiert. Greift keiner, wird das klar benannt: ohne Vulkan-Treiber bleibt Software-Rendering, S1 wird träge, ist aber weiterhin aussagekräftig. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
250 lines
11 KiB
Bash
Executable File
250 lines
11 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
# Phase 0 — Grundinstallation in Termux.
|
||
#
|
||
# Richtet Termux-X11, den GPU-Pfad und ein Debian-13-Rootfs ein, damit die Beweise
|
||
# S1 bis S4 danach laufen können. Idempotent: mehrfaches Ausführen ist unschädlich.
|
||
#
|
||
# Ausführen IN TERMUX auf dem Telefon: bash spike/00-bootstrap-termux.sh
|
||
set -uo pipefail
|
||
source "$(dirname "$0")/lib.sh"
|
||
require_termux
|
||
|
||
DISTRO=debian
|
||
BIND_ROOT="$REPO_ROOT"
|
||
|
||
log "HPOS Phase 0 — Bootstrap"
|
||
log "Protokoll: $LOG"
|
||
geraete_steckbrief
|
||
|
||
# ── Repositories ─────────────────────────────────────────────────────────────
|
||
# x11-repo bringt Termux-X11 und virglrenderer, tur-repo die Mesa-/Turnip-Pakete.
|
||
section "Paketquellen"
|
||
try pkg update -y
|
||
try pkg install -y x11-repo tur-repo
|
||
try pkg update -y
|
||
|
||
# ── Basispakete ──────────────────────────────────────────────────────────────
|
||
# Einzeln installiert und einzeln protokolliert: Paketnamen wandern in Termux
|
||
# gelegentlich, und wir wollen wissen, WELCHES Paket fehlt, statt nur dass etwas fehlt.
|
||
section "Basispakete"
|
||
BASIS=(termux-x11-nightly pulseaudio proot-distro termux-api git python openssl termux-tools)
|
||
for p in "${BASIS[@]}"; do
|
||
if try pkg install -y "$p"; then ok "$p"; else fail "$p — fehlt, betroffene Beweise siehe unten"; fi
|
||
done
|
||
|
||
# ── GPU-Pfad ─────────────────────────────────────────────────────────────────
|
||
# Adreno 6xx/7xx → Turnip greift direkt auf KGSL zu, das ist der schnellste Weg.
|
||
# Mali und alles andere → virgl/ANGLE. Wir installieren beides und entscheiden
|
||
# zur Laufzeit; das Ergebnis landet im GPU-Profil.
|
||
section "GPU-Pakete"
|
||
GPU_PKGS=(virglrenderer-android vulkan-loader-android vulkan-tools angle-android
|
||
mesa-zink virglrenderer-mesa-zink)
|
||
for p in "${GPU_PKGS[@]}"; do
|
||
if try pkg install -y "$p"; then ok "$p"; else warn "$p nicht verfügbar — kein Beinbruch"; fi
|
||
done
|
||
|
||
# Der Vulkan-Treiber ist der einzige GPU-Teil, der wirklich zählt: ohne ihn bleibt
|
||
# nur Software-Rendering. Die Paketnamen haben sich in Termux mehrfach geändert,
|
||
# deshalb werden mehrere Kandidaten probiert, bis einer greift.
|
||
section "Vulkan-Treiber (Turnip)"
|
||
ICD_KANDIDATEN=(mesa-vulkan-icd-freedreno mesa-vulkan-icd-wrapper
|
||
mesa-vulkan-icd-wrapper-android mesa-vulkan-icd-swrast)
|
||
ICD_GEFUNDEN=""
|
||
for p in "${ICD_KANDIDATEN[@]}"; do
|
||
if pkg install -y "$p" >>"$LOG" 2>&1; then
|
||
ICD_GEFUNDEN="$p"
|
||
ok "$p installiert"
|
||
break
|
||
fi
|
||
hint "$p — nicht verfügbar"
|
||
done
|
||
if [ -z "$ICD_GEFUNDEN" ]; then
|
||
warn "Kein Vulkan-Treiber installierbar."
|
||
hint "Ohne ihn läuft der Desktop im Software-Rendering — S1 wird träge,"
|
||
hint "sagt aber trotzdem etwas über die Machbarkeit aus."
|
||
hint "Verfügbare Kandidaten prüfen: pkg search mesa-vulkan"
|
||
fi
|
||
|
||
section "GPU erkennen"
|
||
PLATFORM="$(getprop ro.board.platform 2>/dev/null)"
|
||
HARDWARE="$(getprop ro.hardware 2>/dev/null)"
|
||
GPU_PROFIL="virgl" # konservative Vorgabe
|
||
if have vulkaninfo; then
|
||
vulkaninfo --summary >>"$LOG" 2>&1 || true
|
||
GPU_NAME="$(vulkaninfo --summary 2>/dev/null | grep -m1 -i 'deviceName' | cut -d= -f2- | xargs)"
|
||
else
|
||
GPU_NAME=""
|
||
fi
|
||
log " Plattform = ${PLATFORM:-?}"
|
||
log " Hardware = ${HARDWARE:-?}"
|
||
log " GPU = ${GPU_NAME:-unbekannt}"
|
||
|
||
case "${GPU_NAME}${PLATFORM}" in
|
||
*[Aa]dreno*|*qcom*|*sm[0-9]*|*msm*)
|
||
GPU_PROFIL="turnip"
|
||
ok "Adreno erkannt → Turnip-Profil (direkter KGSL-Zugriff, schnellster Weg)"
|
||
;;
|
||
*[Mm]ali*)
|
||
GPU_PROFIL="virgl"
|
||
warn "Mali erkannt → virgl/ANGLE-Profil. Spürbar langsamer als Turnip."
|
||
;;
|
||
*)
|
||
warn "GPU nicht eindeutig erkannt → virgl als Vorgabe."
|
||
hint "Bitte im Spike-Protokoll vermerken, welcher Pfad tatsächlich getragen hat."
|
||
;;
|
||
esac
|
||
|
||
# Das Profil ist eine Datei, kein Sonderfall im Code — so bleibt es später
|
||
# erweiterbar, ohne dass jemand Skripte anfassen muss.
|
||
mkdir -p "$REPO_ROOT/rootfs/profiles"
|
||
PROFIL_DATEI="$OUT_DIR/gpu-profil.env"
|
||
{
|
||
echo "# Automatisch erkannt von 00-bootstrap-termux.sh"
|
||
echo "HPOS_GPU_PROFIL=$GPU_PROFIL"
|
||
echo "HPOS_GPU_NAME=\"${GPU_NAME:-unbekannt}\""
|
||
echo "HPOS_PLATFORM=\"${PLATFORM:-unbekannt}\""
|
||
} >"$PROFIL_DATEI"
|
||
ok "GPU-Profil geschrieben: $PROFIL_DATEI ($GPU_PROFIL)"
|
||
|
||
# ── Termux-Eigenschaften ─────────────────────────────────────────────────────
|
||
# allow-external-apps ist die Voraussetzung dafür, dass die Bridge-APK später
|
||
# Kommandos in Termux anstoßen darf. Hier gesetzt, damit Phase 2 es vorfindet.
|
||
section "Termux-Eigenschaften"
|
||
TP="$HOME/.termux/termux.properties"
|
||
mkdir -p "$(dirname "$TP")"
|
||
touch "$TP"
|
||
if grep -q '^allow-external-apps' "$TP" 2>/dev/null; then
|
||
ok "allow-external-apps bereits gesetzt"
|
||
else
|
||
echo 'allow-external-apps = true' >>"$TP"
|
||
ok "allow-external-apps = true gesetzt"
|
||
hint "Wird erst nach 'termux-reload-settings' oder Neustart von Termux wirksam."
|
||
fi
|
||
try termux-reload-settings
|
||
|
||
section "Speicherzugriff"
|
||
if [ -d "$HOME/storage" ]; then
|
||
ok "Speicherzugriff bereits eingerichtet"
|
||
else
|
||
warn "termux-setup-storage wird gleich einen Berechtigungsdialog zeigen — bitte erlauben."
|
||
try termux-setup-storage
|
||
sleep 2
|
||
[ -d "$HOME/storage" ] && ok "Speicherzugriff eingerichtet" || fail "Speicherzugriff fehlt — Backup nach /sdcard geht später nicht"
|
||
fi
|
||
|
||
# ── Wachhalten ───────────────────────────────────────────────────────────────
|
||
# Ohne Wake-Lock schläft der Stack weg, sobald der Bildschirm aus geht.
|
||
# Die herstellerseitigen Maßnahmen kommen zusätzlich, siehe provision/.
|
||
section "Wake-Lock"
|
||
try termux-wake-lock && ok "Wake-Lock aktiv" || warn "Wake-Lock nicht gesetzt"
|
||
|
||
# ── Debian-Rootfs ────────────────────────────────────────────────────────────
|
||
section "Debian-Rootfs"
|
||
# Erst prüfen, ob proot-distro überhaupt LÄUFT. Ein installiertes Paket, dessen
|
||
# Shebang-Interpreter fehlt, meldet sich mit "cannot execute: required file not
|
||
# found" — eine Meldung, die aussieht als fehle das Programm, obwohl es da ist.
|
||
if ! proot-distro list >/dev/null 2>&1; then
|
||
fail "proot-distro ist installiert, lässt sich aber nicht ausführen"
|
||
PD="$(command -v proot-distro)"
|
||
SHEBANG="$(head -1 "$PD" 2>/dev/null)"
|
||
INTERPRETER="$(printf '%s' "$SHEBANG" | sed 's|^#!||; s| .*||')"
|
||
log " Datei: $PD"
|
||
log " Shebang: $SHEBANG"
|
||
log " Interpreter: ${INTERPRETER:-(keiner)}"
|
||
|
||
if [ -n "$INTERPRETER" ] && [ ! -x "$INTERPRETER" ]; then
|
||
fail "Der Interpreter fehlt — nicht proot-distro selbst."
|
||
log ""
|
||
log " Das ist der klassische Termux-Teilupgrade-Fehler: das Paket wurde gegen"
|
||
log " eine Fassung gebaut, installiert ist eine andere. Termux verträgt keine"
|
||
log " Teilupgrades — hier hilft nur, alles auf denselben Stand zu bringen."
|
||
|
||
# Schritt 1: fehlendes Paket nachziehen. Bei python3.x heißt es schlicht python.
|
||
case "$(basename "$INTERPRETER")" in
|
||
python3*|python) try pkg install -y python ;;
|
||
bash) try pkg install -y bash ;;
|
||
*) try pkg install -y "$(basename "$INTERPRETER")" ;;
|
||
esac
|
||
|
||
# Schritt 2: Vollupgrade. Das ist die eigentliche Reparatur.
|
||
if [ ! -x "$INTERPRETER" ]; then
|
||
log ""
|
||
warn "Reicht nicht — jetzt das Vollupgrade. Das dauert und lädt einiges."
|
||
try pkg update -y
|
||
try pkg upgrade -y
|
||
try pkg install -y proot proot-distro
|
||
fi
|
||
|
||
# Schritt 3: Notnagel. Nur für Python, und nur weil proot-distro reines
|
||
# Python ohne kompilierte Erweiterungen ist — sonst wäre eine Version
|
||
# überzustülpen grob fahrlässig.
|
||
if [ ! -x "$INTERPRETER" ]; then
|
||
case "$(basename "$INTERPRETER")" in
|
||
python3.*)
|
||
VORHANDEN="$(ls "$PREFIX/bin"/python3.* 2>/dev/null | grep -v config | head -1)"
|
||
if [ -n "$VORHANDEN" ]; then
|
||
log ""
|
||
warn "Notnagel: verweise $(basename "$INTERPRETER") auf $(basename "$VORHANDEN")"
|
||
hint "Vertretbar, weil proot-distro reines Python ist."
|
||
hint "Sauber wird es erst mit einem vollständigen 'pkg upgrade'."
|
||
ln -sf "$VORHANDEN" "$INTERPRETER" && ok "Verweis angelegt"
|
||
fi
|
||
;;
|
||
esac
|
||
fi
|
||
else
|
||
try pkg install -y bash coreutils proot proot-distro
|
||
fi
|
||
|
||
if ! proot-distro list >/dev/null 2>&1; then
|
||
fail "Bleibt defekt — ohne proot-distro geht es nicht weiter."
|
||
log ""
|
||
log " Von Hand versuchen, in dieser Reihenfolge:"
|
||
log " pkg update && pkg upgrade -y # Vollupgrade, keine Teilschritte"
|
||
log " pkg install -y python proot proot-distro"
|
||
log " termux-change-repo # falls der Spiegel unstimmig ist"
|
||
exit 1
|
||
fi
|
||
ok "proot-distro läuft wieder"
|
||
fi
|
||
|
||
if proot-distro list --installed 2>/dev/null | grep -q "^$DISTRO\b" \
|
||
|| [ -d "$PREFIX/var/lib/proot-distro/installed-rootfs/$DISTRO" ]; then
|
||
ok "$DISTRO bereits installiert"
|
||
else
|
||
log " Installiere $DISTRO — das dauert einige Minuten."
|
||
need proot-distro install "$DISTRO"
|
||
ok "$DISTRO installiert"
|
||
fi
|
||
|
||
section "Debian-Grundausstattung"
|
||
# Der Bind macht das Repo im Rootfs unter /hpos sichtbar, damit die inneren
|
||
# Skripte dieselben Dateien benutzen und Ergebnisse am selben Ort landen.
|
||
proot-distro login "$DISTRO" --bind "$BIND_ROOT:/hpos" -- bash -lc '
|
||
set -uo pipefail
|
||
export DEBIAN_FRONTEND=noninteractive
|
||
apt-get update -qq
|
||
apt-get install -y --no-install-recommends \
|
||
ca-certificates locales dbus-x11 sudo nano less procps \
|
||
mesa-utils vulkan-tools pulseaudio-utils
|
||
# Deutsche und englische Locale, sonst meckert die halbe Desktop-Software.
|
||
sed -i "s/^# *\(de_DE.UTF-8\|en_US.UTF-8\)/\1/" /etc/locale.gen
|
||
locale-gen >/dev/null 2>&1
|
||
echo "--- Debian-Version ---"; cat /etc/debian_version
|
||
' 2>&1 | tee -a "$LOG"
|
||
|
||
# ── Abschluss ────────────────────────────────────────────────────────────────
|
||
section "Bereit"
|
||
log "GPU-Profil : $GPU_PROFIL"
|
||
log "Rootfs : $DISTRO"
|
||
log "Repo im Rootfs sichtbar unter /hpos"
|
||
log ""
|
||
log "Nächste Schritte, in dieser Reihenfolge:"
|
||
log " bash spike/01-s1-plasma-mobile.sh # der wackligste Beweis, deshalb zuerst"
|
||
log " bash spike/02-s2-mikrofon.sh"
|
||
log " bash spike/03-s3-pipewire-kamera.sh"
|
||
log " bash spike/04-s4-intent-handoff.sh"
|
||
log ""
|
||
log "Vor dem Übernacht-Test bitte provision/provision.sh vom PC laufen lassen"
|
||
log "und die herstellerseitigen Handgriffe aus docs/machbarkeit.md erledigen."
|