Compatibilidad con el módulo del núcleo

Es posible que una imagen de kernel genérica (GKI) no contenga el soporte de controlador requerido para permitir que un dispositivo monte particiones. Para permitir que un dispositivo monte particiones y continúe init , se mejoró el inicio de la primera etapa para cargar los módulos del kernel presentes en un ramdisk. El ramdisk se divide en ramdisks genéricos y de proveedor. Los módulos del kernel del proveedor se almacenan en el ramdisk del proveedor. El orden en que se cargan los módulos del núcleo es configurable.

Ubicación del módulo

El ramdisk es el sistema de archivos para el inicio de primera init, y para la imagen de recuperación/arranque rápido en dispositivos A/B y virtuales A/B. Es un initramfs compuesto por dos archivos cpio que el gestor de arranque concatena. El primer archivo cpio, que se almacena como ramdisk del proveedor en la partición de arranque del proveedor, contiene estos componentes:

  • Módulos de kernel de proveedor de init de primera etapa, ubicados en /lib/modules/ .
  • Archivos de configuración de modprobe , ubicados en /lib/modules/ : modules.dep , modules.softdep , modules.alias , modules.options .
  • Un archivo modules.load que indica qué módulos cargar durante el inicio de la primera etapa y en qué orden, en /lib/modules/ .
  • Módulos de kernel de recuperación de proveedores, para dispositivos A/B y virtuales A/B, en /lib/modules/
  • modules.load.recovery que indica los módulos a cargar, y en qué orden, para dispositivos A/B y Virtual A/B, en /lib/modules .

El segundo archivo cpio, que se suministra con GKI como ramdisk de boot.img y se aplica sobre el primero, contiene first_stage_init y las bibliotecas de las que depende.

Carga del módulo en el inicio de la primera etapa

El init de la primera etapa comienza leyendo los archivos de configuración de modprobe de /lib/modules/ en el ramdisk. A continuación, lee la lista de módulos especificados en /lib/modules/modules.load (o en el caso de la recuperación, /lib/modules/modules.load.recovery ) e intenta cargar cada uno de esos módulos en orden, siguiendo las configuración especificada en los archivos previamente cargados. El orden solicitado puede desviarse para satisfacer dependencias estrictas o blandas.

Soporte de compilación, inicio de primera etapa

Para especificar los módulos del núcleo que se copiarán en el ramdisk cpio del proveedor, enumérelos en BOARD_VENDOR_RAMDISK_KERNEL_MODULES . La compilación ejecuta depmod en estos módulos y coloca los archivos de configuración de modprobe resultantes en el ramdisk cpio del proveedor.

La compilación también crea un archivo modules.load y lo almacena en el ramdisk cpio del proveedor. De forma predeterminada, contiene todos los módulos enumerados en BOARD_VENDOR_RAMDISK_KERNEL_MODULES . Para anular el contenido de ese archivo, use BOARD_VENDOR_RAMDISK_KERNEL_MODULES_LOAD , como se muestra en este ejemplo:

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

Compatibilidad con compilación, Android completo

Como es el caso en Android 10 y versiones anteriores, los módulos del kernel enumerados en BOARD_VENDOR_KERNEL_MODULES son copiados por la compilación de la plataforma Android en la partición del proveedor en /vendor/lib/modules . La compilación de la plataforma ejecuta depmod en estos módulos y copia los archivos de salida de depmod en la partición del proveedor en la misma ubicación. El mecanismo para cargar módulos de kernel desde /vendor sigue siendo el mismo que para versiones anteriores de Android. Es su decisión cómo y cuándo cargar estos módulos, aunque normalmente esto se hace mediante scripts init.rc

Comodines y compilaciones de kernel integradas

Los proveedores que combinan la compilación del kernel de su dispositivo con la compilación de la plataforma Android pueden tener problemas al usar las macros BOARD mencionadas anteriormente para especificar los módulos del kernel que se copiarán en el dispositivo. Si el proveedor desea evitar enumerar los módulos del kernel en los archivos de compilación de la plataforma del dispositivo, puede usar un comodín ( $(wildcard device/vendor/mydevice/*.ko ). Tenga en cuenta que el comodín no funciona en el caso de un dispositivo integrado compilación del kernel, porque cuando se invoca make y las macros se expanden en archivos MAKE, los módulos del kernel no se han compilado, por lo que las macros están vacías.

Para solucionar este problema, el proveedor puede hacer que su compilación del kernel cree un archivo zip que contenga los módulos del kernel que se copiarán en cada partición. Establezca la ruta de ese archivo zip en BOARD_*_KERNEL_MODULES_ARCHIVE donde * es el nombre de la partición (como BOARD_VENDOR_KERNEL_MODULES_ARCHIVE ). La compilación de la plataforma Android extrae este archivo zip en la ubicación adecuada y ejecuta depmod en los módulos.

El archivo zip del módulo del núcleo debe tener una regla de creación que garantice que la compilación de la plataforma pueda generar el archivo cuando sea necesario.

Recuperación

En versiones anteriores de Android, los módulos del kernel necesarios para la recuperación se especificaban en BOARD_RECOVERY_KERNEL_MODULES . En Android 11, los módulos del kernel necesarios para la recuperación aún se especifican mediante esta macro. Sin embargo, los módulos del kernel de recuperación se copian al ramdisk cpio del proveedor, en lugar del ramdisk cpio genérico. De manera predeterminada, todos los módulos del kernel enumerados en BOARD_RECOVERY_KERNEL_MODULES se cargan durante el init de la primera etapa. Si solo desea que se cargue un subconjunto de estos módulos, especifique el contenido de ese subconjunto en BOARD_RECOVERY_KERNEL_MODULES_LOAD .

Para obtener información sobre cómo crear una partición de arranque de proveedor (que contiene el ramdisk del proveedor mencionado en esta página), consulte Particiones de arranque .