AOSP Expert & Production Engineering
3 min read

Custom Kernel Integration

Integrating Custom Kernels in AOSP

The Linux kernel is the foundation of Android, managing hardware resources and bridging the gap between the physical device and the AOSP framework. Integrating a custom kernel allows developers to optimize performance, add support for new hardware, backport features, or implement specialized security policies.

Sourcing the Custom Kernel

You typically start with an OEM provided kernel source or an upstream Code Aurora Forum (CAF) release for Qualcomm devices.

# Example: Cloning a kernel source into the AOSP tree
git clone https://github.com/torvalds/linux.git kernel/vendor/device_name

To compile successfully for Android, the kernel must include specific patches and configuration options. Google maintains common kernels (e.g., android-4.14, android-4.19, android-11-5.4) that include the necessary Android specific features like Binder, Ashmem (historically), and Energy Aware Scheduling (EAS).

Android Kernel Configuration

The kernel configuration dictates which drivers and features are compiled. Android relies on defconfig files, usually found in arch/arm64/configs/.

A typical AOSP kernel requires several critical configurations:

# Required for Android IPC
CONFIG_ANDROID_BINDER_IPC=y
CONFIG_ANDROID_BINDERFS=y

# Required for memory management and tracing
CONFIG_ASHMEM=y
CONFIG_TRACEPOINTS=y

# Required for SELinux
CONFIG_SECURITY_SELINUX=y

When integrating a custom kernel, you must ensure your defconfig is compatible with the AOSP version you are building. You can verify the configuration using the merge_config.sh script provided in the kernel tree, combining your base config with Android's base config requirements.

Inline Kernel Build vs. Prebuilt Kernel

There are two primary methods for integrating a custom kernel into the AOSP build process: Inline building and using prebuilts.

Method 1: Prebuilt Kernel Integration

This is the simplest approach. You compile the kernel externally and place the resulting Image.gz-dtb (or similar) into your device tree.

  1. Compile the kernel externally using standard make commands.
  2. Copy the kernel binary to device/<vendor>/<codename>-kernel/.
  3. Configure your BoardConfig.mk to use the prebuilt image:
# BoardConfig.mk using a prebuilt kernel
TARGET_PREBUILT_KERNEL := device/vendor/codename-kernel/Image.gz-dtb
BOARD_KERNEL_PAGESIZE := 4096
BOARD_KERNEL_BASE := 0x00000000
BOARD_KERNEL_CMDLINE := console=ttyMSM0,115200n8 androidboot.hardware=qcom

Pros: Faster AOSP compilation times, easier isolation of kernel issues. Cons: Requires manual rebuilding and copying whenever kernel source changes.

Method 2: Inline Kernel Build

Inline building compiles the kernel automatically during the m or mka process. This is preferred for active kernel development alongside ROM development.

To enable inline building, you usually define the kernel source path and the target defconfig in your BoardConfig.mk or a specialized kernel makefile.

# BoardConfig.mk for inline kernel build
TARGET_KERNEL_SOURCE := kernel/vendor/codename
TARGET_KERNEL_CONFIG := vendor_codename_defconfig
TARGET_KERNEL_ARCH := arm64
BOARD_KERNEL_IMAGE_NAME := Image.gz-dtb

During the AOSP build, the build system will enter the TARGET_KERNEL_SOURCE directory, set up the cross compiler, and build the kernel before assembling the boot.img.

Handling Kernel Modules (.ko files)

Many drivers (like Wi-Fi or Audio) are built as loadable kernel modules. When building inline, the AOSP build system must be configured to copy these modules to /vendor/lib/modules/.

# Example device.mk snippet for copying kernel modules
BOARD_VENDOR_KERNEL_MODULES := \
    $(wildcard $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/drivers/net/wireless/qcacld-3.0/wlan.ko) \
    $(wildcard $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/sound/soc/codecs/snd-soc-wcd934x.ko)

Integrating a custom kernel correctly ensures that your hardware is fully supported and optimized for the specific demands of the Android operating system.