Linux-Telefon-Portierung
Bei einem Telefon, das auf Mainline gebracht wird, kostet ein Debug-Durchlauf einen Build plus ein Flashen plus einen Bootvorgang (5–10 Minuten), und blinde Korrekturen werden weitaus häufiger widerlegt, als sie landen. Halten Sie sich strikt an diese Reihenfolge.
0. Richten Sie den Port ein
Führen Sie dies einmal durch, vor dem ersten Flashen. Zwei Dinge machen dies zu Phase 0 und nicht zu einer Formalität: Das Originalsystem ist die vertrauenswürdigste Informationsquelle, die Sie jemals für dieses Board haben werden, und Teile davon sind nicht mehr lesbar, sobald Sie beginnen, Partitionen zu überschreiben.
Legen Sie zuerst das Ziel fest, denn jede spätere Antwort hängt davon ab:
- Genaue Geräteidentität — Marketingname, Codename, SoC sowie regionale Variante oder Speichervariante. Geschwistervarianten desselben Marketingnamens unterscheiden sich routinemäßig in Panel, Touch-Controller oder Modem, und eine Korrektur, die für die falsche Variante recherchiert wurde, sieht plausibel aus und schlägt fehl.
- Ziel-Distro und Init — postmarketOS, Mobian, NixOS, einfaches Debian, etwas anderes. Dies bestimmt die Paketierung, das Image-Layout und welche der Quellen aus Phase 2 am nächsten ist.
- Boot-Topologie — A/B oder nicht A/B, Slot-Layout und Bootloader-Sperrstatus. Nur entsperrte Bootloader. Wenn der Bootloader gesperrt ist, brechen Sie ab: Dieser Skill entsperrt keine Bootloader und enthält keine Schritte zum Entsperren — weisen Sie den Benutzer auf die Anweisungen des jeweiligen OEMs hin und fahren Sie fort, sobald das Gerät entsperrt ist.
- Recovery — ob eine benutzerdefinierte Recovery installiert ist. Keine Voraussetzung: eine Annehmlichkeit zum Sichern und Wiederherstellen.
Erstellen Sie dann ein vollständiges Backup jeder Partition außer Benutzerdaten:
- Überspringen Sie Benutzerdaten: Sie machen den Großteil des Speicherplatzes aus, es sind die Daten des Benutzers, und es ist die einzige Partition, die Sie sich leisten können zu verlieren.
- Sichern Sie die geräteeigenen Partitionen und veröffentlichen Sie sie niemals. Modem-NV/EFS, Persist und ihre Kalibrierungs-Geschwister tragen die IMEI, die Funkkalibrierung und die Sensortrimmung für dieses einzelne Gerät. Sie sind aus keinem Image im Internet reproduzierbar, und ein Port, der sie beschädigt, hinterlässt ein Telefon, das sich nicht in einem Netzwerk registrieren kann. Behandeln Sie sie als sowohl kritisch als auch privat.
- Hashen Sie jedes Image und zeichnen Sie die Hashes zusammen mit der Partitionstabelle auf. Später müssen Sie die Frage beantworten können: "Ist das, was auf dem Gerät ist, noch das, was ich gesichert habe?", und nur ein Hash beantwortet sie.
- Verifizieren Sie, dass das Backup vor dem ersten riskanten Flash tatsächlich wiederherstellbar ist, nicht erst danach.
Welchen Wert das Backup als Forschungsgrundlage hat (über die Wiederherstellung hinaus):
- Der originale DTB — die grundlegende Wahrheit für den Device Tree dieses Boards und der Entscheider, wenn das dtsi des verwandten SoC anderer Meinung ist.
- Firmware-Blobs und ihre Lade-Reihenfolge — was der Vendor-Stack tatsächlich ausliefert und wo er erwartet, es zu finden.
- Die Vendor-Kernel-Cmdline und das Boot-Image-Layout — Offsets, Header-Version und die Argumente, die dem Vendor-Kernel übergeben wurden.
- Die exakte Kernel-Versionszeichenfolge —
uname -aoder/proc/versionaus dem originalen ROM, solange es noch gelesen werden kann (später auch aus dem gesicherten Boot-Image entpackbar). Es ist der Fingerabdruck, der die richtige GPL-veröffentlichte OEM-Quellversion in Phase 2 auswählt; Anbieter liefern mehrere Builds aus, und sie unterscheiden sich. - Vendor-Konfigurationen — Sensor-, Modem- und HAL-Konfigurationen, die die Schnittstellen beschreiben, die der Mainline-Treiber erfüllen muss.
Legen Sie schließlich die Arbeitskonventionen fest, die der Rest der Sitzung voraussetzt: ein hostseitiges Verzeichnis, das ein Unterverzeichnis pro Boot für Logs und Pstore ansammelt, und ein Vermerk darüber, welcher Recovery-Pfad bekanntermaßen funktioniert. Wenn bereits ein Backup von einem früheren Versuch existiert, bestätigen Sie, dass es diese Partitionen abdeckt und dass seine Hashes noch gültig sind, anstatt es einfach anzunehmen.
1. Sammeln Sie zuerst Beweise vom laufenden Gerät
Erfassen Sie das vollständige dmesg des fehlgeschlagenen Laufs, bevor Sie etwas ändern. Aktivieren Sie die relevanten Debug-Schalter vor der Reproduktion (z. B. echo 0xffffffff > /sys/module/<treiber>/parameters/debug_mask), da eine zweite Reproduktion einen weiteren Bootvorgang kostet.
Beweisquellen, in ungefährer Reihenfolge der Zuverlässigkeit:
- Live-Shell über Netzwerk oder USB. Günstigster Kanal; verwenden Sie ihn für alles, was das Gerät überlebt.
- pstore. Sobald systemd läuft, sammeln Sie aus
/var/lib/systemd/pstore/ein, nicht aus/sys/fs/pstore/—systemd-pstore.serviceverschiebt jeden Eintrag früh im Bootvorgang, sodass ein leeres/sys/fs/pstore/kein Beweis dafür ist, dass kein Absturz aufgezeichnet wurde. Der Konsolenbereich ist typischerweise ein einzelner Slot: Kopieren Sie ihn auf den Host, bevor Sie etwas anderes tun, sonst überschreibt der nächste Absturz ihn auch im Archiv. - ramoops. Behandeln Sie es als verlustbehaftet. Die Ladungserhaltung des DRAMs nimmt über das stromlose Intervall hinweg ab — gemessen auf einem Gerät mit etwa 6,5 % der Bits genug, um ECC an den Zonen-Headern fehlschlagen zu lassen und einen Eintrag vollständig zu verlieren. Durchsuchen Sie Einträge unscharf. Was die Region verfallen lässt, ist die unbestromte Zeit, nicht die Zeit, die Sie mit Spammen verbringen, bevor Sie den Strom abschalten. Lassen Sie ein eingefrorenes Gerät daher so lange loggen, wie der Konsolenbereich es fassen kann, und schalten Sie es dann stromlos und wieder ein. Überprüfen Sie die Zonengröße, bevor Sie davon ausgehen, dass Sie sich beeilen müssen: Ein 4 MiB großer Konsolenbereich absorbiert stundenlangen Watchdog-Spam, bevor er überläuft.
- Kernel-Level-USB-ACM-Konsole (
CONFIG_U_SERIAL_CONSOLE=yplusconsole=ttyGS0in der Cmdline). Der einzige Kanal, der einen Systemstillstand überlebt, und seinen einmaligen Flash-Aufwand zu Beginn eines Ports wert. Eine Userspace-ACM-Getty überlebt ihn nicht — sie benötigt eine planbare CPU und liefert null Bytes, während sie über USB einwandfrei aufzählt. Beide Hälften sind erforderlich: Das Konfigurationssymbol allein lässt die Einrichtung inaktiv.
Fünf Regeln, die wiederholt Schlussfolgerungen in Messungen verwandeln:
- Bestätigen Sie, was tatsächlich geflasht ist, indem Sie die Partition zurücklesen, niemals aus Notizen und niemals aus einem Build-Log. Lesen Sie mit
iflag=direct, damit der Lesevorgang selbst das, was Sie debuggen, nicht stört. Hüten Sie sich vor reinen Größenvergleichen — Boot-Images werden auf eine feste Größe aufgefüllt, sodass eine gleiche Länge bei zwei verschiedenen Images nichts beweist. Hashen Sie die Nutzdaten. - Das Lesen einer Debug-Schnittstelle kann das Symptom erzeugen. DRM/GPU-Crash-State-Nodes sind der klassische Fall: Ein Abtasten, während die GPU aktiv einreicht, synthetisiert Fehler- und Wiederherstellungszeilen, die nie aufgetreten sind (gemessen: fünf Lesevorgänge, fünf Fehler-/Wiederherstellungspaare, gegenüber null bei Nichtbeobachtung). Bevor Sie einer Log-Zeile vertrauen, überprüfen Sie, ob Ihre eigene Beobachtung sie erzeugt hat.
- Erfassen Sie die Rohantwort einer Ablehnung, bevor Sie die gemappte errno interpretieren. Die gemappte Fehlermeldung eines Firmware-Aufrufs war mehrdeutig —
EINVALkonnte auf eine falsche Kodierung oder eine verweigerte Richtlinie hindeuten — bis Dynamic Debug im Aufruf-Wrapper die rohen Antwortwörter offenlegte: ein wohlgeformter Aufruf, der eine explizite Ablehnung trug. Das ist eine Richtlinie, keine Kodierung — die gegenteilige Entscheidung mit dem gegenteiligen nächsten Schritt. Klassifizieren Sie jede Firmware-Ablehnung als falsche Kodierung, durch Richtlinie verweigert oder nicht gefunden, bevor Sie darauf reagieren. Die Spiegelregel: Ein sauberes, wohlgeformtes Negativ ist ein positiver Beweis — ein "Nicht gefunden" von einer korrekt geformten Suche validiert die Kodierung und eliminiert einen Zweig des Plans, ohne jemals den Lader zu berühren. - Eine Messung, die mit einer unkontrollierten Bedingung um die Wette läuft, liefert eine plausible, leere Zahl. Ein Benchmark ergab in zwei Sekunden 55: Der Compositor hielt DRM Master, jede Szene schlug fehl, und die Zahl sah real aus, bis die Bedingung überprüft wurde. Der gültige Vergleich — 132 → 485 — benötigte den gestoppten Compositor für beide Läufe, verglich nur innerhalb dieser Generation. Bevor Sie einem Benchmark vertrauen, nennen Sie die Bedingung, die ihn ungültig machen könnte, und verifizieren Sie, dass sie für jeden Lauf galt.
- Notieren Sie die Regeln, die Sie zurückziehen. Bring-up sammelt schnell Folklore an, und eine Regel, die für eine Hardware-Revision oder eine Puffergröße richtig war, wird nach einer Änderung aktiv irreführend. Bewahren Sie die umgestoßene Version zusammen mit der aktuellen und der Änderung auf, damit die nächste Sitzung weiß, welcher Rat belastbar getestet wurde.
Hostseitige Fallstricke, die es wert sind, vorbeugend behandelt zu werden:
timeout N ssh <gerät> '<befehl>'tötet nur den lokalen Client; der entfernte Prozess läuft weiter. Führen Sie einen expliziten Kill durch.pgrep -fundpkill -flaufen über denselben SSH-Pfad und matchen sich selbst mit ihrer eigenen entfernten Shell. Filtern Sie den Matcher heraus oder matchen Sie nach PID.findbenötigt-L, wenn der Startpfad ein Symlink ist, sonst gibt es still und leise nichts zurück.- Jeder Wrapper oder Hook, der die Befehlsausgabe umschreibt — Token-Filter, Pager, Formatierer — wird Beweise verfälschen, manchmal durch Umkehrung eines Tests, anstatt ihn offensichtlich zu brechen. Verwenden Sie den rohen Befehl für alles, was Sie als Ergebnis festhalten werden.
2. Recherchieren Sie vor der Implementierung – alle diese Quellen
Recherche geht der Implementierung immer voraus. Was sie benötigt, hängt davon ab, was Sie tun:
- Untersuchung eines Fehlers — die Phase-1-Beweise. Erfassen Sie ihn zuerst; die Recherche eines Symptoms, das Sie nicht tatsächlich gelesen haben, ist Raten mit Zitaten.
- Hinzufügen einer Fähigkeit — ein Treiber, ein Peripheriegerät, ein Subsystem, das noch nie aufgetaucht ist — die Phase-0-Artefakte sind die Gerätedaten. Der originale DTB, die Vendor-Konfigurationen und das Firmware-Layout beschreiben, wie dieses Board erwartet, dass das Ding angesteuert wird, und sie sind hier genauso maßgeblich wie ein Absturzlog dort.
In beiden Fällen bevor Sie etwas schreiben:
- Analysieren Sie das Subsystem — identifizieren Sie, welcher Treiber, welches Binding oder welche Firmware-Schnittstelle den Fehler besitzt oder die neue Fähigkeit besitzen würde. Die Ihnen zur Verfügung stehenden Skills sind in Ihrem Sitzungskontext aufgelistet: Durchsuchen Sie diese Liste jetzt, und wenn sie einen Skill zur Kernel-Entwicklung oder Absturzanalyse enthält, lesen Sie ihn, bevor Sie fortfahren — seine Register- und Binding-Details sind genau das, was dieser Schritt benötigt. Denken Sie nur dann direkt darüber nach, wenn keiner aufgelistet ist.
- Schlagen Sie die beteiligten Userspace-Bibliotheken und Tools nach — aktuelle Dokumente, keine erinnerten APIs. Wenn ein Skill zum Abrufen von Dokumentationen in derselben Sitzungsliste vorhanden ist, führen Sie ihn aus, anstatt Signaturen aus dem Gedächtnis abzurufen.
- Web-Recherche über alle sechs Quellenfamilien hinweg (parallele Sub-Agents arbeiten hier gut; wenn ein Skill zur Web-Recherche in dieser Liste ist, bevorzugen Sie ihn wegen des Cachings, da Sitzungen dieselben Seiten mehrfach lesen):
- Mainline — lore.kernel.org, der Treiberquellcode, DT-Bindings und das dtsi des nächsten verwandten SoC (gleiche Familie oder gleiche RPM-Generation). Bevor Sie einen "Portieren Sie den Downstream-Treiber"-Feldzug planen, durchsuchen Sie, was Mainline bereits für die Schnittstelle hat: seine exportierte API, ob sie den Userspace erreicht oder nur Kernel-intern ist, und seine Tore — Maschinen-Allowlists, "vom Bootloader vorab geladene" Semantik, built-in statt Modul (gemessen: Eine solche Durchsuchung reduzierte einen 9,4k-Zeilen-Downstream-Port auf ein ~300-Zeilen-Probe-Modul, weil Mainline die Schnittstelle bereits kernel-intern hinter einer Allowlist trug — der Plan wurde, die vorhandene API zu treiben, nicht sie zu portieren).
- Downstream-Vendor-Kernel – die GPL-veröffentlichte OEM-Quelle. GPLv2 verpflichtet Android-OEMs, die Kernel-Quellen zu veröffentlichen, die sie ausgeliefert haben, sodass eine exakte Version für dieses Gerät normalerweise existiert: das Open-Source-Portal des OEM (Samsung, Sony, Xiaomi, Fairphone, OnePlus/OPPO und Motorola betreiben alle eines), ihre GitHub/GitLab-Mirrors und Community-Archive wie XDA, wenn ein Portal-Link tot ist. Wählen Sie das Tarball aus, dessen Versionszeichenfolge mit
/proc/versionaus Phase 0 übereinstimmt — Anbieter veröffentlichen mehrere, und sie unterscheiden sich. Die Compliance-Qualität variiert, behandeln Sie den Tree daher als Orakel zum Abbauen — das Board-dts und die Defconfig für dieses genaue Gerät und die Out-of-Tree-Vendor-Treiber (Touch, Panel, Ladegerät, Modem-Kleber) mit ihren Register-Sequenzen und Firmware-Handshakes — anstatt anzunehmen, dass er baut. Wenn keine genaue Version auftaucht, trägt eine Version eines verwandten Geräts normalerweise dennoch das SoC-dtsi. Noch besser: das originale DTB, das vom Gerät selbst gezogen wurde (ddden unberührten Boot-Slot, scanne nachd00dfeed,dtc -I dtb -O dts). Das ist die grundlegende Wahrheit für dieses Board und hat mehr als einmal falsche Schätzungen verwandter SoCs korrigiert — einschließlich einer SMMU-Stream-ID, die der verwandte SoC falsch hatte und das originale DTB richtig. - postmarketOS — pmaports-Gerätepakete und APKBUILDs, Merge Requests, Wiki-Geräteseiten und der SoC-Mainline-Tree.
- Halium / UBports —
halium/android_device_*-Trees,hybris-boot-Konfigurationen und UBports-Geräteports. Halium führt den Android-Vendor-Stack anstelle von Mainline aus, was es zur besten Quelle dafür macht, wie die Vendor-Firmware angesteuert werden will: Firmware-Blob-Pfade und Lade-Reihenfolge, die Property- und Socket-Schnittstellen, die Daemons erwarten, Sensor- und Modem-HAL-Konfigurationen. Wenn ein Mainline-Treiber sondiert, aber der Firmware-Handshake fehlschlägt — oder wenn Sie wissen müssen, welchen Handshake ein noch nicht unterstütztes Peripheriegerät erwartet —, ist dies normalerweise der Ort, an dem das fehlende Stück niedergeschrieben ist. - Mobian — die Debian-Geräte-Repos.
- NixOS — mobile-nixos-Muster und nixpkgs-Paketierung.
Dünne Ergebnisse sind der Normalfall, kein Hindernis. Das meiste, was ein Port benötigt, wurde noch nie für dieses Board und oft nicht einmal für diesen SoC gemacht. Sechs Quellen, die nichts melden, bedeuten, dass niemand die Arbeit veröffentlicht hat — es bedeutet nie, dass die Arbeit aufhören oder zurückgegeben werden sollte. Wenn kein Präzedenzfall existiert, liegen die Antworten immer noch in den primären Artefakten: dem Out-of-Tree-Vendor-Treiber, der das Peripheriegerät bereits ansteuert (Register-Sequenzen, Firmware-Handshake, GPIO- und Regler-Verdrahtung), dem eigenen Knoten des originalen DTB dafür, der Vendor-HAL-Konfiguration, die benennt, was der Userspace erwartet, und dem nächsten Mainline-Treiber für dieselbe Geräteklasse als strukturelle Vorlage. Lesen Sie diese, leiten Sie das Design ab und schreiben Sie das fehlende Stück — einen DT-Knoten, einen Quirk, einen kleinen Treiber. Das Verfassen dieses Stücks ist der normale Endzustand eines Bring-ups, keine Ausnahme, die gerechtfertigt werden muss; das Phase-0-Backup und die Regel "eine Variable pro Flash" existieren genau dafür, dass eine falsche Ableitung einen Boot und eine Zeile im Hauptbuch kostet, genau wie jede andere Widerlegung.
Eine leere Suche und ein leerer Scan sind unterschiedliche Ergebnisse. Eine leere Suche in den Quellen bedeutet, dass niemand die Arbeit veröffentlicht hat. Ein leerer Scan — eine Extraktion, die nichts zurückgibt — ist ungültig, bis dieselbe Methode gegen eine bekannte Positivkontrolle ausgeführt und ihre Abdeckung verifiziert wurde: Dateizahlen, Segmentlisten, was der Glob tatsächlich gematcht hat. Gemessene Beinahe-Fehler: Ein Glob matchte 9 von 27 Firmware-Segmenten und hätte fast ein falsches "die Firmware lässt es aus" aufgezeichnet; ein Bibliotheksscan wurde erst vertrauenswürdig, nachdem er eine bekannte Chip-ID als Positivkontrolle fand.
Downstream-Identifikatoren sind downstreams P...
[... abgeschnitten für die Übersetzung]