So aktualisieren Sie Ihren Android-Kernel auf den neuesten Linux-Stand

Wir haben Anleitungen zu Android-Kerneln behandelt, wie zum Beispiel "Erstellen eines benutzerdefinierten Kernels" und "Beste benutzerdefinierte Kernel für Android". Heute zeigen wir Ihnen jedoch, wie Sie Ihren Kernel mit dem neuesten Linux-Stable upstreamen können.

Bitte beachten Sie, dass dies fortgeschrittenes Material ist. Wenn Sie noch nie zuvor einen Kernel kompiliert haben, befolgen Sie die oben verlinkten Anleitungen zum Erstellen eines benutzerdefinierten Kernels. Diese Anleitung beinhaltet das Auswählen und Zusammenführen von Commits der neuesten Linux-Versionen. stabiler Kernel mit Ihrem Android-Kernel, bevor Sie ihn kompilieren.

Das Upstreaming Ihres Android-Kernels auf den neuesten Linux-Stable hat eine Menge positiver Vorteile, zum Beispiel, dass Sie über die neuesten Sicherheits-Commits und Bugfixes auf dem Laufenden sind - einige Vor- und Nachteile werden später in diesem Handbuch erläutert.

Was ist ein Linux-stabiler Kernel?

Linux-stable ist, wie der Name schon sagt, der stabile Zweig des Linux-Kernels. Der andere Arm ist als „Hauptzweig“ bekannt, bei dem es sich um den Hauptzweig handelt . Die gesamte Linux-Kernel-Entwicklung findet in der Hauptlinie statt und läuft im Allgemeinen wie folgt ab:

  1. Linus Torvalds wird seinen Betreuern zwei Wochen lang ein paar Pflaster abnehmen.
  2. Nach diesen zwei Wochen veröffentlicht er einen rc1-Kernel (zB 4.14-rc1).
  3. Für jede Woche in den nächsten 6-8 Wochen wird er einen weiteren RC-Kernel (z. B. 4.14-rc2, 4.14-rc3 usw.) veröffentlichen, der NUR Fehler- und Regressionskorrekturen enthält.
  4. Sobald es als stabil eingestuft ist, wird es als Tarball zum Download in org (zB 4.14) freigegeben.

Was sind LTS-Kernel?

Jedes Jahr wird Greg einen Kernel auswählen und entweder zwei Jahre (LTS) oder sechs Jahre (Extended LTS) warten. Diese Produkte müssen stabil sein (z. B. Android-Telefone oder andere IOT-Geräte). Der Vorgang ist genau der gleiche wie oben, es passiert nur für eine längere Zeit. Derzeit gibt es sechs LTS-Kernel (die immer auf der kernel.org-Release-Seite eingesehen werden können):

  • 4.14 (LTS), gepflegt von Greg Kroah-Hartman
  • 4.9 (LTS), gepflegt von Greg Kroah-Hartman
  • 4.4 (eLTS), gepflegt von Greg Kroah-Hartman
  • 4.1 (LTS), gepflegt von Sasha Levin
  • 3.16 (LTS), gepflegt von Ben Hutchings
  • 3.2 (LTS), gepflegt von Ben Hutchings

Was sind die Vorteile eines Upstreams meines Android-Kernels auf Linux Stable?

Wenn wichtige Schwachstellen aufgedeckt / behoben werden, sind die stabilen Kernel die ersten, die diese bekommen. So ist Ihr Android-Kernel viel sicherer gegen Angriffe, Sicherheitslücken und generell nur gegen Fehler.

Der Linux-Stable enthält Korrekturen für viele Treiber, die mein Android-Gerät nicht verwendet. Ist das nicht meistens unnötig?

Ja und Nein, je nachdem, wie Sie "meistens" definieren. Der Linux-Kernel enthält möglicherweise eine Menge Code, der im Android-System nicht verwendet wird, der jedoch nicht garantiert, dass beim Zusammenführen neuer Versionen keine Konflikte mit diesen Dateien auftreten! Verstehen Sie, dass praktisch niemand jeden einzelnen Teil des Kernels erstellt, nicht einmal die gängigsten Linux-Distributionen wie Ubuntu oder Mint. Dies bedeutet nicht, dass Sie diese Korrekturen nicht vornehmen sollten, da für Treiber, die Sie ausführen, Korrekturen vorhanden sind. Nehmen wir zum Beispiel arm / arm64 und ext4, die die am häufigsten verwendete Android-Architektur bzw. das Dateisystem sind. In 4.4, von 4.4.78 (Version des neuesten Oreo CAF-Tags) bis 4.4.121 (letztes Upstream-Tag), sind dies die folgenden Nummern für die Commits dieser Systeme:

 ~ / kernels / linux-stable (master) $ git log --format =% h v4.4.78..v4.4.121 | wc -l2285 ~ / kernels / linux-stable (master) $ git log --format =% h v4.4.78..v4.4.121 arch / arm | wc -l58 ~ / kernels / linux-stable (master) $ git log --format =% h v4.4.78..v4.4.121 arch / arm64 | wc -l22 ~ / kernels / linux-stable (master) $ git log --format =% h v4.4.78..v4.4.121 fs / ext4 | wc -l18 

Der zeitaufwändigste Teil ist die erste Einführung; Sobald Sie auf dem neuesten Stand sind, dauert es keine Zeit mehr, eine neue Version zu erstellen, die in der Regel nicht mehr als 100 Commits enthält. Die Vorteile, die dies mit sich bringt (mehr Stabilität und mehr Sicherheit für Ihre Benutzer), sollten diesen Prozess jedoch erforderlich machen.

So führen Sie einen stabilen Linux-Kernel in einen Android-Kernel ein

Zuerst müssen Sie herausfinden, welche Kernelversion auf Ihrem Android-Gerät ausgeführt wird.

So trivial dies auch erscheint, es ist wichtig zu wissen, wo Sie anfangen müssen. Führen Sie den folgenden Befehl in Ihrem Kernelbaum aus:

 Kernelversion machen 

Die Version, auf der Sie sich befinden, wird zurückgegeben. Die ersten beiden Zahlen werden verwendet, um den benötigten Zweig herauszufinden (z. B. linux-4.4.y für einen beliebigen 4.4-Kernel) und die letzte Zahl wird verwendet, um zu bestimmen, welche Version Sie mit dem Zusammenführen beginnen müssen (z. B. wenn Sie auf 4.4 sind) .21, werden Sie als nächstes 4.4.22 zusammenführen).

Besorgen Sie sich die neueste Kernelquelle von kernel.org

kernel.org enthält die neueste Kernelquelle im linuxstabilen Repository. Am Ende dieser Seite befinden sich drei Abruflinks. Nach meiner Erfahrung ist der Spiegel von Google in der Regel der schnellste, aber Ihre Ergebnisse können variieren. Führen Sie die folgenden Befehle aus:

 git remote add linux-stable //kernel.googlesource.com/pub/scm/linux/kernel/git/stable/linux-stable.gitgit holt linux-stable 

Entscheiden Sie, ob Sie den gesamten Kernel zusammenführen oder die Commits auswählen möchten

Als nächstes müssen Sie auswählen, ob Sie die Commits oder Cherry-Pick zusammenführen möchten. Hier ist das Für und Wider von jedem und wann Sie sie tun möchten.

ANMERKUNG: Wenn Ihre Kernelquelle in Form eines Tarballs vorliegt, müssen Sie höchstwahrscheinlich eine Auswahl treffen. Andernfalls kommt es zu Tausenden von Dateikonflikten, da git den Verlauf nur auf der Grundlage des Upstreams auffüllt und nicht auf der Grundlage des OEM oder des CAF geändert. Fahren Sie einfach mit Schritt 4 fort.

Rosinenpickerei:

Vorteile:

  • Einfachere Lösung von Konflikten, da Sie genau wissen, welcher Konflikt ein Problem verursacht.
  • Das Zurücksetzen ist einfacher, da jedes Commit für sich allein steht.
  • Leichter zu halbieren, wenn Probleme auftreten

Nachteile:

  • Es dauert länger, da jedes Commit einzeln ausgewählt werden muss.
  • Etwas schwieriger zu sagen, ob das Commit auf den ersten Blick vom Upstream stammt

Verschmelzen

Vorteile :

  • Es ist schneller, da Sie nicht darauf warten müssen, dass alle sauberen Patches zusammengeführt werden.
  • Es ist einfacher zu erkennen, wann ein Commit vom Upstream stammt, da Sie nicht der Committer, sondern der Upstream-Betreuer sind.

Nachteile:

  • Das Lösen von Konflikten kann etwas schwieriger sein, da Sie mithilfe von git log / git blame nachsehen müssen, welches Commit den Konflikt verursacht. Dies wird Ihnen nicht direkt mitgeteilt.
  • Das erneute Abspeichern ist schwierig, da Sie eine Zusammenführung nicht erneut abspeichern können. Es wird angeboten, alle Commits einzeln auszuwählen. Sie sollten jedoch nicht häufig rebasieren, sondern nach Möglichkeit git revert und git merge verwenden.

Ich würde empfehlen, zuerst einen Cherry-Pick durchzuführen, um etwaige Problemkonflikte herauszufinden, eine Zusammenführung durchzuführen und anschließend die festgeschriebenen Probleme zurückzusetzen, um die Aktualisierung zu vereinfachen (da das Zusammenführen nach dem Aktualisieren schneller vonstatten geht).

Fügen Sie die Commits jeweils einer Version zu Ihrer Quelle hinzu

Der wichtigste Teil dieses Prozesses ist jeweils die Version. Möglicherweise befindet sich in Ihrer Upstream-Serie ein Problem-Patch, das zu einem Problem beim Booten oder Unterbrechen von Sound oder Laden führen kann (siehe Tipps und Tricks). Aus diesem Grund ist es wichtig, inkrementelle Versionsänderungen vorzunehmen. Bei einigen Versionen ist es einfacher, ein Problem in 50 Commits zu finden, als ab 2000 Commits. Ich würde nur empfehlen, eine vollständige Zusammenführung durchzuführen, wenn Sie alle Probleme und Konfliktlösungen kennen.

Rosinenpickerei

Format:

 Git Cherry-Pick .. 

Beispiel:

Git Cherry-Pick v3.10.73..v3.10.74

Verschmelzen

Format:

 Git Merge 

Beispiel:

Git Merge v3.10.74

Ich empfehle, die Konflikte in Merge-Commits zu verfolgen, indem Sie die # -Markierungen entfernen.

Konflikte lösen

Wir können keine Schritt-für-Schritt-Anleitung zur Lösung jedes einzelnen Konflikts geben, da dies gute Kenntnisse der C-Sprache voraussetzt, aber hier einige Hinweise.

Wenn Sie zusammenführen, ermitteln Sie, welches Commit den Konflikt verursacht. Sie können dies auf zwei Arten tun:

  1. git log -pv $ (Kernelversion erstellen) .., um die Änderungen zwischen Ihrer aktuellen Version und der neuesten Version vom Upstream abzurufen. Das Flag -p gibt Ihnen die Änderungen an, die von jedem Commit vorgenommen wurden, damit Sie sehen können.
  2. Führen Sie git blame für die Datei aus, um die Hashes für jedes Commit in dem Bereich abzurufen. Sie können dann git show –format = fuller ausführen, um festzustellen, ob der Committer von mainline / stable, Google oder CodeAurora stammt.
  • Finden Sie heraus, ob Sie das Commit bereits haben. Einige Anbieter wie Google oder CAF werden versuchen, im Upstream nach kritischen Fehlern zu suchen, z. B. die Fehlerbehebung für Dirty COW, und ihre Backports könnten mit denen im Upstream in Konflikt geraten. Sie können git log –grep = ”” ausführen und prüfen, ob etwas zurückgegeben wird. Ist dies der Fall, können Sie das Festschreiben überspringen (wenn Sie mit git reset - hard && git cherry-pick - fortfahren) oder die Konflikte ignorieren (<<<<< >>>> entfernen).
  • Finden Sie heraus, ob ein Backport die Auflösung durcheinander gebracht hat. Google und CAF möchten bestimmte Patches, die nicht stabil sind, zurückportieren. Stable muss die Auflösung des Mainline-Commits häufig an das Fehlen bestimmter Patches anpassen, die Google für den Backport auswählt. Sie können sich das Mainline-Commit ansehen, indem Sie git show ausführen (der Mainline-Hash steht in der Commit-Nachricht des Stable-Commits zur Verfügung). Wenn ein Backport es vermasselt, können Sie entweder die Änderungen verwerfen oder die Hauptversion verwenden (was normalerweise erforderlich ist).
  • Lesen Sie, was der Commit versucht, und prüfen Sie, ob das Problem bereits behoben ist. Manchmal kann es vorkommen, dass CAF einen Fehler unabhängig vom Upstream behebt. Dies bedeutet, dass Sie den Fehler entweder für den Upstream überschreiben oder wie oben beschrieben verwerfen können.

Andernfalls ist es möglicherweise nur ein Ergebnis eines CAF / Google / OEM-Zusatzes. In diesem Fall müssen Sie nur einige Dinge durcheinander bringen.

Hier ist ein Spiegel des Linux-stabilen kernel.org-Repositorys auf GitHub, das das Nachschlagen von Commit-Listen und Unterschieden für die Konfliktlösung erleichtert. Ich empfehle, zuerst die Commit-Listenansicht aufzurufen und das Problem Commit zu suchen, um das ursprüngliche Diff zu sehen und es mit Ihrem zu vergleichen.

Beispiel-URL: //github.com/nathanchance/linux-stable/commits/linux-3.10.y/arch/arm64/mm/mmu.c

Sie können dies auch über die Befehlszeile tun:

 Git Log .. Git Show 

Beim Lösen von Auflösungen dreht sich alles um den Kontext. Was Sie IMMER tun sollten, ist sicherzustellen, dass Ihr finales Diff mit dem des Upstreams übereinstimmt, indem Sie die folgenden Befehle in zwei separaten Fenstern ausführen:

 git diff HEAD git diff v $ (Kernelversion erzeugen) .. $ (git tag --sort = -taggerdate -lv $ (Kernelversion erzeugen | cut -d. -f 1, 2) * | head -n1) 

Erneut aktivieren

Git hat eine Funktion namens "rerere" (steht für "Reuse Recorded Resolution"), was bedeutet, dass beim Erkennen eines Konflikts aufgezeichnet wird, wie Sie ihn gelöst haben, damit Sie ihn später wiederverwenden können. Dies ist besonders hilfreich für beide chronischen Rebasers, sowohl beim Zusammenführen als auch beim Kirschpflücken, da Sie nur git add ausführen müssen. && git - Fahren Sie fort, wenn Sie den Upstream-Aufruf wiederholen, da der Konflikt so gelöst wird, wie Sie ihn zuvor gelöst haben.

Sie können es aktivieren, indem Sie den folgenden Befehl in Ihrem Kernel-Repository ausführen:

 git config rerere.enabled true 

Wie man eine Zweiteilung durchführt, wenn ein Compiler- oder Laufzeitfehler auftritt

Angesichts der Tatsache, dass Sie eine beträchtliche Anzahl von Commits hinzufügen werden, ist es sehr gut möglich, dass Sie einen Compiler- oder Laufzeitfehler einführen. Anstatt einfach aufzugeben, können Sie das in git integrierte Zweiteilungswerkzeug verwenden, um die Hauptursache des Problems herauszufinden! Im Idealfall erstellen und flashen Sie jede einzelne Kernel-Version, während Sie sie hinzufügen, sodass die Halbierung bei Bedarf weniger Zeit in Anspruch nimmt. Sie können jedoch 5000 Commits ohne Probleme halbieren.

Was GIT BISECT tun wird, ist eine Reihe von Festschreibungen vorzunehmen, von wo das Problem vorliegt bis zu wo es nicht vorliegt, und dann den Festschreibungsbereich zu halbieren, damit Sie bauen und testen und es wissen lassen können, ob es gut ist oder nicht . Dies wird fortgesetzt, bis das Commit, das Ihr Problem verursacht, ausgespuckt wird. An diesem Punkt können Sie es entweder reparieren oder zurücksetzen.

  1. Start bisecting: Git-Bisect-Start
  2. Kennzeichnen Sie die aktuelle Revision als schlecht: git bisect bad
  3. Kennzeichnen Sie eine Revision als gut: git bisect good
  4. Erstellen Sie mit der neuen Revision
  5. Sagen Sie anhand des Ergebnisses (ob das Problem vorliegt oder nicht) git: git bisect good ODER git bisect bad
  6. Spülen und wiederholen Sie die Schritte 4 bis 5, bis das Problem festgestellt wurde.
  7. Stellen Sie das Problem fest, oder beheben Sie es.

ANMERKUNG: Fusionen müssen vorübergehend git rebase -i ausführen, um alle Patches auf Ihren Zweig anzuwenden, damit eine ordnungsgemäße Zweiteilung erfolgt, da die Zweiteilung mit den vorhandenen Zusammenführungen häufig zu einem Check-out für die vorgelagerten Commits führt, dh Sie haben keine der Android-spezifischen Commits. Ich kann auf Anfrage näher darauf eingehen, aber vertraue mir, es wird gebraucht. Sobald Sie das Problem festgestellt haben, können Sie es zurücksetzen oder in die Zusammenführung einbinden.

Upstream-Updates NICHT quetschen

Viele neue Entwickler sind versucht, dies zu tun, da es "sauberer" und "einfacher" zu verwalten ist. Das ist aus ein paar Gründen schrecklich:

  • Die Urheberschaft geht verloren. Es ist unfair gegenüber anderen Entwicklern, wenn ihre Verdienste für ihre Arbeit gestrichen werden.
  • Eine Halbierung ist nicht möglich. Wenn Sie eine Reihe von Commits quetschen und in dieser Reihe ein Problem auftritt, können Sie nicht feststellen, durch welches Commit ein Problem bei einem Squash verursacht wurde.
  • Zukünftige Cherry-Picks sind schwieriger. Wenn Sie mit einer gequetschten Serie rebasieren müssen, ist es schwierig / unmöglich zu sagen, woher ein Konflikt kommt.

Abonnieren Sie die Mailingliste für den Linux-Kernel, um aktuelle Informationen zu erhalten

Um bei jedem Upstream-Update benachrichtigt zu werden, abonnieren Sie die linux-kernel-announce-Liste. Auf diese Weise können Sie jedes Mal eine E-Mail erhalten, wenn ein neuer Kernel veröffentlicht wird, damit Sie so schnell wie möglich aktualisieren und auf den neuesten Stand bringen können.

Interessante Artikel