Uma imagem genérica de kernel (GKI, na sigla em inglês) pode não conter o suporte necessário ao driver para
permitir que um dispositivo ative partições. Para permitir que um dispositivo ative partições e
continue a inicialização, o init
de primeiro estágio é aprimorado para carregar os
módulos do kernel presentes em um ramdisk. O ramdisk é dividido em genéricos e
de fornecedores. Os módulos de kernel do fornecedor são armazenados no ramdisk do fornecedor. A
ordem em que os módulos do kernel são carregados é configurável.
Local do módulo
O ramdisk é o sistema de arquivos do init,
de primeiro estágio e da
imagem de recuperação/fastbootd em dispositivos A/B e A/B virtuais. Ele é um
initramfs
composto por dois arquivos cpio que são concatenados pelo
carregador de inicialização. 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 serão carregados durante a inicialização do primeiro estágio e em que ordem, em/lib/modules/
. - Módulos de kernel de recuperação do fornecedor, para dispositivos A/B e A/B virtuais, em
/lib/modules/
modules.load.recovery
, que indica os módulos a serem carregados e em qual ordem, para dispositivos A/B e A/B virtuais, em/lib/modules
.
O segundo arquivo cpio, fornecido com a GKI
como o ramdisk do boot.img e aplicado sobre o
primeiro, contém first_stage_init
e as bibliotecas de que ele depende.
Carregamento de módulo no init de primeiro estágio
O init
de primeiro estágio começa lendo os arquivos de configuração
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 a configuração especificada nos
arquivos carregados anteriormente. A ordem solicitada pode ser desviada para
satisfazer dependências rígidas ou flexíveis.
Suporte a build, init de primeiro estágio
Para especificar os módulos do kernel a serem copiados para o cpio do ramdisk do fornecedor, liste
eles em BOARD_VENDOR_RAMDISK_KERNEL_MODULES
. O build executa
depmod
nesses módulos e coloca os arquivos de configuração modprobe resultantes
no cpio do ramdisk do fornecedor.
O build também cria um arquivo modules.load
e o armazena no
cpio do 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 build, Android completo
Como acontece no Android 10 e nas versões anteriores, os módulos do kernel listados em
BOARD_VENDOR_KERNEL_MODULES
são copiados pelo build da plataforma Android
na partição do fornecedor em /vendor/lib/modules
. O
build da plataforma executa depmod
nesses módulos e copia os
arquivos de saída depmod
na partição do fornecedor no mesmo
local. O mecanismo para carregar módulos do kernel do /vendor
permanece o mesmo das versões anteriores do Android. Cabe a você decidir como e quando carregar esses módulos, embora isso geralmente seja feito usando scripts init.rc
.
Caracteres curinga e builds de kernel integrados
Os fornecedores que combinam o build do kernel do dispositivo com o build 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
a listagem de módulos do kernel nos arquivos de build da plataforma do dispositivo, ele poderá usar um caractere curinga
($(wildcard device/vendor/mydevice/*.ko
). O caractere curinga não
funciona no caso de um build integrado do kernel, porque quando o make é invocado e as
macros são expandidas em makefiles, os módulos do kernel não foram criados, portanto, as macros
estão vazias.
Para contornar esse problema, o fornecedor pode fazer com que o build do kernel crie um arquivo zip
que contenha os módulos do kernel a serem copiados em cada partição.
Defina o caminho desse arquivo ZIP em BOARD_*_KERNEL_MODULES_ARCHIVE
,
em que *
é o nome da partição (como
BOARD_VENDOR_KERNEL_MODULES_ARCHIVE
). O build da plataforma Android
extrai esse arquivo ZIP no local adequado e executa depmod
nos módulos.
O arquivo ZIP do módulo do kernel precisa ter uma regra de criação que garanta que o build da plataforma possa gerar o arquivo quando necessário.
Recuperação
Em versões anteriores do Android, os módulos do kernel necessários para recuperação eram
especificados em BOARD_RECOVERY_KERNEL_MODULES
. No Android 12,
os módulos do kernel necessários para a recuperação ainda são
especificados usando essa macro. No entanto, os módulos do kernel de recuperação são copiados para
o cpio do ramdisk do fornecedor, em vez do cpio genérico do ramdisk. Por padrão, todos
os módulos do kernel listados em BOARD_RECOVERY_KERNEL_MODULES
são carregados
durante o init
do primeiro estágio. Se você quiser que apenas um subconjunto desses
módulos seja carregado, especifique o conteúdo desse subconjunto em
BOARD_RECOVERY_KERNEL_MODULES_LOAD
.
Documentação relacionada
Para saber como criar uma partição de inicialização do fornecedor (que contém o ramdisk do fornecedor mencionado nesta página), consulte Partições de inicialização.