Android-Kernel-ABI-Überwachung

Sie können die Anwendungstools zur Überwachung der Binärschnittstelle (ABI) verwenden, die in Android 11 und höher verfügbar sind, um die Kernel-ABI von Android-Kerneln zu stabilisieren. Das Werkzeug sammelt und vergleicht ABI Darstellungen aus vorhandenen Kernel - Binärdateien ( vmlinux + Module). Diese ABI Darstellungen sind die .xml - Dateien und die Symbollisten. Die Schnittstelle, auf die die Darstellung eine Ansicht gibt, wird als Kernel Module Interfaces (KMIs) bezeichnet. Sie können die Tools verwenden, um Änderungen am KMI zu verfolgen und abzuschwächen.

Die ABI Überwachung Werkzeuge wird in AOSP entwickelt und verwendet libabigail Darstellungen zu erzeugen und zu vergleichen.

Auf dieser Seite werden die Tools, der Prozess zum Sammeln und Analysieren von ABI-Darstellungen und die Verwendung solcher Darstellungen beschrieben, um Stabilität für das In-Kernel-ABI zu gewährleisten. Diese Seite enthält auch Informationen zum Mitwirken von Änderungen an den Android-Kernels.

Dieses Verzeichnis enthält die spezifischen Werkzeuge für die ABI - Analyse. Verwenden Sie es mit dem Build - Skripte , bereitgestellt durch build_abi.sh .)

Verfahren

Die Analyse der ABI des Kernels erfordert mehrere Schritte, von denen die meisten automatisiert werden können:

  1. Erwerben Sie die Toolchain, Build - Skripte und die Kernel - Quellen durch repo .
  2. Geben Sie libabigail alle Voraussetzungen (wie die libabigail Bibliothek und Sammlung von Werkzeugen).
  3. Erstellen Sie den Kernel und seine ABI Darstellung .
  4. Analysieren ABI Unterschiede zwischen dem Aufbau und einer Referenz .
  5. Aktualisieren Sie die ABI Vertretung (falls erforderlich) .
  6. Arbeit mit Symbollisten .

Die folgenden Anweisungen gelten für jeden Kernel , dass Sie bauen können eine unterstützte Werkzeugkette (wie die vorkompilierte Clang Toolchain) verwenden. repo manifests - repo manifests sind für alle Android gemeinsamen Kernel Filialen verfügbar und für mehrere gerätespezifische Kerne sorgen sie dafür , dass die richtige Werkzeugkette wird verwendet, wenn Sie einen Kernel - Distribution für Analyse aufzubauen.

Verwenden des ABI-Monitoring-Tools

1. Erwerben Sie die Toolchain, erstellen Sie Skripte und Kernel-Quellen über Repository

Sie können die Werkzeugkette, Build - Skripte (diese Skripte) und Kernel - Quellen mit erwerben repo . Eine ausführliche Dokumentation finden Sie die entsprechenden Informationen für den Bau Android - Kernel .

Um den Prozess zu erläutern, werden die folgenden Schritte verwenden common-android12-5.10 , ein Android - Kernel Zweig, der die zuletzt veröffentlichte GKI Kernel zum Zeitpunkt des Schreibens dieses Artikels ist. Um diesen Zweig durch zu erhalten repo , führen Sie die folgenden:

repo init -u https://android.googlesource.com/kernel/manifest -b common-android12-5.10
repo sync

2. Voraussetzungen schaffen

Das ABI-Tooling verwendet libabigail, eine Bibliothek und eine Sammlung von Tools, um Binärdateien zu analysieren. Ein geeigneter Satz von vorkompilierten Binärdateien kommt mit den Kernel-build-Tool und wird automatisch mit verwendet build_abi.sh .

Um die untergeordneten Werkzeuge (wie zu nutzen dump_abi ), fügen Sie die Kernel-Build- Tools zum PATH .

3. Erstellen Sie den Kernel und seine ABI-Darstellung

An diesem Punkt sind Sie bereit , einen Kernel mit der richtigen Werkzeugkette aufzubauen und eine ABI Darstellung von seinen Binärdateien (zu extrahieren vmlinux + Module).

Ähnlich wie bei dem üblichen Android - Kernel Build - Prozess (mit build.sh ) erfordert läuft dieser Schritt build_abi.sh .

BUILD_CONFIG=common/build.config.gki.aarch64 build/build_abi.sh

Das baut den Kernel und extrahiert die ABI - Darstellung in dem out_abi Unterverzeichnis. In diesem Fall out/android12-5.10/dist/abi.xml ist ein symbolischer Link auf out_abi/android12-5.10/dist/abi-<id>.xml . < id> wird berechnet durch Ausführen git describe gegen den Kernelquellen.

4. Analysieren Sie die ABI-Unterschiede zwischen dem Build und einer Referenzdarstellung

build_abi.sh analysiert und meldet alle ABI Unterschiede , wenn ein Referenz durch die Umgebungsvariable zur Verfügung gestellt ABI_DEFINITION . ABI_DEFINITION muss eine Referenzdatei in Bezug auf den Kernquellbaum zeigen, und kann auf der Befehlszeile oder, häufiger, in build.config als einen Wert festgelegt werden. Im Folgenden finden Sie ein Beispiel:

BUILD_CONFIG=common/build.config.gki.aarch64 build/build_abi.sh

In dem obigen Befehl, build.config.gki.aarch64 definiert die Referenzdatei (wie ABI_DEFINITION=android/abi_gki_aarch64.xml ) und diff_abi Anrufe abidiff die frisch erzeugten ABI Darstellung gegenüber der Referenzdatei zu vergleichen. build_abi.sh druckt die Lage des Berichts und gibt einen kurzen Bericht für jeden ABI Bruch. Wenn Brüche festgestellt werden , build_abi.sh beendet und gibt einen von Null verschiedenen Beendigungscode.

5. Aktualisieren Sie die ABI-Darstellung (falls erforderlich)

So aktualisieren Sie die ABI Darstellung, invoke build_abi.sh mit der --update Flagge. Es aktualisiert die entsprechenden abi.xml - Datei , die durch definiert ist build.config . So drucken Sie die ABI Unterschiede aufgrund der Aktualisierung, rufen Sie das Skript mit --print-report . Achten Sie darauf , den Bericht aufzunehmen in der Commit - Nachricht , wenn die Aktualisierung abi.xml Datei.

6. Arbeiten mit Symbollisten

Parametrisieren build_abi.sh mit KMI Symbolliste an Filter Symbole während der Extraktion ABI. Dies sind reine Textdateien, die relevante ABI-Kernelsymbole auflisten. Zum Beispiel begrenzt eine Symbol - List - Datei mit folgendem Inhalt ABI Analyse der ELF - Symbole mit den Namen symbol1 und symbol2 :

[abi_symbol_list]
   symbol1
   symbol2

Änderungen an anderen ELF-Symbolen werden nicht berücksichtigt. Eine Symbol Listendatei kann in der entsprechenden angegeben wird build.config mit Konfigurationsdatei KMI_SYMBOL_LIST= als Datei in Bezug auf das Kernel - Quellverzeichnis ( $KERNEL_DIR ). Um eine Ebene der Organisation zur Verfügung stellen, können Sie zusätzliche Symbollisten Dateien angeben , indem Sie ADDITIONAL_KMI_SYMBOL_LISTS= in der build.config Datei. Dies gibt weitere Symbolliste Dateien, bezogen auf $KERNEL_DIR ; Trennen Sie mehrere Dateinamen durch Leerzeichen.

Um eine erste Symbolliste zu erstellen oder einen vorhandenen zu aktualisieren, müssen Sie die Verwendung build_abi.sh Skript mit dem --update-symbol-list Parameter.

Wenn das Skript mit einer geeigneten Konfiguration ausgeführt wird, baut es den Kernel und extrahiert die Symbole , die aus exportiert werden vmlinux und GKI - Module und die von irgendeinem anderen Modul im Baum benötigt werden.

Betrachten Sie vmlinux exportieren folgende Symbole ( in der Regel über das getan EXPORT_SYMBOL* Makros):

  func1
  func2
  func3

Auch vorstellen, zwei Lieferantenmodule waren, modA.ko und modB.ko , die folgenden Symbole erfordern (in anderen Worten, sie Liste undefined Symboleinträge in ihrer Symboltabelle):

 modA.ko:    func1 func2
 modB.ko:    func2

Von einer ABI Stabilität Sicht func1 und func2 muss stabil gehalten werden, da sie durch ein externes Modul gewohnt sind. Im Gegenteil, während func3 exportiert wird, wird es nicht aktiv genutzt von jedem Modul (mit anderen Worten, es ist nicht erforderlich). Somit enthält die Symbolliste func1 und func2 nur.

So erstellen oder eine vorhandene Symbolliste zu aktualisieren, build_abi.sh muss ausgeführt werden , wie folgt:

BUILD_CONFIG=path/to/build.config.device build/build_abi.sh --update-symbol-list

In diesem Beispiel build.config.device müssen mehrere Konfigurationsoptionen umfassen:

  • vmlinux muss in der sein FILES - Liste.
  • KMI_SYMBOL_LIST müssen Set und zeigt auf der KMI Symbolliste zu aktualisieren sein.
  • GKI_MODULES_LIST muss in der Liste der GKI Module gesetzt und zeigen werden. Dieser Weg ist in der Regel android/gki_aarch64_modules .

Arbeiten mit den untergeordneten ABI-Tools

Die meisten Benutzer werden nur verwenden müssen build_abi.sh . In einigen Fällen kann es erforderlich sein, direkt mit den untergeordneten ABI-Tools zu arbeiten. Die beiden verwendeten Befehle von build_abi.sh , dump_abi und diff_abi sind verfügbar ABI - Dateien zu extrahieren und zu vergleichen. Informationen zu ihrer Verwendung finden Sie in den folgenden Abschnitten.

Erstellen von ABI-Darstellungen aus Kernelbäumen

Vorausgesetzt , ein Linux - Kernel - Baum mit eingebautem vmlinux und Kernel - Module, wobei das Werkzeug dump_abi erzeugt eine Darstellung , die die ABI ausgewählt ABI Werkzeug. Ein Beispielaufruf sieht so aus:

dump_abi --linux-tree path/to/out --out-file /path/to/abi.xml

Die Datei abi.xml enthält eine textuelle ABI Darstellung des kombinierten, beobachtbare ABI von vmlinux und den Kernel - Module im angegebenen Verzeichnis. Diese Datei kann zur manuellen Inspektion, weiteren Analyse oder als Referenzdatei verwendet werden, um die ABI-Stabilität zu erzwingen.

ABI-Darstellungen vergleichen

ABI Darstellungen erstellt dump_abi können verglichen werden diff_abi . Verwenden Sie die gleiche abi-Werkzeug für dump_abi und diff_abi . Ein Beispielaufruf sieht so aus:

diff_abi --baseline abi1.xml --new abi2.xml --report report.out

Der generierte Bericht listet erkannte ABI-Änderungen auf, die den KMI betreffen. Die Dateien wie angegeben baseline und new sind ABI Darstellungen , die mit gesammelt wurden dump_abi . diff_abi pflanzt sich der Beendigungscode des zugrunde liegenden Werkzeugs und daher gibt einen Wert ungleich Null , wenn die verglichenen ABIs inkompatibel sind.

KMI-Symbollisten verwenden

Um Filterdarstellungen erstellt mit dump_abi oder Filtersymbolen verglichen mit diff_abi , verwendet , um die Parameter --kmi-symbol-list , die einen Pfad zu einer Datei KMI Symbolliste nimmt:

dump_abi --linux-tree path/to/out --out-file /path/to/abi.xml --kmi-symbol-list /path/to/symbol_list_file

Vergleich von Kernel-Binärdateien mit der GKI-Referenz KMI

Während Sie auf der GKI Kernel Compliance arbeiten, ist es sinnvoll , ein lokales Kernel - Build zu einer Referenz GKI KMI Darstellung regelmäßig zu vergleichen , ohne Verwendung mit build_abi.sh . Das Werkzeug gki_check ist ein leichtes Werkzeug , um genau das zu tun. Bei einem lokalen Linux-Kernel-Build-Baum, einem Beispielaufruf, um die Darstellung der lokalen Binärdateien zu vergleichen, ist zum Beispiel der Vergleich mit der 5.4-Darstellung:

build/abi/gki_check --linux-tree path/to/out/ --kernel-version 5.4

gki_check verwendet Parameternamen im Einklang mit dump_abi und diff_abi . Daher --kmi-symbol-list path/to/kmi_symbol_list_file kann verwendet werden , daß für den Vergleich erlaubt Symbole zu begrenzen , indem eine KMI Symbolliste übergeben.

Umgang mit ABI-Brüchen

Als Beispiel führt der folgende Patch einen sehr offensichtlichen ABI-Bruch ein:

 diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
  index 5ed8f6292a53..f2ecb34c7645 100644
  --- a/include/linux/mm_types.h
  +++ b/include/linux/mm_types.h
  @@ -339,6 +339,7 @@ struct core_state {
   struct kioctx_table;
   struct mm_struct {
      struct {
  +       int dummy;
          struct vm_area_struct *mmap;            /* list of VMAs */
          struct rb_root mm_rb;
          u64 vmacache_seqnum;                   /* per-thread vmacache */

Wenn Sie laufen build_abi.sh wieder mit diesem Patch angewendet, die Werkzeug endet mit einem Nicht-Null - Fehler - Code und meldet einen ABI Unterschied ähnlich wie folgt aus :

 Leaf changes summary: 1 artifact changed
  Changed leaf types summary: 1 leaf type changed
  Removed/Changed/Added functions summary: 0 Removed, 0 Changed, 0 Added function
  Removed/Changed/Added variables summary: 0 Removed, 0 Changed, 0 Added variable

  'struct mm_struct at mm_types.h:372:1' changed:
    type size changed from 6848 to 6912 (in bits)
    there are data member changes:
  [...]

Reparieren eines defekten ABI auf Android Gerrit

Wenn Sie die Kernel-ABI nicht absichtlich beschädigt haben, müssen Sie dies anhand der Anleitung des ABI-Überwachungstools untersuchen. Die häufigsten Ursachen für Fehler sind hinzugefügte oder gelöschte Funktionen, geänderte Datenstrukturen oder Änderungen an der ABI, die durch das Hinzufügen von Konfigurationsoptionen verursacht wurden, die zu einem der oben genannten führen. Beginnen Sie damit, die vom Tool gefundenen Probleme zu beheben.

Sie können , indem Sie den folgenden Befehl mit den gleichen Argumenten des ABI - Test vor Ort reproduzieren , dass Sie für den Betrieb verwendet haben würde build/build.sh :

Dies ist ein Beispielbefehl für die GKI-Kernel:

BUILD_CONFIG=common/build.config.gki.aarch64 build/build_abi.sh

Aktualisieren der Kernel-ABI

Wenn Sie die Kernel ABI Darstellung aktualisieren müssen, dann müssen Sie aktualisieren die entsprechende abi.xml Datei im Kernel - Quellbaum. Der bequemste Weg , dies zu tun ist durch die Verwendung build/build_abi.sh wie folgt:

build/build_abi.sh --update --print-report

Verwenden Sie die gleichen Argumente , dass Sie hätte ausgeführt werden sollen build/build.sh . Dieses Update der richtige abi.xml im Quellbaum und druckt die ermittelten Unterschiede. Fügen Sie in der Praxis den gedruckten (Kurz-)Bericht (zumindest teilweise) in die Commit-Nachricht ein.

Android Kernel Branches mit vordefiniertem ABI

Einige Kernel-Zweige enthalten vordefinierte ABI-Darstellungen für Android als Teil ihrer Quelldistribution. Diese ABI Darstellungen sollen genau sein, und das Ergebnis zu reflektieren build_abi.sh , als ob Sie es auf eigene Faust ausführen würde. Da das ABI stark von verschiedenen Kernel - Konfigurationsoptionen beeinflusst wird, diese .xml in der Regel Dateien zu einer bestimmten Konfiguration gehören. Zum Beispiel kann der common-android12-5.10 enthält Zweig eine abi_gki_aarch64.xml Das entspricht das build Ergebnis , wenn die Verwendung von build.config.gki.aarch64 . Insbesondere build.config.gki.aarch64 bezieht sich auch auf diese Datei durch ABI_DEFINITION .

Solche vordefinierten ABI Darstellungen werden als Basislinie Definition verwendet wird, wenn beim Vergleichen diff_abi . Um zum Beispiel einer Kernel - Patch in Bezug auf Änderungen an das ABI, erstellen Sie die ABI - Darstellung mit dem Patch angewandt und verwenden zu validieren diff_abi vergleichen es mit dem erwarteten ABI für diesen bestimmten Quellbaum oder Konfiguration. Wenn ABI_DEFINITION gesetzt ist, läuft build_abi.sh wird entsprechend verfahren.

Erzwingen des KMI mithilfe der Modulversionierung

Die GKI kerne Verwendung Modul Versionierung ( CONFIG_MODVERSIONS ) KMI Compliance zur Laufzeit zu erzwingen. Modul Versionierung verursacht CRC Mismatch Ausfälle bei Modulladezeit , wenn die erwartete KMI eines Moduls nicht den Vorstellungen vmlinux KMI. Zum Beispiel, hier ist ein typischer Fehler, der aufgrund eines CRC - Konflikt für das Symbol auf Modulladezeit tritt module_layout() :

init: Loading module /lib/modules/kernel/.../XXX.ko with args ""
XXX: disagrees about version of symbol module_layout
init: Failed to insmod '/lib/modules/kernel/.../XXX.ko' with args ''

Modulversionierung verwendet

Die Modulversionierung ist aus vielen Gründen nützlich:

  1. Es erfasst Änderungen in der Sichtbarkeit der Datenstruktur. Wenn Module undurchsichtige Datenstrukturen ändern können, z. B. Datenstrukturen, die nicht Teil des KMI sind, werden Module nach zukünftigen Änderungen an der Struktur unterbrochen.
  2. Es fügt eine Laufzeitprüfung hinzu, um zu vermeiden, dass versehentlich ein Modul geladen wird, das nicht mit dem Kernel KMI-kompatibel ist. (Zum Beispiel, wenn ein aktuelles Modul zu einem späteren Zeitpunkt von einem neuen Kernel geladen wird, der nicht kompatibel ist.) Dies ist vorzuziehen, wenn nachfolgende Laufzeitprobleme oder Kernel-Abstürze schwer zu debuggen sind.
  3. abidiff hat Einschränkungen bei der Identifizierung von ABI Unterschiede in bestimmten Fällen gewundenen dass CONFIG_MODVERSIONS fangen kann.

Als Beispiel für (1), die betrachten fwnode Feld in struct device . Das Feld muss undurchlässig Module sein , so dass sie keine Änderungen an Bereichen machen können device->fw_node oder machen Annahmen über seine Größe.

Wenn jedoch ein Modul enthält <linux/fwnode.h> (direkt oder indirekt), dann das fwnode Feld in der struct device stoppt undurchlässig zu sein. Das Modul kann dann Änderungen an device->fwnode->dev oder device->fwnode->ops . Das ist aus mehreren Gründen problematisch:

  1. Es kann Annahmen brechen, die der Kernelcode über seine internen Datenstrukturen macht.

  2. Wenn ein zukünftiger Kernel - Update die Änderungen struct fwnode_handle (der Datentyp fwnode ), dann wird das Modul nicht mit dem neuen Kernel arbeiten. Darüber hinaus abidiff zeigen keine Unterschiede , da das Modul die KMI bricht durch die direkte interne Datenstrukturen in einer Weise manipuliert , die nicht nur erfasst werden kann , indem die binäre Darstellung inspizieren.

Das Aktivieren der Modulversionsverwaltung verhindert all diese Probleme.

Auf CRC-Nichtübereinstimmungen prüfen, ohne das Gerät zu booten

Alle Kernel - Build mit CONFIG_MODVERSIONS aktiviert eine generiert Module.symvers Datei als Teil des Build - Prozesses. Die Datei hat eine Zeile für jede von der exportierten Symbol vmlinux und die Module. Jede Zeile besteht aus dem CRC - Wert, Symbol Namen, Symbol - Namensraum, vmlinux oder Modulnamen, der das Symbol den Export und den Exporttyp (zum Beispiel EXPORT_SYMBOL vs. EXPORT_SYMBOL_GPL ).

Sie können die vergleichen Module.symvers Dateien zwischen dem GKI zu bauen und Ihren Build für alle CRC Unterschiede in den Symbolen von exportiert zu überprüfen vmlinux . Wenn es eine CRC - Wert - Differenz in jedem Symbol durch ausgeführte vmlinux und durch eines des Module verwendet wird Sie in Ihrem Gerät laden, wird das Modul nicht geladen werden .

Wenn Sie nicht alle die Build - Artefakte haben, haben aber nur die vmlinux Dateien des GKI - Kernel und den Kernel, können Sie den CRC - Wert für ein bestimmtes Symbol vergleichen , indem Sie den folgenden Befehl ausführen sowohl auf den Kernel, dann die Ausgabe zu vergleichen:

nm <path to vmlinux>/vmlinux | grep __crc_<symbol name>

Um zum Beispiel des CRC - Wert für das überprüfen module_layout Symbol,

nm vmlinux | grep __crc_module_layout
0000000008663742 A __crc_module_layout

CRC-Mismatch beheben

Wenn Sie beim Laden des Moduls eine CRC-Nichtübereinstimmung erhalten, können Sie dies wie folgt beheben:

  1. Erstellen Sie den GKI - Kernel und das Gerät Kernel und fügt KBUILD_SYMTYPES=1 vor dem Befehl , den Sie verwenden , um den Kernel zu bauen. Beachten Sie , bei der Verwendung von build_abi.sh, ist dies bereits implizit gesetzt. Dies wird eine generieren .symtypes Datei für jede .o - Datei. Zum Beispiel:

    KBUILD_SYMTYPES=1 BUILD_CONFIG=common/build.config.gki.aarch64 build/build.sh
    
  2. Finden Sie die .c - Datei , in der das Symbol mit CRC - Mismatch exportiert wird. Zum Beispiel:

    cd common && git grep EXPORT_SYMBOL.*module_layout
    kernel/module.c:EXPORT_SYMBOL(module_layout);
    
  3. Die .c Datei hat eine entsprechende .symtypes Datei in der GKI und Ihr Gerät Kernel Build Artefakte.

    cd out/$BRANCH/common && ls -1 kernel/module.*
    kernel/module.o
    kernel/module.o.symversions
    kernel/module.symtypes
    

    A. Das Format dieser Datei ist eine (möglicherweise sehr lange) Zeile pro Symbol.

    B. [s|u|e|etc]# am Anfang der Zeile bedeutet das Symbol des Datentypen ist [struct|union|enum|etc] . Zum Beispiel t#bool typedef _Bool bool .

    C. A fehlt # Präfix im Anfang der Zeile zeigt das Symbol eine Funktion ist. Zum Beispiel,
    find_module s#module * find_module ( const char * ) .

  4. Vergleichen Sie diese beiden Dateien und beheben Sie alle Unterschiede.

Fall 1: Unterschiede aufgrund der Sichtbarkeit des Datentyps

Wenn ein Kernel hält ein Symbol oder Datentyp undurchsichtig zu den Modulen und der andere Kernel nicht, dann zeigt es zwischen den als Differenz bis .symtypes Dateien der beiden Kerne. Die .symtypes Datei von einem des Kerns hat UNKNOWN für ein Symbol und die .symtypes Datei von dem anderen Kernel eine erweiterte Ansicht des Symbol oder Datentyp hat.

Zum Beispiel annimmt , dass Sie diese Zeile in dem include/linux/device.h im Kernel:

 #include <linux/fwnode.h>

Das verursacht CRC Mismatches, mit einem von ihnen für module_layout() . Wenn Sie die vergleichen module.symtypes für dieses Symbol, sieht es wie folgt aus :

 $ diff -u <GKI>/kernel/module.symtypes <your kernel>/kernel/module.symtypes
  --- <GKI>/kernel/module.symtypes
  +++ <your kernel>/kernel/module.symtypes
  @@ -334,12 +334,15 @@
  ...
  -s#fwnode_handle struct fwnode_handle { UNKNOWN }
  +s#fwnode_reference_args struct fwnode_reference_args { s#fwnode_handle * fwnode ; unsigned int nargs ; t#u64 args [ 8 ] ; }
  ...

Wenn Ihr Kernel es wie hat UNKNOWN und der GKI - Kernel hat die erweiterte Ansicht des Symbols (sehr unwahrscheinlich), dann verschmelzen die neuesten Android gemeinsamen Kernel in den Kernel , so dass Sie die neueste GKI Kernel Basis verwenden.

Fast immer hat der GKI - Kernel als UNKNOWN , aber Ihr Kernel hat die internen Einzelheiten des Symbols aufgrund von Änderungen an deinem Kernel vorgenommen. Dies liegt daran , eine der Dateien in Ihrem Kernel eine hinzugefügt #include , die nicht in dem GKI - Kernel ist.

Um die Identifizierung #include , die den Unterschied verursacht, gehen Sie folgendermaßen vor:

  1. Öffnen Sie die Header-Datei, die das Symbol oder den Datentyp mit diesem Unterschied definiert. Zum Beispiel bearbeiten include/linux/fwnode.h für die struct fwnode_handle .
  2. Fügen Sie am Anfang der Header-Datei den folgenden Code hinzu:

    #ifdef CRC_CATCH
    #error "Included from here"
    #endif
    
  3. Dann , in dem die Modul .c - Datei (die eine , die ein CRC - Mismatch aufweist), die folgende als die erste Zeile , bevor einen der #include Linien.

    #define CRC_CATCH 1
    
  4. Kompilieren Sie nun Ihr Modul. Sie erhalten einen Build - Zeitfehler , dass zeigt die Kette der Header - Datei erhalten #include , dass zu diesem CRC - Konflikt geführt. Zum Beispiel:

    In file included from .../drivers/clk/XXX.c:16:`
    In file included from .../include/linux/of_device.h:5:
    In file included from .../include/linux/cpu.h:17:
    In file included from .../include/linux/node.h:18:
    .../include/linux/device.h:16:2: error: "Included from here"
    #error "Included from here"
    
  5. Eines der Glieder dieser Kette von #include ist aufgrund einer Änderung im Kernel getan, die in der GKI Kernel fehlen wird .

  6. Sobald Sie die Änderung identifizieren, kehren sie in den Kernel oder es zu ACK laden und bekommen es verschmolzen .

Fall 2: Unterschiede aufgrund von Datentypänderungen

Wenn die CRC-Nichtübereinstimmung für ein Symbol oder einen Datentyp nicht auf einen Unterschied in der Sichtbarkeit zurückzuführen ist, liegt dies an tatsächlichen Änderungen (Hinzufügungen, Entfernungen oder Änderungen) am Datentyp selbst. Typischerweise abidiff Rasten dieses, aber wenn es ein aufgrund bekannten Nachweislücken auslässt, die MODVERSIONS kann Mechanismus fangen.

Angenommen, Sie nehmen die folgende Änderung in Ihrem Kernel vor:

diff --git a/include/linux/iommu.h b/include/linux/iommu.h
  --- a/include/linux/iommu.h
  +++ b/include/linux/iommu.h
  @@ -259,7 +259,7 @@ struct iommu_ops {
     void (*iotlb_sync)(struct iommu_domain *domain);
     phys_addr_t (*iova_to_phys)(struct iommu_domain *domain, dma_addr_t iova);
     phys_addr_t (*iova_to_phys_hard)(struct iommu_domain *domain,
  -        dma_addr_t iova);
  +        dma_addr_t iova, unsigned long trans_flag);
     int (*add_device)(struct device *dev);
     void (*remove_device)(struct device *dev);
     struct iommu_group *(*device_group)(struct device *dev);

Das würde eine Menge von CRC - Fehlpaarungen führen (so viele Symbole werden indirekt durch diese Art der Änderung betroffen sind ) und einer von ihnen würde für sein devm_of_platform_populate() .

Wenn Sie die vergleichen .symtypes Dateien für dieses Symbol, es könnte wie folgt aussehen:

 $ diff -u <GKI>/drivers/of/platform.symtypes <your kernel>/drivers/of/platform.symtypes
  --- <GKI>/drivers/of/platform.symtypes
  +++ <your kernel>/drivers/of/platform.symtypes
  @@ -399,7 +399,7 @@
  ...
  -s#iommu_ops struct iommu_ops { ... ; t#phy
  s_addr_t ( * iova_to_phys_hard ) ( s#iommu_domain * , t#dma_addr_t ) ; int
    ( * add_device ) ( s#device * ) ; ...
  +s#iommu_ops struct iommu_ops { ... ; t#phy
  s_addr_t ( * iova_to_phys_hard ) ( s#iommu_domain * , t#dma_addr_t , unsigned long ) ; int ( * add_device ) ( s#device * ) ; ...

Gehen Sie folgendermaßen vor, um den geänderten Typ zu identifizieren:

  1. Hier finden Sie die Definition des Symbols im Quellcode ( in der Regel in .h - Dateien).
  2. Wenn es zwischen der Kernel ein offensichtliches Symbol Unterschied ist und der GKI - Kernel, führen Sie eine git blame finden die begehen.
  3. Manchmal wird ein Symbol in einem Baum gelöscht und Sie möchten es im anderen Baum löschen. Um die Änderung zu finden, die die Zeile gelöscht hat, führen Sie diesen Befehl in der Baumstruktur aus, in der die Zeile gelöscht wurde:

    A. git log -S "copy paste of deleted line/word" -- <file where it was deleted>

    B. Sie erhalten eine verkürzte Liste von Commits. Der erste ist wahrscheinlich der, nach dem Sie suchen. Wenn dies nicht der Fall ist, gehen Sie die Liste durch, bis Sie den Commit finden.

  4. Sobald Sie die Änderung identifizieren, kehren sie entweder in den Kernel oder es zu ACK laden und bekommen es verschmolzen .