Como parte dos requisitos do kernel do módulo introduzidos no Android 8.0, todos os kernels do sistema-em-chip (SoC) precisam oferecer suporte a módulos de kernel carregáveis.
Opções de configuração do kernel
Para oferecer suporte a módulos de kernel carregáveis, android-base.config em todos os kernels comuns inclui as seguintes opções de kernel-config (ou equivalentes da versão do kernel):
CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_MODVERSIONS=y
Todos os kernels do dispositivo precisam ativar essas opções. Os módulos do kernel também precisam oferecer suporte ao descarregamento e à recarga sempre que possível.
Assinatura de módulo
  A assinatura de módulo não é compatível com módulos de fornecedores do GKI. Em dispositivos que precisam
  oferecer suporte à inicialização verificada, o Android exige que os módulos do kernel estejam nas partições
  com o dm-verity ativado. Isso elimina a necessidade de assinar módulos
  individuais para verificar a autenticidade deles.
  O Android 13 introduziu o conceito de módulos de GKI. Os módulos do GKI usam a infraestrutura de assinatura do tempo de build
  do kernel para diferenciar o GKI de outros módulos no momento da execução.
  Os módulos não assinados podem ser carregados, desde que usem apenas símbolos que aparecem na lista de permissões
  ou fornecidos por outros módulos não assinados.
  Para facilitar a assinatura de módulos do GKI durante o build do GKI usando o par de chaves do kernel,
  a configuração do kernel do GKI ativou CONFIG_MODULE_SIG_ALL=y.
  Para evitar a assinatura de módulos que não são GKI durante builds do kernel do dispositivo, adicione
  # CONFIG_MODULE_SIG_ALL is not set como parte dos fragmentos
  de configuração do kernel.
Locais de arquivos
  Embora o Android 7.x e versões anteriores não exijam módulos do kernel (e incluam
  suporte a insmod e rmmod), o Android 8.x e
  versões mais recentes recomendam o uso de módulos do kernel no ecossistema. A tabela a seguir
  mostra o possível suporte a periféricos específicos da placa necessário em três
  modos de inicialização do Android.
| Modo de inicialização | Armazenamento | Tela | Teclado | Bateria | PMIC | Tela touchscreen | NFC, Wi-Fi, Bluetooth | Sensores | Câmera | 
|---|---|---|---|---|---|---|---|---|---|
| Recuperação | |||||||||
| Carregador | |||||||||
| Android | 
Além da disponibilidade nos modos de inicialização do Android, os módulos do kernel também podem ser categorizados por quem os possui (o fornecedor do SoC ou o ODM). Se módulos do kernel estiverem sendo usados, os requisitos para a colocação deles no sistema de arquivos são os seguintes:
- Todos os kernels precisam ter suporte integrado para inicialização e montagem de partições.
- Os módulos do kernel precisam ser carregados de uma partição somente leitura.
- Para dispositivos que precisam ter inicialização verificada, os módulos do kernel precisam ser carregados de partições verificadas.
- Os módulos do kernel não podem estar localizados em /system.
- Os módulos GKI necessários para o dispositivo precisam ser carregados de
  /system/lib/modules, que é um link simbólico para/system_dlkm/lib/modules.
- Os módulos do kernel do fornecedor do SoC que são necessários para o Android completo ou
  os modos de carregador precisam estar localizados em /vendor/lib/modules.
- Se uma partição ODM existir, os módulos do kernel do ODM que forem necessários
  para os modos Android completo ou carregador precisam estar localizados em
  /odm/lib/modules. Caso contrário, esses módulos precisam estar localizados em/vendor/lib/modules.
- Os módulos do kernel do fornecedor do SoC e do ODM que são necessários para o modo
  de recuperação precisam estar localizados no ramfsde recuperação em/lib/modules.
- Os módulos do kernel necessários para o modo de recuperação e os modos de carregador ou
  Android completo precisam existir na rootfsde recuperação e nas partições/vendorou/odm(conforme descrito acima).
- Os módulos do kernel usados no modo de recuperação não podem depender de módulos localizados
  apenas em /vendorou/odm, porque essas partições não são montadas no modo de recuperação.
- Os módulos do kernel do fornecedor do SoC não podem depender dos módulos do kernel do ODM.
  No Android 7.x e versões anteriores, as partições /vendor e /odm
  não são montadas antecipadamente. No Android 8.x e versões mais recentes,
  para tornar possível o carregamento de módulos dessas partições, foram feitas
  provisões para montar partições com antecedência para
  dispositivos não A/B e A/B. Isso também
  garante que as partições sejam montadas nos modos Android e Carregador.
Suporte ao sistema de build do Android
  No BoardConfig.mk, o build do Android define uma
  variável BOARD_VENDOR_KERNEL_MODULES que fornece uma lista completa
  dos módulos do kernel destinados à imagem do fornecedor. Os módulos listados nesta variável são copiados para a imagem do fornecedor em /lib/modules/ e, depois de serem montados no Android, aparecem em /vendor/lib/modules (de acordo com os requisitos acima).
  Exemplo de configuração dos módulos do kernel do fornecedor:
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
Neste exemplo, um repositório pré-criado de módulo do kernel do fornecedor é mapeado para o build do Android no local listado acima.
  A imagem de recuperação pode conter um subconjunto dos módulos do fornecedor. O build do
  Android define a variável BOARD_RECOVERY_KERNEL_MODULES para
  esses módulos. Exemplo:
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
  O build do Android cuida da execução de depmod para gerar os
  arquivos modules.dep necessários em /vendor/lib/modules
  e /lib/modules (recovery ramfs).
Carregamento e controle de versão do módulo
  Carregue todos os módulos do kernel em uma única passagem de init.rc* chamando
  modprobe -a. Isso evita a sobrecarga de inicialização repetida
  do ambiente de execução C para o binário modprobe. O
  evento early-init pode ser modificado para invocar modprobe:
on early-init
    exec u:r:vendor_modprobe:s0 -- /vendor/bin/modprobe -a -d \
        /vendor/lib/modules module_a module_b module_c ...
  Normalmente, um módulo do kernel precisa ser compilado com o kernel que o módulo
  será usado. Caso contrário, o kernel se recusa a carregar o módulo.
  O CONFIG_MODVERSIONS oferece uma solução alternativa detectando falhas
  na interface binária do aplicativo (ABI). Esse recurso calcula um valor de verificação
  de redundância cíclica (CRC, na sigla em inglês) para o protótipo de cada símbolo exportado no
  kernel e armazena os valores como parte dele. Para símbolos usados por um
  módulo do kernel, os valores também são armazenados no módulo do kernel. Quando o
  módulo é carregado, os valores dos símbolos usados pelo módulo são comparados
  com os do kernel. Se os valores corresponderem, o módulo será carregado.
  Caso contrário, a carga falhará.
  Para ativar a atualização da imagem do kernel separadamente da imagem do fornecedor,
  ative CONFIG_MODVERSIONS. Isso permite pequenas atualizações do
  kernel (como correções de bugs do LTS) mantendo a compatibilidade
  com os módulos de kernel existentes na imagem do fornecedor. No entanto,
  CONFIG_MODVERSIONS não corrige uma interrupção de ABI por conta própria. Se o
  protótipo de um símbolo exportado no kernel mudar, seja devido
  à modificação da origem ou porque a configuração do kernel mudou, isso
  vai interromper a compatibilidade com os módulos do kernel que usam esse símbolo. Nesses casos,
  o módulo do kernel precisa ser recompilado.
  Por exemplo, a estrutura task_struct no kernel (definida em
  include/linux/sched.h) contém muitos campos incluídos condicionalmente
  dependendo da configuração do kernel. O campo sched_info
  só está presente se CONFIG_SCHED_INFO estiver ativado, o que
  ocorre quando CONFIG_SCHEDSTATS ou
  CONFIG_TASK_DELAY_ACCT estão ativados. Se essas opções de configuração
  mudarem de estado, o layout da estrutura task_struct
  vai mudar, e todas as interfaces exportadas do kernel que usam
  task_struct serão alteradas (por exemplo,
  set_cpus_allowed_ptr em kernel/sched/core.c).
  A compatibilidade com módulos de kernel compilados anteriormente que usam essas
  interfaces é interrompida, exigindo que esses módulos sejam recriados com a nova configuração
  do kernel.
  Para mais detalhes sobre CONFIG_MODVERSIONS, consulte a
  documentação na árvore do kernel em
  Documentation/kbuild/modules.rst.
