Módulos do kernel carregáveis

Como parte dos requisitos do kernel do módulo introduzidos no Android 8.0, todos Os kernels system on 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 do kernel carregáveis, android-base.config em todos os kernels comuns inclui o as seguintes opções do kernel-config (ou a versão equivalente 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 são compatíveis com descarregamento e recarregamento sempre que possível.

Assinatura do módulo

A assinatura de módulo não tem suporte para módulos de fornecedores de GKI. Nos dispositivos em que 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 em busca de autenticidade. O Android 13 introduziu o conceito de módulos GKI. Os módulos GKI usam o tempo de build do kernel infraestrutura de assinatura para diferenciar a GKI de outros módulos no ambiente de execução. Módulos não assinados podem ser carregados desde que usem apenas símbolos que apareçam na lista de permissões ou fornecidos por outros módulos não assinados. Para facilitar a assinatura de módulos de GKI durante o build de GKI usando o par de chaves de tempo de build do kernel, A configuração do kernel de GKI ativou CONFIG_MODULE_SIG_ALL=y. Para evitar assinar módulos não GKI durante builds do kernel do dispositivo, você precisa adicionar # CONFIG_MODULE_SIG_ALL is not set como parte da configuração do kernel fragmentos

Locais dos arquivos

Enquanto o Android 7.x e versões anteriores não exigem módulos do kernel (e incluem suporte a insmod e rmmod), Android 8.x e maiores recomendam o uso de módulos do kernel no ecossistema. O seguinte a tabela 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 é o proprietário deles (o fornecedor de SoC ou o ODM). Se os módulos do kernel estão sendo usados, os requisitos para sua colocação no sistema de arquivos são da seguinte forma:

  • Todos os kernels devem ter suporte integrado para inicialização e montagem partições diferentes.
  • 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 devem 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 /system/lib/modules, que é um link simbólico para /system_dlkm/lib/modules.
  • Módulos de kernel do fornecedor de SoC necessários para versões completas de Android ou Os modos do carregador precisam estar localizados em /vendor/lib/modules.
  • Se houver uma partição ODM, os módulos do kernel do ODM que são necessários para os modos Android ou Charger completos devem estar localizados em /odm/lib/modules: Caso contrário, esses módulos devem estar localizados em /vendor/lib/modules:
  • Módulos do kernel do fornecedor de SoC e ODM necessários para recuperação deve estar localizado no ramfs de recuperação em /lib/modules.
  • Módulos de kernel necessários para o modo de recuperação e para o Android ou Os modos do carregador precisam existir nos campos rootfs e as partições /vendor ou /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 /vendor ou /odm, porque essas partições não estão ativado no modo de recuperação.
  • Os módulos de kernel do fornecedor de SoC não podem depender de módulos do kernel ODM.

No Android 7.x e versões anteriores, /vendor e /odm as partições não são montadas antecipadamente. No Android 8.x e mais recentes, para possibilitar o carregamento de módulos com essas partições, as provisões foram para montar partições antecipadamente para ambos dispositivos que não são A/B e A/B. Isso também garante que as partições sejam montadas nos modos Android e Charger.

Suporte ao sistema de build do Android

Em BoardConfig.mk, o build do Android define uma A variável BOARD_VENDOR_KERNEL_MODULES que fornece uma lista completa dos módulos do kernel destinados à imagem do fornecedor. Os módulos listados nos essa variável são copiadas na imagem do fornecedor em /lib/modules/, e, depois de ser montado no Android, aparecem /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 do módulo de 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 Android build define a variável BOARD_RECOVERY_KERNEL_MODULES para nestes 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 executa o depmod para gerar o modules.dep arquivos necessários em /vendor/lib/modules e /lib/modules (recovery ramfs).

Carregamento de módulo e controle de versões

Carregue todos os módulos do kernel em uma passagem de init.rc* invocando modprobe -a. Isso evita a sobrecarga de inicializar repetidamente o ambiente de execução C para o binário modprobe. A 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 com o qual o módulo está. pelo uso (caso contrário, o kernel se recusará a carregar o módulo). O CONFIG_MODVERSIONS oferece uma solução alternativa ao detectar falhas na interface binária do aplicativo (ABI). Esse recurso calcula um ciclo de verificação de redundância (CRC) para o protótipo de cada símbolo exportado na kernel e armazena os valores como parte do kernel; para símbolos usados por um módulo do kernel, os valores também são armazenados no módulo do kernel. Quando o é 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, o carregamento falhará.

Para ativar a atualização da imagem do kernel separadamente da imagem do fornecedor, ativar CONFIG_MODVERSIONS. Isso permite pequenas atualizações no (como correções de bug do LTS) a serem feitas, mantendo a compatibilidade com os módulos do kernel na imagem do fornecedor. No entanto, O CONFIG_MODVERSIONS não corrige uma falha de ABI por si só. Se o o protótipo de um símbolo exportado nas mudanças do kernel, seja devido a da origem ou porque a configuração do kernel mudou, isso quebra a compatibilidade com 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 condicionalmente incluído, dependendo da configuração do kernel. O sched_info só estará presente se CONFIG_SCHED_INFO estiver ativado (que ocorre quando CONFIG_SCHEDSTATS ou CONFIG_TASK_DELAY_ACCT estão ativados). Se essas configurações as opções mudam de estado, o layout da estrutura task_struct alterações e quaisquer interfaces exportadas do kernel que usam task_struct forem alterados (por exemplo, set_cpus_allowed_ptr em kernel/sched/core.c). Compatibilidade com módulos de kernel compilados anteriormente que usam essas interface falha, exigindo que esses módulos sejam reconstruídos com o novo kernel configuração do Terraform.

Para mais detalhes sobre CONFIG_MODVERSIONS, consulte a na árvore de kernel em Documentation/kbuild/modules.rst.