Compatibilidad con el módulo de kernel

Es posible que una imagen genérica del kernel (GKI) no sea compatible con el controlador necesario para permitir que un dispositivo active particiones. Para permitir que un dispositivo active particiones y continúe con el inicio, se mejoró el elemento init inicial para cargar los módulos de kernel presentes en un disco RAM. El disco RAM se divide en discos RAM de proveedores y genéricos. Los módulos de kernel del proveedor se almacenan en el disco RAM del proveedor. Puedes configurar el orden en el que se cargan los módulos de kernel.

Ubicación del módulo

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

  • Módulos de kernel del proveedor init de primera etapa, ubicados en /lib/modules/
  • Archivos de configuración modprobe, ubicados en /lib/modules/: modules.dep, modules.softdep, modules.alias y 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 del proveedor, para dispositivos A/B y A/B virtuales, en /lib/modules/
  • modules.load.recovery, que indica los módulos que se cargarán y en qué orden para dispositivos A/B y A/B virtuales, en /lib/modules.

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

Carga de módulos en la inicialización de primera etapa

El init de primera etapa comienza por leer los archivos de configuración de modprobe desde /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) y, luego, intenta cargar cada uno de esos módulos en orden, según la configuración especificada en los archivos cargados anteriormente. Es posible que se desvíe del orden solicitado para satisfacer dependencias duras o blandas.

Compatibilidad de compilación, inicialización de primera etapa

Para especificar los módulos de kernel que se copiarán en el cpio del ramdisk del proveedor, inclúyelos 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 cpio del ramdisk del proveedor.

La compilación también crea un archivo modules.load y lo almacena en el proveedor ramdisk cpio. De forma predeterminada, contiene todos los módulos que se enumeran en BOARD_VENDOR_RAMDISK_KERNEL_MODULES. Para anular el contenido de ese archivo, usa 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 de compilación, Android completo

Como es el caso de Android 10 y versiones anteriores, la compilación de la plataforma de Android copia los módulos de kernel enumerados en BOARD_VENDOR_KERNEL_MODULES 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 en versiones anteriores de Android. Tú decides cómo y cuándo cargar estos módulos, aunque, por lo general, esto se hace con secuencias de comandos init.rc.

Comodines y compilaciones de kernel integradas

Es posible que los proveedores que combinen la compilación del kernel de su dispositivo con la compilación de la plataforma de Android tengan un problema cuando usen 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). Ten en cuenta que el comodín no funciona en el caso de una compilación de kernel integrada, ya que cuando se invoca make y se expanden las macros en los archivos makefile, los módulos del kernel no se compilaron, por lo que las macros están vacías.

Para evitar 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. Establece la ruta de acceso de ese archivo ZIP en BOARD_*_KERNEL_MODULES_ARCHIVE, en la que * es el nombre de la partición (como BOARD_VENDOR_KERNEL_MODULES_ARCHIVE). La compilación de la plataforma de Android extrae este archivo ZIP en la ubicación adecuada y ejecuta depmod en los módulos.

El archivo ZIP del módulo del kernel debe tener una regla de make 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 12, los módulos del kernel necesarios para la recuperación aún se especifican con esta macro. Sin embargo, los módulos del kernel de recuperación se copian en el CPIO del ramdisk del proveedor, en lugar del CPIO del ramdisk genérico. De forma predeterminada, todos los módulos del kernel que se enumeran en BOARD_RECOVERY_KERNEL_MODULES se cargan durante el init de primera etapa. Si solo quieres que se cargue un subconjunto de estos módulos, especifica su contenido en BOARD_RECOVERY_KERNEL_MODULES_LOAD.

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