Suporte ao módulo do kernel

Uma imagem de kernel genérica (GKI) pode não conter o suporte de driver necessário para permitir que um dispositivo monte partições. Para permitir que um dispositivo monte partições e continue inicializando, o init de primeiro estágio é aprimorado para carregar os módulos do kernel presentes em um ramdisk. O ramdisk é dividido em ramdisks genéricos e de fornecedor. Os módulos do kernel do fornecedor são armazenados no ramdisk do fornecedor. A ordem na qual os módulos do kernel são carregados é configurável.

Localização do módulo

O ramdisk é o sistema de arquivos para init, de primeiro estágio e para a imagem de recuperação/fastbootd em dispositivos A/B e A/B virtuais. É um initramfs composto por dois arquivos cpio que são concatenados pelo bootloader. O primeiro arquivo cpio, que é armazenado como o ramdisk do fornecedor na partição de inicialização do fornecedor, contém estes componentes:

  • Módulos de kernel do fornecedor init de primeiro estágio, localizados em /lib/modules/ .
  • arquivos de configuração modprobe , localizados em /lib/modules/ : modules.dep , modules.softdep , modules.alias , modules.options .
  • Um arquivo modules.load que indica quais módulos devem ser carregados durante a inicialização do primeiro estágio e em qual ordem, em /lib/modules/ .
  • Módulos de kernel de recuperação do fornecedor, para dispositivos A/B e Virtual A/B, em /lib/modules/
  • modules.load.recovery que indica os módulos a serem carregados e em qual ordem, para dispositivos A/B e Virtual A/B, em /lib/modules .

O segundo arquivo cpio, que é fornecido com o GKI como o ramdisk do boot.img e aplicado sobre o primeiro, contém first_stage_init e as bibliotecas das quais ele depende.

Carregamento do módulo no init de primeiro estágio

O init de primeiro estágio começa lendo os arquivos de configuração do modprobe de /lib/modules/ no ramdisk. Em seguida, ele lê a lista de módulos especificados em /lib/modules/modules.load (ou no caso de recuperação, /lib/modules/modules.load.recovery ) e tenta carregar cada um desses módulos em ordem, seguindo o configuração especificada nos arquivos carregados anteriormente. O pedido solicitado pode ser desviado para satisfazer dependências físicas ou flexíveis.

Suporte de construção, inicialização de primeiro estágio

Para especificar os módulos do kernel a serem copiados no cpio do ramdisk do fornecedor, liste-os em BOARD_VENDOR_RAMDISK_KERNEL_MODULES . A compilação executa o depmod nesses módulos e coloca os arquivos de configuração modprobe resultantes no cpio ramdisk do fornecedor.

A compilação também cria um arquivo modules.load e o armazena no cpio ramdisk do fornecedor. Por padrão, ele contém todos os módulos listados em BOARD_VENDOR_RAMDISK_KERNEL_MODULES . Para substituir o conteúdo desse arquivo, use BOARD_VENDOR_RAMDISK_KERNEL_MODULES_LOAD , conforme mostrado neste exemplo:

BOARD_VENDOR_RAMDISK_KERNEL_MODULES_LOAD := \
    device/vendor/mydevice-kernel/first.ko \
    device/vendor/mydevice-kernel/second.ko \
    device/vendor/mydevice-kernel/third.ko

Suporte de compilação, Android completo

Como é o caso do Android 10 e versões anteriores, os módulos do kernel listados em BOARD_VENDOR_KERNEL_MODULES são copiados pela plataforma Android compilada na partição do fornecedor em /vendor/lib/modules . A compilação da plataforma executa o depmod nesses módulos e copia os arquivos de saída do depmod na partição do fornecedor no mesmo local. O mecanismo para carregar módulos do kernel de /vendor permanece o mesmo de versões anteriores do Android. É sua decisão como e quando carregar esses módulos, embora normalmente isso seja feito usando scripts init.rc

Curingas e compilações de kernel integradas

Os fornecedores que combinam a compilação do kernel do dispositivo com a compilação da plataforma Android podem ter problemas ao usar as macros BOARD mencionadas acima para especificar os módulos do kernel a serem copiados para o dispositivo. Se o fornecedor quiser evitar listar os módulos do kernel nos arquivos de compilação da plataforma do dispositivo, eles podem usar um curinga ( $(wildcard device/vendor/mydevice/*.ko ). Observe que o curinga não funciona no caso de um integrado kernel build, porque quando make é invocado e as macros são expandidas em makefiles, os módulos do kernel não foram compilados, então as macros estão vazias.

Para contornar esse problema, o fornecedor pode fazer com que sua compilação do kernel crie um arquivo zip contendo os módulos do kernel a serem copiados em cada partição. Defina o caminho desse arquivo zip em BOARD_*_KERNEL_MODULES_ARCHIVE onde * é o nome da partição (como BOARD_VENDOR_KERNEL_MODULES_ARCHIVE ). A compilação da plataforma Android extrai esse arquivo zip para o local apropriado e executa o depmod nos módulos.

O arquivo zip do módulo do kernel deve ter uma regra make que garanta que a compilação da plataforma possa gerar o arquivo quando necessário.

Recuperação

Em versões anteriores do Android, os módulos de kernel necessários para recuperação eram especificados em BOARD_RECOVERY_KERNEL_MODULES . No Android 11, os módulos do kernel necessários para recuperação ainda são especificados usando essa macro. No entanto, os módulos do kernel de recuperação são copiados para o ramdisk cpio do fornecedor, em vez do ramdisk cpio genérico. Por padrão, todos os módulos do kernel listados em BOARD_RECOVERY_KERNEL_MODULES são carregados durante a init do primeiro estágio. Se você deseja que apenas um subconjunto desses módulos seja carregado, especifique o conteúdo desse subconjunto em BOARD_RECOVERY_KERNEL_MODULES_LOAD .

Para saber como criar uma partição de inicialização do fornecedor (que contém o disco ram do fornecedor mencionado nesta página), consulte Partições de inicialização .