Kernel module support

A generic kernel image (GKI) may not contain the required driver support to enable a device to mount partitions. To enable a device to mount partitions and to continue booting, first-stage init is enhanced to load the kernel modules present on a ramdisk. The ramdisk is split into generic and vendor ramdisks. Vendor kernel modules are stored in the vendor ramdisk. The order in which kernel modules are loaded is configurable.

Module location

The ramdisk is the filesystem for first-stage init, and for the recovery/fastbootd image on A/B and virtual A/B devices. It's an initramfs composed of two cpio archives that get concatenated by the bootloader. The first cpio archive, which is stored as the vendor ramdisk in the vendor-boot partition, contains these components:

  • First-stage init vendor kernel modules, located in /lib/modules/.
  • modprobe config files, located in /lib/modules/: modules.dep, modules.softdep, modules.alias, modules.options.
  • A modules.load file that indicates which modules to load during first stage init, and in which order, in /lib/modules/.
  • Vendor recovery-kernel modules, for A/B and Virtual A/B devices, in /lib/modules/
  • modules.load.recovery which indicates the modules to load, and in which order, for A/B and Virtual A/B devices, in /lib/modules.

The second cpio archive, which is supplied with the GKI as the ramdisk of the boot.img and applied on top of the first, contains first_stage_init and the libraries on which it depends.

Module loading in first-stage init

First-stage init begins by reading the modprobe configuration files from /lib/modules/ on the ramdisk. Next, it reads the list of modules specified in /lib/modules/modules.load (or in the case of recovery, /lib/modules/modules.load.recovery) and attempts to load each of those modules in order, following the configuration specified in the previously loaded files. The requested order may be deviated from to satisfy hard or soft dependencies.

Build support, first-stage init

To specify kernel modules to be copied into the vendor ramdisk cpio, list them in BOARD_VENDOR_RAMDISK_KERNEL_MODULES. The build runs depmod on these modules and puts the resulting modprobe configuration files in the vendor ramdisk cpio.

The build also creates a modules.load file and stores it in the vendor ramdisk cpio. By default it contains all of the modules listed in BOARD_VENDOR_RAMDISK_KERNEL_MODULES. To override the contents of that file, use BOARD_VENDOR_RAMDISK_KERNEL_MODULES_LOAD, as shown in this example:

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

Build support, full Android

As is the case in Android 10 and lower releases, kernel modules listed in BOARD_VENDOR_KERNEL_MODULES are copied by the Android platform build into the vendor partition at /vendor/lib/modules. The platform build runs depmod on these modules, and copies the depmod output files into the vendor partition at the same location. The mechanism for loading kernel modules from /vendor remains the same as it was for prior releases of Android. It's your decision how and when to load these modules, although typically this is done using init.rc scripts.

Wildcards and integrated kernel builds

Vendors who combine their device kernel build with the Android platform build may run into a problem using the above mentioned BOARD macros to specify kernel modules to be copied on to the device. If the vendor wishes to avoid listing kernel modules in the device's platform build files, they can use a wildcard ($(wildcard device/vendor/mydevice/*.ko). Note that the wildcard doesn't work in the case of an integrated kernel build, because when make is invoked and the macros are expanded in makefiles, the kernel modules haven't been built, so the macros are empty.

To get around this problem, the vendor may have their kernel build create a zip archive containing the kernel modules to be be copied onto each partition. Set the path of that zip archive in BOARD_*_KERNEL_MODULES_ARCHIVE where * is the name of the partition (such as BOARD_VENDOR_KERNEL_MODULES_ARCHIVE). The Android platform build extracts this zip archive into the appropriate location and runs depmod on the modules.

The kernel module zip archive should have a make rule that ensures the platform build can generate the archive when required.

Recovery

In prior Android releases, kernel modules required for recovery were specified in BOARD_RECOVERY_KERNEL_MODULES. In Android 12, kernel modules required for recovery are still specified using this macro. However, the recovery kernel modules are copied to the vendor ramdisk cpio, rather than the generic ramdisk cpio. By default all kernel modules listed in BOARD_RECOVERY_KERNEL_MODULES are loaded during first-stage init. If you only want a subset of these modules to be loaded, specify the contents of that subset in BOARD_RECOVERY_KERNEL_MODULES_LOAD.

To learn about creating a vendor boot partition (which contains the vendor ramdisk mentioned on this page), see Boot partitions.