Surveillance de l'ABI du noyau Android

Vous pouvez utiliser les outils de surveillance de l'interface binaire d'application (ABI) disponibles dans Android 11 ou version ultérieure, pour stabiliser le noyau ABI des noyaux Android. L'outil collecte et compare les représentations d'ABI à partir de binaires de noyau existants (vmlinux + modules GKI). Ces ABI les représentations sont les fichiers .stg et les listes de symboles. L'interface de que la représentation donne une vue est appelée interface de module kernel (KMI). Vous pouvez utiliser les outils pour suivre et atténuer les changements du KMI.

Les outils de surveillance de l'ABI développé dans AOSP et utilise STG (ou libabigail po Android 13 ou version antérieure) pour générer et comparer représentations.

Cette page décrit les outils, le processus de collecte et d'analyse de l'ABI et l'utilisation de ces représentations pour assurer la stabilité l'ABI intégrée au noyau. Cette page fournit également des informations sur la contribution des modifications vers les noyaux Android.

Procédure

L'analyse de l'ABI du noyau se fait en plusieurs étapes, dont la plupart peuvent être automatisées:

  1. Créez le noyau et sa représentation ABI.
  2. Analysez les différences d'ABI entre la compilation et une référence.
  3. Mettez à jour la représentation de l'ABI (si nécessaire).
  4. Utiliser des listes de symboles

Les instructions suivantes s'appliquent noyau que vous pouvez créer à l'aide d'un une chaîne d'outils compatible (telle que la chaîne d'outils Clang prédéfinie). repo manifests sont disponibles pour toutes les branches courantes du noyau Android et pour plusieurs noyaux spécifiques à l'appareil, ils garantissent l'utilisation de la chaîne d'outils appropriée créer une distribution de noyau pour l'analyse.

Listes de symboles

Le KMI n'inclut pas tous les symboles du noyau,ni même tous les plus de 30 000 et les symboles exportés. À la place, les symboles qui peuvent être utilisés par les modules de fournisseurs sont explicitement listés dans un ensemble de fichiers de liste de symboles gérés publiquement dans le répertoire racine de l'arborescence du noyau. L'union de tous les symboles dans tous les fichiers de liste de symboles définit l'ensemble des symboles KMI conservés comme stables. Exemple de fichier de liste de symboles correspond à abi_gki_aarch64_db845c, qui déclare les symboles requis pour le paramètre DragonBoard 845c.

Seuls les symboles répertoriés dans une liste de symboles et leurs structures associées et les définitions sont considérées comme faisant partie du KMI. Vous pouvez intégrer les modifications des listes de symboles si les symboles dont vous avez besoin ne sont pas présents. Après le déploiement des nouvelles interfaces, une liste de symboles et qu'ils font partie de la description du KMI, ils sont conservés comme stables et ne doit pas être supprimé de la liste de symboles ni modifié une fois la branche est figée.

Chaque branche du noyau KMI d'Android Common Kernel (ACK) possède son propre ensemble de symboles . Aucune tentative visant à assurer la stabilité de l'ABI entre différents noyau KMI n'est effectuée branches. Par exemple, le KMI de android12-5.10 est complètement indépendant de le KMI pour android13-5.10.

Les outils ABI utilisent des listes de symboles KMI pour limiter les interfaces à surveiller la stabilité. La liste des symboles principaux contient les symboles requis par les modules du noyau GKI. Les fournisseurs sont vous êtes tenu d'envoyer et de mettre à jour d'autres listes de symboles pour garantir sur lesquelles elles s'appuient pour maintenir la compatibilité avec les ABI. Par exemple, pour afficher une liste de listes de symboles pour android13-5.15, reportez-vous à https://android.googlesource.com/kernel/common/+/refs/heads/android13-5.15/android

Une liste de symboles contient les symboles qui sont signalés comme nécessaires pour le du fournisseur ou de l'appareil. La liste complète utilisée par les outils combine toutes les Fichiers de liste de symboles KMI. Les outils ABI déterminent les détails de chaque symbole, y compris la signature de la fonction et les structures de données imbriquées.

Lorsque le KMI est figé, aucune modification n'est autorisée aux interfaces KMI existantes. ils sont stables. Toutefois, les fournisseurs sont libres d'ajouter des symboles au KMI à tout moment. tant que les ajouts n'affectent pas la stabilité de l'ABI existante. Ajouté récemment les symboles sont maintenus aussi stables quand ils sont cités par une liste de symboles KMI. Les symboles ne doivent pas être supprimés d'une liste pour un noyau, sauf s'ils peuvent être confirmés qu’aucun appareil n’a jamais été livré avec une dépendance sur ce symbole.

Vous pouvez générer une liste de symboles KMI pour un appareil en suivant les instructions de Utiliser les listes de symboles De nombreux partenaires soumettent une liste de symboles par ACK, mais ce n'est pas une exigence stricte. Si cela facilite la maintenance, vous pouvez envoyer plusieurs listes de symboles.

Étendez votre KMI

Alors que les symboles KMI et les structures associées sont conservés comme stables (ce qui signifie les modifications qui rompent les interfaces stables dans un noyau avec un KMI figé ne peuvent pas être le noyau GKI reste ouvert aux extensions pour que les appareils plus tard dans l'année n'ont pas besoin de définir toutes leurs dépendances avant que le KMI ne soit est figée. Pour étendre le KMI, vous pouvez ajouter de nouveaux symboles au KMI pour de nouveaux fonctions de noyau exportées existantes, même si le KMI est bloqué. Nouveau noyau des correctifs peuvent également être acceptés s'ils n'entravent pas le KMI.

À propos des problèmes de KMI

Un noyau dispose de sources, et les binaires sont créés à partir de ces sources. Les branches de noyau surveillées par ABI incluent une représentation ABI du GKI actuel ABI (sous la forme d'un fichier .stg). Après les binaires (vmlinux, Image et des modules GKI) sont compilés, une représentation d'ABI peut être extraite binaires. Toute modification apportée à un fichier source du noyau peut affecter les binaires et dans tourner affecte également l'élément .stg extrait. L'analyseur AbiAnalyzer compare les validé le fichier .stg avec celui extrait des artefacts de compilation et définit un Étiquette lint-1 sur le changement de Gerrit en cas de différence sémantique.

Gérer les défaillances d'ABI

Par exemple, le correctif suivant introduit une faille évidente dans l'ABI:

diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index 42786e6364ef..e15f1d0f137b 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -657,6 +657,7 @@ struct mm_struct {
                ANDROID_KABI_RESERVE(1);
        } __randomize_layout;

+       int tickle_count;
        /*
         * The mm_cpumask needs to be at the end of mm_struct, because it
         * is dynamically sized based on nr_cpu_ids.

Lorsque vous exécutez l'ABI de compilation avec ce correctif appliqué, l'outil se ferme avec un code d'erreur non nul et signale une différence d'ABI semblable à celle-ci:

function symbol 'struct block_device* I_BDEV(struct inode*)' changed
  CRC changed from 0x8d400dbd to 0xabfc92ad

function symbol 'void* PDE_DATA(const struct inode*)' changed
  CRC changed from 0xc3c38b5c to 0x7ad96c0d

function symbol 'void __ClearPageMovable(struct page*)' changed
  CRC changed from 0xf489e5e8 to 0x92bd005e

... 4492 omitted; 4495 symbols have only CRC changes

type 'struct mm_struct' changed
  byte size changed from 992 to 1000
  member 'int tickle_count' was added
  member 'unsigned long cpu_bitmap[0]' changed
    offset changed by 64

Différences d'ABI détectées au moment de la compilation

Cette erreur se produit généralement lorsqu'un conducteur utilise un nouveau symbole un noyau qui ne figure dans aucune des listes de symboles.

Si le symbole ne figure pas dans la liste (android/abi_gki_aarch64), vous devez d'abord vérifier qu'elle est exportée avec EXPORT_SYMBOL_GPL(symbol_name), puis mettez à jour Représentation XML ABI et liste de symboles. Par exemple, les modifications suivantes ajoutent la nouvelle fonctionnalité de SF incrémentielle dans la branche android-12-5.10, qui inclut la mise à jour de la liste de symboles et de la représentation XML de l'ABI.

  • L'exemple de modification de caractéristique est disponible aosp/1345659.
  • L'exemple de liste de symboles se trouve dans (aosp/1346742).
  • L'exemple de modification XML de l'ABI est aosp/1349377.

Si le symbole a été exporté (par vous ou précédemment), mais qu'il n'a autre pilote l'utilise, vous pouvez obtenir une erreur de compilation semblable à la suivante.

Comparing the KMI and the symbol lists:
+ build/abi/compare_to_symbol_list out/$BRANCH/common/Module.symvers out/$BRANCH/common/abi_symbollist.raw
ERROR: Differences between ksymtab and symbol list detected!
Symbols missing from ksymtab:
Symbols missing from symbol list:
 - simple_strtoull

Pour résoudre le problème, mettez à jour la liste des symboles KMI dans le noyau et dans l'ACK (voir Mettre à jour la représentation de l'ABI. Exemple : de la mise à jour du fichier XML d'ABI et de la liste de symboles dans l'ACK, reportez-vous à aosp/1367601.

Résoudre les problèmes d'ABI du noyau

Vous pouvez gérer les défaillances d'ABI du noyau en refactorisant le code pour ne pas modifier le ABI ou mettre à jour la représentation de l'ABI. Utilisez les éléments suivants : graphique afin de déterminer la meilleure approche pour votre situation.

Organigramme des défaillances de l'ABI

Figure 1 : Résolution des problèmes liés à l'ABI

Refactoriser le code pour éviter les modifications de l'ABI

Faites tout votre possible pour éviter de modifier l'ABI existante. Dans de nombreux cas, vous pouvez refactoriser votre code pour supprimer les modifications qui affectent l'ABI ;

  • Refactorisation des modifications du champ struct. Si une modification modifie l'ABI pour un débogage ajoutez un élément #ifdef autour des champs (dans les objets struct et source ) et assurez-vous que le CONFIG utilisé pour #ifdef est désactivé pour defconfig de production et gki_defconfig. Pour voir un exemple de la façon dont un service peut être ajoutée à un struct sans endommager l'ABI, reportez-vous à cette patchset, par exemple).

  • Refactorisation des fonctionnalités pour ne pas modifier le noyau principal. Si de nouvelles fonctionnalités ont besoin à ajouter à l'ACK afin de prendre en charge les modules partenaires, essayez de refactoriser l'ABI pour éviter de modifier l'ABI du noyau. Pour voir un exemple d'utilisation l'ABI du noyau existante pour ajouter des fonctionnalités sans modifier les ABI du noyau font référence aosp/1312213.

Corriger une ABI défectueuse sur Android Gerrit

Si vous n'avez pas intentionnellement cassé l'ABI du noyau, vous devez examiner, à l'aide des conseils fournis par les outils de surveillance de l'ABI. Les plus courantes les causes de défaillance sont la modification des structures de données et le symbole associé CRC. ou si l'option de configuration a changé à l'origine de l'un des problèmes susmentionnés. Commencez par résoudre les problèmes identifiés par l'outil.

Vous pouvez reproduire les résultats d'ABI localement. Consultez Créez le noyau et sa représentation ABI.

À propos des étiquettes lint-1

Si vous importez des modifications vers une branche contenant un KMI figé ou finalisé, les modifications doivent transmettre AbiAnalyzer pour que les modifications n'affectent pas la version stable de manière incompatible. Au cours de ce processus, AbiAnalyzer recherche un rapport d'ABI créé pendant la compilation (une compilation étendue qui exécute une compilation normale, puis quelques étapes d'extraction et de comparaison de l'ABI.

Si AbiAnalyzer trouve un rapport non vide, il définit le libellé lint-1 et l'envoi de la modification est bloqué jusqu'à ce qu'il soit résolu ; jusqu'à ce que le patchset ne reçoive Libellé lint+1.

Mettre à jour l'ABI du noyau

Si la modification de l'ABI est inévitable, vous devez appliquer vos modifications de code, la représentation de l'ABI et la liste de symboles à l'ACK. Pour que lint supprimez -1 sans affecter la compatibilité GKI, procédez comme suit:

  1. Importez les modifications de code sur l'ACK.

  2. Attendez de recevoir une évaluation de code +2 pour l'ensemble de correctifs.

  3. Mettez à jour la représentation de l'ABI de référence.

  4. Fusionnez vos modifications de code avec la modification de mise à jour de l'ABI.

Importer les modifications du code d'ABI dans l'ACK

La mise à jour de l'ABI ACK dépend du type de modification apportée.

  • Si une modification de l'ABI est liée à une fonctionnalité qui affecte les tests CTS ou VTS, changement peut généralement être sélectionné cerise sur ACK tel quel. Par exemple:

  • Si une modification de l'ABI concerne une fonctionnalité pouvant être partagée avec l'ACK, cette modification peut être sélectionnée cerise sur ACK en l’état. Par exemple, les modifications ne sont pas nécessaires pour le test CTS ou VTS, mais peuvent être partagés avec ACK:

    • (aosp/1250412). est un changement de caractéristique thermique.
    • (aosp/1288857). correspond à un changement de EXPORT_SYMBOL_GPL.
  • Si un changement d'ABI introduit une nouvelle fonctionnalité qui n'a pas besoin d'être incluse dans l’ACK, vous pouvez introduire les symboles dans ACK à l’aide d’un bouchon comme décrit dans dans la section suivante.

Utiliser des bouchons pour ACK

Les stubs ne doivent être nécessaires que pour les modifications du noyau sans avantage pour le ACK, comme les variations de performances et de puissance. La liste suivante fournit des exemples détaillés de bouchons et de sélections partielles dans l'ACK pour GKI.

  • Souche d'isolement de la caractéristique principale (aosp/1284493). Les capacités dans ACK ne sont pas nécessaires, mais les symboles doivent être présents dans ACK pour que vos modules utilisent ces symboles.

  • Symbole d'espace réservé pour le module "Fournisseur" (aosp/1288860).

  • Sélection ABI de la fonctionnalité de suivi des événements mm par processus (aosp/1288454). Le correctif d'origine a été sélectionné pour ACK, puis coupé pour n'inclure que les modifications nécessaires pour résoudre les différences d'ABI pour task_struct et mm_event_count Ce correctif met également à jour l'énumération mm_event_type pour qu'elle contienne les derniers membres.

  • Sélection partielle des modifications de l'ABI de la structure thermique qui nécessitaient plus que de simples en ajoutant les nouveaux champs d'ABI.

    • Corriger (aosp/1255544). Résolution des différences d'ABI entre le noyau partenaire et l'ACK

    • Corriger (aosp/1291018). Correction des problèmes fonctionnels détectés lors des tests GKI du correctif précédent. La correction incluait l'initialisation de la structure du paramètre "sens" afin d'enregistrer plusieurs zones thermiques à un seul capteur.

  • CONFIG_NL80211_TESTMODE modifications de l'ABI (aosp/1344321). Ce correctif a ajouté les modifications de structure nécessaires pour l'ABI et a permis de s'assurer d'autres champs n'entraînaient aucune différence fonctionnelle, permettant ainsi aux partenaires d'inclure CONFIG_NL80211_TESTMODE dans leurs noyaux de production tout en continuant à maintenir la conformité GKI.

Appliquer le KMI au moment de l'exécution

Les noyaux GKI utilisent les options de configuration TRIM_UNUSED_KSYMS=y et UNUSED_KSYMS_WHITELIST=<union of all symbol lists>, qui limitent les symboles exportés. (comme les symboles exportés à l'aide de EXPORT_SYMBOL_GPL()) vers ceux répertoriés sur une liste de symboles. Tous les autres symboles ne sont pas exportés, et le chargement d'un module nécessitant une le symbole non exporté est refusé. Cette restriction est appliquée au moment de la compilation les entrées manquantes sont signalées.

À des fins de développement, vous pouvez utiliser une version de noyau GKI qui n'inclut pas le découpage des symboles (tous les symboles généralement exportés peuvent alors être utilisés) ; Pour localiser ces builds, recherchez les builds kernel_debug_aarch64 sur ci.android.com

Appliquer le KMI à l'aide de la gestion des versions de module

Les noyaux GKI (Generic Kernel Image) utilisent la gestion des versions de module (CONFIG_MODVERSIONS) comme mesure supplémentaire pour veiller à la conformité avec le KMI de l'environnement d'exécution. La gestion des versions de module peut entraîner une incohérence au niveau du contrôle de redondance cyclique (CRC) au moment du chargement d'un module, si son KMI attendu ne correspond pas vmlinux KMI. Voici un exemple de défaillance typique qui se produit temps de chargement du module en raison d'une non-concordance entre le CRC et le symbole 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 ''

Utilisations de la gestion des versions de module

La gestion des versions de module est utile pour les raisons suivantes:

  • La gestion des versions de module détecte les modifications apportées à la visibilité de la structure des données. Si les modules modifier des structures de données opaques, c'est-à-dire des structures de données qui ne font pas partie KMI, ils ne fonctionnent pas après des modifications futures de la structure.

    À titre d'exemple, prenons fwnode. dans struct device. Ce champ DOIT être opaque pour les modules afin qu'ils ne puissent pas modifier champs de device->fw_node ou faire des hypothèses sur sa taille.

    Toutefois, si un module inclut <linux/fwnode.h> (directement ou indirectement), alors le champ fwnode dans struct device n'est plus opaque. La module peut ensuite modifier device->fwnode->dev ou device->fwnode->ops Ce scénario est problématique pour plusieurs raisons, comme suit:

    • Il peut briser les hypothèses que le code de base fait sur son système interne les structures de données.

    • Si une mise à jour ultérieure du noyau modifie le struct fwnode_handle (les données type de fwnode), cela signifie que le module ne fonctionne plus avec le nouveau noyau. De plus, stgdiff n'affichera aucune différence, car le module ne fonctionnera pas le KMI en manipulant directement les structures de données internes de manière impossible être capturé en inspectant uniquement la représentation binaire.

  • Un module actuel est considéré comme incompatible avec KMI lorsqu'il est chargé à une date ultérieure par un nouveau noyau incompatible. La gestion des versions de module ajoute une vérification de l'exécution éviter de charger accidentellement un module qui n’est pas compatible KMI avec le noyau. Cette vérification permet d'éviter les problèmes d'exécution difficiles à déboguer et les plantages du noyau résulter d'une incompatibilité non détectée dans le KMI.

L'activation de la gestion des versions de module permet d'éviter tous ces problèmes.

Rechercher les incohérences CRC sans démarrer l'appareil

stgdiff compare et signale les incohérences CRC entre les noyaux, ainsi que d'autres Différences entre les ABI.

De plus, une compilation complète du noyau avec CONFIG_MODVERSIONS activé génère Module.symvers dans le cadre du processus de compilation normal. Ce fichier contient un pour chaque symbole exporté par le noyau (vmlinux) et les modules. Chaque composée de la valeur CRC, du nom du symbole, de l'espace de noms du symbole, du caractère vmlinux ou le nom du module exportant le symbole et le type d'exportation (par exemple, EXPORT_SYMBOL contre EXPORT_SYMBOL_GPL).

Vous pouvez comparer les fichiers Module.symvers entre le build GKI et votre build. pour vérifier les différences du CRC dans les symboles exportés par vmlinux. S'il y a est une différence de valeur CRC pour tout symbole exporté par vmlinux et qui est utilisé par l'un des modules que vous chargez sur votre appareil, le module ne de votre application.

Si vous ne disposez pas de tous les artefacts de compilation, mais que vous disposez des fichiers vmlinux de entre le noyau GKI et le noyau, vous pouvez comparer les valeurs CRC pour un type en exécutant la commande suivante sur les deux noyaux et en comparant les sortie:

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

Par exemple, la commande suivante vérifie la valeur CRC pour module_layout symbole:

nm vmlinux | grep __crc_module_layout
0000000008663742 A __crc_module_layout

Résoudre les problèmes de correspondance du CRC

Procédez comme suit pour résoudre une erreur de correspondance CRC lors du chargement d'un module:

  1. Créez le noyau GKI et le noyau de votre appareil à l'aide de --kbuild_symtypes. comme indiqué dans la commande suivante:

    tools/bazel run --kbuild_symtypes //common:kernel_aarch64_dist
    

    Cette commande génère un fichier .symtypes pour chaque fichier .o. Voir KBUILD_SYMTYPES dans Kleaf pour en savoir plus.

    Pour Android 13 et versions antérieures, créez le noyau GKI et le noyau de votre appareil en ajoutant KBUILD_SYMTYPES=1 au début de la commande utiliser pour créer le noyau, comme indiqué dans la commande suivante:

    KBUILD_SYMTYPES=1 BUILD_CONFIG=common/build.config.gki.aarch64 build/build.sh
    

    Lorsque vous utilisez build_abi.sh,, l'option KBUILD_SYMTYPES=1 est implicitement définie. déjà.

  2. Recherchez le fichier .c dans lequel le symbole avec non-concordance CRC est exporté à l'aide de la commande suivante:

    cd common && git grep EXPORT_SYMBOL.*module_layout
    kernel/module.c:EXPORT_SYMBOL(module_layout);
    
  3. Le fichier .c possède un fichier .symtypes correspondant dans GKI, et votre les artefacts de compilation du noyau de l’appareil. Recherchez le fichier .c à l'aide de la commande suivante : commandes:

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

    Voici les caractéristiques du fichier .c:

    • Le format du fichier .c correspond à une ligne (potentiellement très longue) par symbole.

    • [s|u|e|etc]# au début de la ligne signifie que le symbole est de type de données [struct|union|enum|etc] Exemple :

      t#bool typedef _Bool bool
      
    • S'il manque un préfixe # au début de la ligne, cela signifie que le symbole est une fonction. Exemple :

      find_module s#module * find_module ( const char * )
      
  4. Comparez les deux fichiers et corrigez toutes les différences.

Cas 1: différences dues à la visibilité du type de données

Si un noyau maintient un symbole ou un type de données opaque pour les modules et que l'autre ne le fait pas, cette différence apparaît entre les fichiers .symtypes des deux noyaux. Le fichier .symtypes de l'un des noyaux contient UNKNOWN. pour un symbole et le fichier .symtypes de l'autre noyau a une vue développée du symbole ou du type de données.

Par exemple, si vous ajoutez la ligne suivante au include/linux/device.h du noyau provoque des incohérences CRC, dont l'une pour module_layout():

 #include <linux/fwnode.h>

La comparaison de la valeur module.symtypes pour ce symbole révèle les éléments suivants : différences:

 $ 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 ] ; }
  ...

Si votre noyau a la valeur UNKNOWN et que le noyau GKI a la vue développée du symbole (très peu probable), puis fusionnez le tout dernier noyau Android commun dans votre noyau afin d’utiliser la dernière base de noyau GKI.

Dans la plupart des cas, le noyau GKI a la valeur UNKNOWN, mais il a le détails internes du symbole en raison des modifications apportées à votre noyau. C'est car l'un des fichiers de votre noyau a ajouté un #include qui n'est pas présent dans le noyau GKI.

Souvent, la solution consiste simplement à masquer le nouveau #include pour genksyms.

#ifndef __GENKSYMS__
#include <linux/fwnode.h>
#endif

Sinon, pour identifier l'élément #include à l'origine de la différence, procédez comme suit : étapes:

  1. Ouvrez le fichier d'en-tête qui définit le symbole ou le type de données contenant ce la différence. Par exemple, modifiez include/linux/fwnode.h pour struct fwnode_handle

  2. Ajoutez le code suivant en haut du fichier d'en-tête:

    #ifdef CRC_CATCH
    #error "Included from here"
    #endif
    
  3. Dans le fichier .c du module qui présente une incohérence CRC, ajoutez le qui suit comme première ligne avant l'une des lignes #include.

    #define CRC_CATCH 1
    
  4. Compilez votre module. L'erreur qui en résulte au moment de la compilation montre la chaîne fichier d'en-tête #include à l'origine de cette incohérence dans le CRC. Exemple :

    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"
    

    L'un des maillons de cette chaîne de #include est dû à une modification de votre qui manque dans le noyau GKI.

  5. Identifiez la modification, annulez-la dans votre noyau ou l'importer sur ACK et le fusionner.

Cas 2: différences dues à des changements de type de données

Si la non-concordance du CRC pour un symbole ou un type de données n'est pas due à une différence en raison de modifications réelles (ajouts, suppressions ou modifications) le type de données lui-même.

Par exemple, la modification suivante dans votre noyau entraîne plusieurs erreurs CRC car de nombreux symboles sont indirectement affectés par ce type de modification:

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);

Une non-concordance du CRC concerne devm_of_platform_populate().

Si vous comparez les fichiers .symtypes pour ce symbole, cela pourrait ressembler à ceci:

 $ 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 * ) ; ...

Pour identifier le type modifié, procédez comme suit:

  1. Recherchez la définition du symbole dans le code source (généralement dans les fichiers .h).

    • Pour les différences de symboles entre votre noyau et le noyau GKI, Recherchez le commit en exécutant la commande suivante:
    git blame
    
    • Pour les symboles supprimés (lorsqu'un symbole est supprimé de l'arborescence et que vous la supprimer dans l'autre arborescence), vous devez trouver la modification a supprimé la ligne. Exécutez la commande suivante dans l'arborescence où la ligne a été supprimé:
    git log -S "copy paste of deleted line/word" -- <file where it was deleted>
    
  2. Examinez la liste des commits renvoyés pour localiser la modification ou la suppression. La le premier commit est probablement celui que vous recherchez. Si ce n'est pas le cas, allez dans la liste jusqu'à ce que vous trouviez le commit.

  3. Après avoir identifié la modification, annulez-la dans votre noyau ou l'importer sur l'ACK et le récupérer fusionnés.