Moduli kernel caricabili

Come parte dei requisiti del kernel del modulo introdotti in Android 8.0, i kernel system-on-chip (SoC) devono supportare moduli kernel caricabili.

Opzioni di configurazione del kernel

Per supportare i moduli kernel caricabili, android-base.config in tutti i kernel comuni include la classe seguenti opzioni kernel-config (o l'equivalente della loro versione kernel):

CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODVERSIONS=y

Tutti i kernel del dispositivo devono abilitare queste opzioni. I moduli del kernel devono inoltre supportano lo scarico e il ricaricamento quando possibile.

Firma del modulo

La firma del modulo non è supportata per i moduli del fornitore GKI. Sui dispositivi necessari per supportare l'avvio verificato, Android richiede che i moduli kernel siano nelle partizioni con la verifica dm-verity abilitata. In questo modo non è più necessario firmare i singoli utenti i moduli per la loro autenticità. Android 13 ha introdotto il concetto di moduli GKI. I moduli GKI utilizzano il tempo di build del kernel di firma per distinguere tra GKI e altri moduli in fase di esecuzione. I moduli non firmati possono essere caricati purché utilizzino solo i simboli presenti nella lista consentita o forniti da altri moduli non firmati. Per facilitare la firma dei moduli GKI durante la build GKI utilizzando la coppia di chiavi per il tempo di creazione del kernel, La configurazione del kernel GKI ha abilitato CONFIG_MODULE_SIG_ALL=y. Per evitare di firmare moduli non GKI durante le build del kernel del dispositivo, devi aggiungere # CONFIG_MODULE_SIG_ALL is not set come parte della configurazione del kernel di grandi dimensioni.

Posizioni dei file

Sebbene Android 7.x e versioni precedenti non richiedano l'uso di moduli kernel (e includono supporto per insmod e rmmod), Android 8.x e di usare i moduli kernel nell'ecosistema. Le seguenti mostra il potenziale supporto periferico specifico della scheda richiesto in tre Modalità di avvio di Android.

Modalità di avvio Spazio di archiviazione Display Tastierino Batteria PMIC Touchscreen NFC, Wi-Fi,
Bluetooth
Sensori Fotocamera
Ripristino
Caricabatterie
Android

Oltre alla disponibilità nelle modalità di avvio di Android, i moduli kernel possono essere classificati in base a chi li possiede (il fornitore di SoC o l'ODM). Se i moduli kernel i requisiti per il posizionamento nel file system sono i seguenti che segue:

  • Tutti i kernel devono avere il supporto integrato per l'avvio e il montaggio partizioni di Compute Engine.
  • I moduli del kernel devono essere caricati da una partizione di sola lettura.
  • Per i dispositivi per cui è necessario l'avvio verificato, i moduli kernel devono essere caricato da partizioni verificate.
  • I moduli del kernel non devono trovarsi in /system.
  • I moduli GKI richiesti per il dispositivo devono essere caricati da /system/lib/modules, che è un link simbolico a /system_dlkm/lib/modules.
  • Moduli del kernel del fornitore di SoC richiesti per le versioni complete Le modalità di ricarica devono essere disponibili in /vendor/lib/modules.
  • Se esiste una partizione ODM, i moduli kernel dell'ODM che sono richiesti per la modalità completa di Android o del caricabatterie deve essere disponibile in /odm/lib/modules. In caso contrario, questi moduli dovrebbero trovarsi in /vendor/lib/modules.
  • Moduli del kernel del fornitore di SoC e ODM che sono richiesti per il ripristino deve trovarsi nel ramfs di ripristino all'indirizzo /lib/modules.
  • Moduli del kernel richiesti sia per la modalità Recovery sia per le versioni Android o Le modalità del caricabatterie devono esistere sia nell'rootfs di ripristino che la partizione /vendor o /odm (come descritto sopra).
  • I moduli del kernel utilizzati in modalità di ripristino non devono dipendere dai moduli situati solo in /vendor o /odm, poiché queste partizioni non sono montato in Recovery mode.
  • I moduli kernel del fornitore SoC non devono dipendere dai moduli kernel ODM.

In Android 7.x e versioni precedenti, /vendor e /odm le partizioni non vengono montate in anticipo. In Android 8.x e versioni successive, per rendere possibile il caricamento dei moduli da queste partizioni, sono state per montare in anticipo le partizioni dispositivi non A/B e A/B. Anche questo assicura che le partizioni siano montate sia in modalità Android che in modalità caricabatterie.

Supporto del sistema di build Android

In BoardConfig.mk, la build Android definisce Variabile BOARD_VENDOR_KERNEL_MODULES che fornisce un elenco completo dei moduli kernel destinati all'immagine del fornitore. I moduli elencati in questa variabile viene copiata nell'immagine del fornitore in /lib/modules/, e, dopo essere stato montato in Android, appaiono in /vendor/lib/modules (in conformità ai requisiti di cui sopra). Configurazione di esempio dei moduli kernel del fornitore:

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

In questo esempio, un repository predefinito per i moduli kernel del fornitore è mappato la build Android nella posizione indicata sopra.

L'immagine di ripristino può contenere un sottoinsieme dei moduli del fornitore. Android nella build definisce la variabile BOARD_RECOVERY_KERNEL_MODULES questi moduli. Esempio:

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

La build Android si occupa di eseguire depmod per generare modules.dep file richiesti in /vendor/lib/modules e /lib/modules (recovery ramfs).

Caricamento del modulo e controllo delle versioni

Carica tutti i moduli kernel in un passaggio da init.rc* richiamando modprobe -a. In questo modo si evita l'overhead associato all'inizializzazione ripetuta nell'ambiente di runtime C per il programma binario modprobe. La L'evento early-init può essere modificato per richiamare modprobe:

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

In genere, un modulo kernel deve essere compilato con il kernel che usato (altrimenti il kernel si rifiuta di caricare il modulo). CONFIG_MODVERSIONS offre una soluzione alternativa rilevando i malfunzionamenti nell'Application Bin Interface (ABI). Questa caratteristica calcola una del controllo di ridondanza (CRC) per il prototipo di ciascun simbolo esportato nel il kernel e archivia i valori come parte del kernel; per i simboli utilizzati modulo kernel, i valori sono archiviati anche nel modulo kernel. Quando modulo viene caricato, i valori dei simboli utilizzati dal modulo vengono confrontati a quelli nel kernel. Se i valori corrispondono, il modulo viene caricato; altrimenti il caricamento non riesce.

Per abilitare l'aggiornamento dell'immagine del kernel separatamente dall'immagine del fornitore, abilita CONFIG_MODVERSIONS. In questo modo è possibile apportare piccoli aggiornamenti (come le correzioni di bug di LTS) mantenendo la compatibilità con i moduli kernel esistenti nell'immagine del fornitore. Tuttavia, CONFIG_MODVERSIONS non risolve autonomamente un'interruzione dell'ABI. Se un prototipo di un simbolo esportato nelle modifiche del kernel, a causa del codice sorgente o a causa della modifica della configurazione del kernel, interrompe la compatibilità con i moduli kernel che utilizzano quel simbolo. In questi casi, il modulo kernel deve essere ricompilato.

Ad esempio, la struttura task_struct nel kernel (definita in include/linux/sched.h) contiene molti campi in modo condizionale a seconda della configurazione del kernel. sched_info è presente solo se CONFIG_SCHED_INFO è abilitato (che si verifica quando CONFIG_SCHEDSTATS o CONFIG_TASK_DELAY_ACCT abilitati). Se queste configurazioni opzioni cambiano stato, il layout della struttura task_struct modifiche ed eventuali interfacce esportate dal kernel che usano task_struct è stato modificato (ad esempio, set_cpus_allowed_ptr a kernel/sched/core.c). Compatibilità con i moduli kernel compilati in precedenza che utilizzano questi si interrompono, richiedendo che questi moduli vengano ricreati con il nuovo kernel configurazione.

Per maggiori dettagli su CONFIG_MODVERSIONS, consulta le documentazione nella struttura del kernel Documentation/kbuild/modules.rst.