Modules du noyau chargeables

Dans le cadre des exigences de noyau du module introduites dans Android 8.0, toutes Les noyaux système sur puce (SoC) doivent prendre en charge les modules de noyau chargeables.

Options de configuration du noyau

Pour prendre en charge les modules de noyau chargeables, android-base.config dans tous les noyaux courants inclut le les options kernel-config suivantes (ou leur équivalent en version kernel):

CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODVERSIONS=y

Tous les noyaux de l'appareil doivent activer ces options. Les modules kernel doivent également prennent en charge le déchargement et l'actualisation dans la mesure du possible.

Signature de module

La signature de module n'est pas prise en charge pour les modules de fournisseurs GKI. Sur les appareils requis pour prend en charge le démarrage validé, Android exige que les modules du noyau se trouvent dans les partitions pour lesquelles dm-verity est activé. Ainsi, il n'est plus nécessaire de signer modules pour vérifier leur authenticité. Android 13 a introduit le concept des modules GKI. Les modules GKI utilisent la durée de compilation pour différencier GKI des autres modules au moment de l'exécution. Les modules non signés sont autorisés à se charger s'ils n'utilisent que des symboles figurant sur la liste d'autorisation ou fournis par d'autres modules non signés. Pour faciliter la signature des modules GKI lors de la compilation GKI à l'aide de la paire de clés de temps de compilation du noyau, La configuration du noyau GKI a activé CONFIG_MODULE_SIG_ALL=y. Pour éviter de signer des modules non-GKI pendant les compilations du noyau de l'appareil, vous devez ajouter # CONFIG_MODULE_SIG_ALL is not set dans votre configuration de noyau Fragments.

Emplacements des fichiers

Même si Android 7.x et ses versions antérieures n'exigent pas l'utilisation des modules du noyau (et incluent compatible avec insmod et rmmod), Android 8.x et recommandent davantage l'utilisation des modules du noyau dans l'écosystème. Les éléments suivants : le tableau montre la compatibilité potentielle des périphériques spécifiques aux cartes requises sur trois Modes de démarrage Android

Mode de démarrage Stockage Écran Clavier Batterie PMIC Écran tactile NFC, Wi-Fi,
Bluetooth
Capteurs Appareil photo
Récupération
Chargeur
Android

Outre la disponibilité dans les modes de démarrage Android, les modules du noyau peuvent être par propriétaire (fournisseur SoC ou ODM). Si les modules du noyau sont utilisées, les exigences liées à leur placement dans le système de fichiers sont ce qui suit:

  • Tous les noyaux doivent disposer d'une prise en charge intégrée du démarrage et de l'installation des partitions.
  • Les modules kernel doivent être chargés depuis une partition en lecture seule.
  • Pour les appareils dont le démarrage validé est requis, les modules du noyau doivent être chargées à partir de partitions validées.
  • Les modules du kernel ne doivent pas se trouver dans /system.
  • Les modules GKI requis pour l'appareil doivent être chargés depuis /system/lib/modules, qui est un lien symbolique vers /system_dlkm/lib/modules
  • Modules du noyau du fournisseur SoC requis pour le fonctionnement complet d'Android ou Les modes de chargement doivent être en /vendor/lib/modules.
  • Si une partition ODM existe, les modules de noyau de l'ODM qui sont requis pour le mode Android ou Chargeur complet doit se trouver /odm/lib/modules Sinon, ces modules doivent se trouver dans /vendor/lib/modules
  • Modules du noyau du fournisseur SoC et ODM requis pour la récupération doit se trouver dans le ramfs de récupération /lib/modules
  • Modules du kernel requis pour le mode Recovery et la version complète d'Android, ou Les modes chargeur doivent être présents à la fois dans le rootfs de récupération et dans les partitions /vendor ou /odm (comme décrit ci-dessus).
  • Les modules kernel utilisés en mode Recovery ne doivent pas dépendre de modules situés que dans /vendor ou /odm, car ces partitions monté en mode Recovery.
  • Les modules de noyau des fournisseurs SoC ne doivent pas dépendre des modules du noyau ODM.

Sous Android 7.x et versions antérieures, /vendor et /odm les partitions ne sont pas installées en amont. Sur Android 8.x et versions ultérieures, pour permettre le chargement des modules à partir de ces partitions, pour monter des partitions en avance pour les deux appareils non-A/B et A/B De plus, garantit que les partitions sont installées en mode Android et en mode Chargeur.

Compatibilité avec le système de compilation Android

Dans BoardConfig.mk, le build Android définit Variable BOARD_VENDOR_KERNEL_MODULES fournissant une liste complète des modules du noyau destinés à l'image du fournisseur. Les modules répertoriés dans cette variable sont copiées dans l'image du fournisseur à l'emplacement /lib/modules/, et, une fois installés sur Android, /vendor/lib/modules (conformément aux exigences ci-dessus). Exemple de configuration des modules de noyau du fournisseur:

vendor_lkm_dir := device/$(vendor)/lkm-4.x
BOARD_VENDOR_KERNEL_MODULES := \
  $(vendor_lkm_dir)/vendor_module_a.ko \
  $(vendor_lkm_dir)/vendor_module_b.ko \
  $(vendor_lkm_dir)/vendor_module_c.ko

Dans cet exemple, un référentiel prédéfini du module de noyau du fournisseur est mappé le build Android à l'emplacement indiqué ci-dessus.

L'image de récupération peut contenir un sous-ensemble des modules du fournisseur. Android La compilation définit la variable BOARD_RECOVERY_KERNEL_MODULES pour ces modules. Exemple :

vendor_lkm_dir := device/$(vendor)/lkm-4.x
BOARD_RECOVERY_KERNEL_MODULES := \
  $(vendor_lkm_dir)/vendor_module_a.ko \
  $(vendor_lkm_dir)/vendor_module_b.ko

Le build Android se charge d'exécuter depmod pour générer fichiers modules.dep requis dans /vendor/lib/modules et /lib/modules (recovery ramfs).

Chargement de modules et gestion des versions

Chargez tous les modules du noyau en une seule fois depuis init.rc* en appelant la méthode modprobe -a Cela évite d'avoir à s'initialiser à plusieurs reprises l'environnement d'exécution C pour le binaire modprobe. La Vous pouvez modifier l'événement early-init pour appeler modprobe:

on early-init
    exec u:r:vendor_modprobe:s0 -- /vendor/bin/modprobe -a -d \
        /vendor/lib/modules module_a module_b module_c ...

En général, un module de noyau doit être compilé avec le noyau sur lequel le module est (sinon le noyau refuse de charger le module). CONFIG_MODVERSIONS fournit une solution de contournement en détectant les défaillances. dans l'interface binaire de l'application (ABI). Cette caractéristique calcule une valeur du contrôle de redondance (CRC) pour le prototype de chaque symbole exporté dans le et stocke les valeurs dans le noyau ; pour les symboles utilisés par module du noyau, les valeurs sont également stockées dans le module du noyau. Lorsque module est chargé, les valeurs des symboles qu'il utilise sont comparées avec ceux du noyau. Si les valeurs correspondent, le module est chargé : sinon le chargement échoue.

Pour permettre la mise à jour de l'image du noyau séparément de l'image du fournisseur, activer CONFIG_MODVERSIONS. Cela permet de petites mises à jour noyau (comme les corrections de bugs de LTS) à effectuer tout en maintenant la compatibilité avec les modules de noyau existants dans l'image du fournisseur. Toutefois, CONFIG_MODVERSIONS ne corrige pas une faille de l'ABI en soi. Si le d'un symbole exporté dans le noyau change, soit en raison modification de la source ou parce que la configuration du noyau a changé, ce rompt la compatibilité avec les modules du noyau qui utilisent ce symbole. Dans ce cas, le module du noyau doit être recompilé.

Par exemple, la structure task_struct dans le noyau (définie dans include/linux/sched.h) contient de nombreux champs sous condition. en fonction de la configuration du noyau. sched_info n'est présent que si CONFIG_SCHED_INFO est activé (ce qui se produit lorsque CONFIG_SCHEDSTATS ou CONFIG_TASK_DELAY_ACCT sont activées). Si ces configurations les options changent d'état, la mise en page de la structure task_struct modifications et toute interface exportée du noyau qui utilise task_struct ont été modifiés (par exemple, set_cpus_allowed_ptr dans kernel/sched/core.c). Compatibilité avec les modules de noyau compilés précédemment qui utilisent ces interfaces tombent en panne, ce qui nécessite de recompiler ces modules avec le nouveau noyau configuration.

Pour en savoir plus sur CONFIG_MODVERSIONS, consultez les dans l'arborescence du noyau Documentation/kbuild/modules.rst