Introduction: The Imperative for Automated Kernel Builds
Developing for Android often involves customizing the underlying Linux kernel. Whether you’re integrating new drivers, optimizing performance, or experimenting with security features, building a custom kernel for the Android Open Source Project (AOSP) is a common, yet often tedious, task. Manually compiling, integrating, and testing these kernels for QEMU-based Android Virtual Devices (AVDs) can be time-consuming and prone to errors. This article delves into creating a robust CI/CD pipeline to automate the entire process, ensuring reproducible, efficient, and consistent kernel builds for your AOSP development environment.
Automating this workflow not only accelerates development cycles but also fosters a more reliable testing environment, crucial for projects like Android Emulator, Anbox, or Waydroid where custom kernel features are paramount. We’ll cover the essential steps from setting up the environment to designing a multi-stage pipeline that takes your kernel source, compiles it, integrates it into an AOSP build, and prepares it for deployment on QEMU.
Prerequisites and Environment Setup
Before diving into automation, ensure you have a powerful Linux-based build machine (Ubuntu LTS or Debian recommended) with sufficient resources:
- At least 16GB RAM (32GB+ recommended)
- 200GB+ free disk space (for AOSP source and build artifacts)
- Multi-core CPU (8+ cores recommended)
- Git
- Python 3
- Java Development Kit (JDK) 11
- Basic build tools (
make,gcc,g++,libc6-dev, etc.)
Start by syncing the AOSP source and the kernel source. For QEMU, the AOSP common kernel is typically used. Navigate to your AOSP root directory:
mkdir aosp-project && cd aosp-projectrepo init -u https://android.googlesource.com/platform/manifest -b android-13.0.0_r40repo sync -j$(nproc)
Next, clone the AOSP common kernel source. The branch should match your AOSP version:
cd kernel/common/cp/gs-google/gs-google-qemu-x86_64git clone https://android.googlesource.com/kernel/common --depth 1 -b android-gs-qemu-x86_64-5.10 kernel-source
Ensure your build environment is set up. The AOSP `envsetup.sh` script will configure necessary paths and functions:
source build/envsetup.sh
Manual Kernel Compilation for QEMU AVDs
To understand the automated process, it’s helpful to first perform a manual kernel build. We’ll target an `x86_64` QEMU device. First, select the target product and variant:
lunch aosp_x86_64-eng
Now, let’s build the kernel. The AOSP build system typically handles kernel compilation automatically if `TARGET_PREBUILT_KERNEL` is not set. However, for a custom kernel, you might build it separately. Navigate to your kernel source directory:
cd kernel-sourceexport ARCH=x86_64export SUBARCH=x86_64export CROSS_COMPILE=$(pwd)/../prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.9/bin/x86_64-linux-android-
Configure and build the kernel:
make cleanmake gki_x86_64_defconfig # Or the appropriate defconfig for your targetmake -j$(nproc)
Upon successful compilation, the kernel image (`Image.gz`) will be located in `arch/x86_64/boot/Image.gz`. For QEMU, you might also need `bzImage` and kernel modules.
Integrating Custom Kernel into AOSP Build
Once your custom kernel is built, you need to integrate it into the AOSP system image. The most straightforward way for QEMU targets is to place your compiled `Image.gz` in a location where the AOSP build system expects a kernel, or to directly specify its path.
For AOSP QEMU builds, the kernel is usually found in a prebuilt path or generated by the build system. You can override the kernel used by AOSP by setting `TARGET_PREBUILT_KERNEL` to the path of your custom kernel image *before* starting the AOSP build. For example, if your compiled kernel is at `/path/to/your/custom/kernel/Image.gz`:
export TARGET_PREBUILT_KERNEL=/path/to/your/custom/kernel/Image.gz
Then, initiate the full AOSP build:
make -j$(nproc)
This will generate the necessary QEMU images, including `emulator-kernel.img`, `ramdisk.img`, and `system.img`, incorporating your custom kernel.
Designing the CI/CD Pipeline
A CI/CD pipeline for AOSP kernel builds should automate the entire lifecycle from source changes to deployable artifacts. We’ll outline a generic pipeline structure applicable to platforms like Jenkins, GitLab CI, or GitHub Actions.
Pipeline Stages:
-
Environment Setup and Source Synchronization
This stage prepares the build agent. It clones or updates the AOSP and kernel source repositories and installs any necessary dependencies. Using a dedicated Docker image with pre-installed build tools can significantly speed this up.
# Example: .gitlab-ci.yml or .github/workflows/main.ymlstage: setupimage: custom-aosp-builder-image:latestscript: - repo init -u https://android.googlesource.com/platform/manifest -b android-13.0.0_r40 - repo sync -j$(nproc) - git clone https://android.googlesource.com/kernel/common --depth 1 -b android-gs-qemu-x86_64-5.10 kernel-source -
Kernel Compilation
In this stage, the custom kernel is built. It navigates to the kernel source, sets up the cross-compilation toolchain, and executes the `make` commands.
stage: compile-kernelscript: - cd kernel-source - export ARCH=x86_64 - export SUBARCH=x86_64 - export CROSS_COMPILE=$(pwd)/../prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.9/bin/x86_64-linux-android- - make clean - make gki_x86_64_defconfig - make -j$(nproc) - cp arch/x86_64/boot/Image.gz ../custom_kernel.imgartifacts:paths: - custom_kernel.img -
AOSP Integration and Image Build
This critical stage takes the compiled kernel, integrates it into the AOSP tree, and then triggers the full AOSP build process to generate QEMU images.
stage: build-aospneeds: [compile-kernel]script: - source build/envsetup.sh - lunch aosp_x86_64-eng - export TARGET_PREBUILT_KERNEL=$(pwd)/custom_kernel.img - make -j$(nproc) - cp out/target/product/generic_x86_64/*.img .artifacts:paths: - *.img -
Artifact Storage and Deployment
The final stage is responsible for archiving the built AOSP images (e.g., `system.img`, `ramdisk.img`, `emulator-kernel.img`) and potentially deploying them to a testing environment or artifact repository. This allows for easy download and testing of the AVDs with the custom kernel.
Example Pipeline Logic (Conceptual)
trigger: - push: branches: - main - kernel-devjobs: setup-environment: stage: setup steps: - checkout: path: aosp repository: your/aosp-repo - checkout: path: kernel-common repository: your/kernel-common-repo - run: | cd aosp repo sync -j$(nproc) - run: | cd kernel-common git clone https://android.googlesource.com/kernel/common ... kernel-source build-kernel: stage: build needs: [setup-environment] steps: - run: | cd aosp/kernel-common/kernel-source export ARCH=x86_64 export SUBARCH=x86_64 export CROSS_COMPILE=$(pwd)/../../prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.9/bin/x86_64-linux-android- make clean make gki_x86_64_defconfig make -j$(nproc) cp arch/x86_64/boot/Image.gz $(Build.ArtifactStagingDirectory)/custom_kernel.img artifacts: paths: - $(Build.ArtifactStagingDirectory)/custom_kernel.img build-aosp-with-custom-kernel: stage: integrate-build needs: [build-kernel] steps: - download-artifacts: name: custom_kernel.img targetPath: aosp/ - run: | cd aosp source build/envsetup.sh lunch aosp_x86_64-eng export TARGET_PREBUILT_KERNEL=$(pwd)/custom_kernel.img make -j$(nproc) cp out/target/product/generic_x86_64/*.img $(Build.ArtifactStagingDirectory)/ artifacts: paths: - $(Build.ArtifactStagingDirectory)/*.img
Benefits of Automation
Implementing such a CI/CD pipeline offers significant advantages:
- Reproducibility: Every build is consistent, reducing
Android Mobile Specs & Compare Directory
Are you researching mobile hardware properties, processor SoCs, GPU chipsets, or RAM configurations? Access our complete specs catalog to compare up to 5 devices side-by-side!
Compare Devices Specs →