Kernels de compilación

En esta página, se detalla el proceso de compilación de kernels personalizados para dispositivos Android. Estas instrucciones te guiarán en el proceso de seleccionar las fuentes correctas, compilar el kernel e incorporar los resultados en una imagen del sistema compilada a partir del Proyecto de código abierto de Android (AOSP).

Mediante Repo, puedes adquirir las fuentes de kernel más recientes y compilarlas sin realizar una configuración adicional. Para hacerlo, ejecuta build/build.sh desde la raíz del resultado de tu fuente.

Cómo descargar fuentes y herramientas de compilación

En el caso de los kernels más recientes, usa repo para descargar las fuentes, la cadena de herramientas y las secuencias de comandos de compilación. Algunos kernels (por ejemplo, los de Pixel 3) requieren fuentes de varios repositorios de Git, mientras que otros (por ejemplo, los comunes) solo requieren una fuente. Puedes usar repo para garantizar una configuración correcta del directorio de la fuente.

Descarga las fuentes de la rama correcta:

mkdir android-kernel && cd android-kernel
repo init -u https://android.googlesource.com/kernel/manifest -b BRANCH
repo sync

En la siguiente tabla, se incluyen los nombres de BRANCH de los kernels disponibles con este método.

Dispositivo Ruta de objeto binario en el árbol de AOSP Ramas del repositorio
Pixel 7 (Panther)
Pixel 7 Pro (Cheetah)
device/google/pantah-kernel android-gs-pantah-5.10-android13-qpr2
Pixel 6a (Bluejay) device/google/bluejay-kernel android-gs-bluejay-5.10-android13-qpr2
Pixel 6 (Oriole)
Pixel 6 Pro (Raven)
device/google/raviole-kernel android-gs-raviole-5.10-android13-qpr2
Pixel 5a (Barbet)
Pixel 5 (Redfin)
Pixel 4a (5G) (Bramble)
device/google/redbull-kernel android-msm-redbull-4.19-android13-qpr2
Pixel 4a (Sunfish) device/google/sunfish-kernel android-msm-sunfish-4.14-android13-qpr2
Pixel 4 (Flame)
Pixel 4 XL (Coral)
device/google/coral-kernel android-msm-coral-4.14-android13
Pixel 3a (Sargo)
Pixel 3a XL (Bonito)
device/google/bonito-kernel android-msm-bonito-4.9-android12L
Pixel 3 (Blueline)
Pixel 3 XL (Crosshatch)
device/google/crosshatch-kernel android-msm-crosshatch-4.9-android12
Pixel 2 (Walleye)
Pixel 2 XL (Taimen)
device/google/wahoo-kernel android-msm-wahoo-4.4-android10-qpr3
Pixel (Sailfish)
Pixel XL (Marlin)
device/google/marlin-kernel android-msm-marlin-3.18-pie-qpr2
HiKey 960 device/linaro/hikey-kernel hikey-linaro-android-4.14
hikey-linaro-android-4.19
common-android12-5.4
common-android13-5.10
Beagle x15 device/ti/beagle_x15-kernel omap-beagle-x15-android-4.14
omap-beagle-x15-android-4.19
Kernel común de Android N/A common-android-4.4
common-android-4.9
common-android-4.14
common-android-4.19
common-android-4.19-stable
common-android11-5.4
common-android12-5.4
common-android12-5.10
common-android13-5.10
common-android13-5.15
common-android14-5.15
common-android14-6.1
common-android-mainline

Cómo compilar el kernel

Compila el kernel con lo siguiente:

build/build.sh

El objeto binario, los módulos y la imagen correspondiente del kernel se encuentran en el directorio de out/BRANCH/dist.

Cómo compilar con Bazel (Kleaf)

Android 13 introdujo la compilación de kernels con Bazel y reemplazó a build/build.sh.

Para compilar el kernel de GKI para la arquitectura aarch64, consulta una rama de kernel común de Android a partir de Android 13 y, luego, ejecuta el siguiente comando:

tools/bazel build //common:kernel_aarch64_dist

Para crear una distribución, ejecuta el siguiente comando:

tools/bazel run //common:kernel_aarch64_dist -- --dist_dir=$DIST_DIR

Luego, los objetos binarios, los módulos y las imágenes correspondientes del kernel se encuentran en el directorio $DIST_DIR. Si no se especifica --dist_dir, consulta el resultado del comando para obtener la ubicación de los artefactos. Para obtener más detalles, consulta la documentación sobre AOSP.

Cómo compilar módulos de proveedor para el dispositivo virtual

Android 11 introdujo GKI, que separa el kernel en una imagen de kernel que mantiene Google y los módulos que mantiene el proveedor, compilados por separado.

En este ejemplo, se muestra la configuración de una imagen de kernel:

BUILD_CONFIG=common/build.config.gki.x86_64 build/build.sh

En este ejemplo, se muestra la configuración de un módulo (Cuttlefish y Emulator):

BUILD_CONFIG=common-modules/virtual-device/build.config.cuttlefish.x86_64 build/build.sh

En Android 12, Cuttlefish y Goldfish convergen, por lo que comparten el mismo kernel: virtual_device. Para compilar los módulos de ese kernel, usa la siguiente configuración de compilación:

BUILD_CONFIG=common-modules/virtual-device/build.config.virtual_device.x86_64 build/build.sh

Android 13 introdujo la compilación de kernels con Bazel (Kleaf) y reemplaza build.sh.

Para compilar los módulos de virtual_device, ejecuta lo siguiente:

tools/bazel build //common-modules/virtual-device:virtual_device_x86_64_dist

Para crear una distribución, ejecuta el siguiente comando:

tools/bazel run //common-modules/virtual-device:virtual_device_x86_64_dist -- --dist_dir=$DIST_DIR

Para obtener más detalles sobre la compilación de kernels de Android con Bazel, consulta Kleaf: Cómo compilar kernels de Android con Bazel.

Si deseas obtener detalles sobre la compatibilidad de Kleaf para arquitecturas individuales, consulta Compatibilidad con Kleaf para dispositivos y kernels.

Compatibilidad con Kleaf para dispositivos y kernels

En la siguiente tabla, se muestra la compatibilidad de Kleaf para kernels de dispositivos individuales. Para dispositivos que no figuran en la lista, comunícate con el fabricante.

Dispositivo Ramas del repositorio Compatibilidad con Kleaf Compatibilidad con build/build.sh
Kernel común de Android
db845c
Dispositivo virtual (x86_64, arm64)
Dispositivo virtual (i686, arm)
Rockpi4
common-android-4.4
common-android-4.9
common-android-4.14
common-android-4.19
common-android-4.19-stable
common-android11-5.4
common-android12-5.4
common-android12-5.10
Kernel común de Android common-android13-5.10
common-android13-5.15
✅ (oficial)1
Kernel común de Android common-android14-5.15
common-android14-6.1
common-android-mainline
db845c common-android13-5.10
db845c common-android13-5.15 ✅ (oficial)1
db845c common-android14-5.15
common-android14-6.1
common-android-mainline
Dispositivo virtual (x86_64, arm64) common-android13-5.10
common-android13-5.15
✅ (oficial)1 ⚠️ (sin mantenimiento)2
Dispositivo virtual (x86_64, arm64) common-android14-5.15
common-android14-6.1
common-android-mainline
Dispositivo virtual (i686, arm) common-android13-5.10
common-android13-5.15
Dispositivo virtual (i686, arm) common-android14-5.15
common-android14-6.1
common-android-mainline
Rockpi4 common-android13-5.10
common-android13-5.15
Rockpi4 common-android14-5.15
common-android14-6.1
common-android-mainline
Hikey960 hikey-linaro-android-4.14
hikey-linaro-android-4.19
common-android12-5.4
common-android13-5.10
Módulo fips140 common-android12-5.10
common-android13-5.10
common-android13-5.15
Módulo fips140 common-android14-5.15

1 "Oficial" significa que esta es la forma oficial de compilar el kernel, aunque la forma alternativa también se puede usar.

2 "Sin mantenimiento" significa que compilar el kernel con este método debería funcionar, pero el método de compilación no se prueba de forma continua. Es posible que deje de funcionar en el futuro. En su lugar, usa el método "oficial".

Cómo ejecutar el kernel

Hay varias maneras de ejecutar un kernel de compilación personalizada. Lo siguientes son métodos conocidos y apropiados para implementarlos en distintos entornos de desarrollo.

Cómo incorporar en la compilación de imágenes de Android

Copia Image.lz4-dtb en la ubicación correspondiente del objeto binario del kernel en el árbol de AOSP y vuelve a compilar la imagen de inicio.

También puedes definir la variable TARGET_PREBUILT_KERNEL mientras usas make bootimage (o cualquier otra línea de comandos de make que compile una imagen de inicio). Esta variable es compatible con todos los dispositivos, ya que se configura a través de device/common/populate-new-device.sh. Por ejemplo:

export TARGET_PREBUILT_KERNEL=DIST_DIR/Image.lz4-dtb

Cómo instalar e iniciar kernels con el inicio rápido

Los dispositivos más recientes tienen una extensión de bootloader que optimiza el proceso de generación y de inicio de una imagen.

Para iniciar el kernel sin instalarlo, haz lo siguiente:

adb reboot bootloader
fastboot boot Image.lz4-dtb

Mediante este método, el kernel no se instala y no persistirá después de un reinicio.

Cómo personalizar la compilación del kernel

Para personalizar las compilaciones del kernel para las compilaciones de Kleaf, consulta la documentación de Kleaf.

Para build/build.sh, el proceso de compilación y el resultado pueden verse influenciados por variables de entorno. La mayoría son opcionales y cada rama de kernel debería incluir una configuración predeterminada apropiada. Las más utilizadas se incluyen en esta lista. Para ver la lista completa (y actualizada), consulta build/build.sh.

Variable de entorno Descripción Ejemplo
BUILD_CONFIG Archivo de configuración de compilación desde donde se inicia el entorno de compilación. La ubicación debe definirse según el directorio raíz del repositorio. La configuración predeterminada es build.config.
Es obligatorio para kernels comunes.
BUILD_CONFIG=common/build.config.gki.aarch64
CC Anula el compilador que se utilizará. Recurre al compilador predeterminado definido por build.config. CC=clang
DIST_DIR Directorio de salida base para la distribución de kernel DIST_DIR=/path/to/my/dist
OUT_DIR Directorio de salida base para la compilación de kernel OUT_DIR=/path/to/my/out
SKIP_DEFCONFIG Omitir make defconfig SKIP_DEFCONFIG=1
SKIP_MRPROPER Omitir make mrproper SKIP_MRPROPER=1

Cómo configurar el kernel de forma personalizada para compilaciones locales

Si necesitas cambiar una opción de la configuración de kernel con frecuencia (por ejemplo, cuando trabajas en una función) o si precisas que se configure una opción con fines de desarrollo, puedes mantener una versión local o copiar la configuración de la compilación para lograr esa flexibilidad.

Establece la variable POST_DEFCONFIG_CMDS en una afirmación que se evalúe una vez que termine el paso make defconfig habitual. Como los archivos build.config se originan en el entorno de compilación, se puede llamar a las funciones definidas en build.config como parte de los comandos posteriores a la desconfiguración.

Un ejemplo común consiste en inhabilitar la optimización del tiempo de vinculación (LTO) para kernels de crosshatch durante el desarrollo. Aunque LTO ofrece ventajas para los kernels lanzados, el tiempo de compilación puede ser considerable. Si agregas el siguiente fragmento al build.config local, se inhabilitará LTO de manera persistente cuando uses build/build.sh.

POST_DEFCONFIG_CMDS="check_defconfig && update_debug_config"
function update_debug_config() {
    ${KERNEL_DIR}/scripts/config --file ${OUT_DIR}/.config \
         -d LTO \
         -d LTO_CLANG \
         -d CFI \
         -d CFI_PERMISSIVE \
         -d CFI_CLANG
    (cd ${OUT_DIR} && \
     make O=${OUT_DIR} $archsubarch CC=${CC} CROSS_COMPILE=${CROSS_COMPILE} olddefconfig)
}

Cómo identificar versiones de kernel

Puedes identificar la versión correcta para compilar a partir de dos fuentes: el árbol de AOSP y la imagen del sistema.

Versión de kernel del árbol de AOSP

El árbol de AOSP incluye versiones de kernel compiladas previamente. El registro de Git muestra la versión correcta como parte del mensaje de confirmación:

cd $AOSP/device/VENDOR/NAME
git log --max-count=1

Si la versión de kernel no aparece en el registro de Git, obtenla desde la imagen del sistema, como se describe a continuación.

Versión de kernel de la imagen del sistema

Para determinar la versión de kernel que se usa en una imagen del sistema, ejecuta el siguiente comando en el archivo de kernel:

file kernel

En el caso de los archivos Image.lz4-dtb, ejecuta lo siguiente:

grep -a 'Linux version' Image.lz4-dtb

Cómo compilar una imagen de arranque

Es posible compilar una imagen de arranque usando el entorno de compilación del kernel.

Cómo compilar una imagen de arranque para dispositivos con init_boot

Para dispositivos con la partición init_boot, la imagen de arranque se compila junto con el kernel. La imagen initramfs no está incorporada a la imagen de arranque.

Por ejemplo, con Kleaf, puedes compilar la imagen de arranque de GKI con lo siguiente:

tools/bazel run //common:kernel_aarch64_dist -- --dist_dir=$DIST_DIR

Con build/build.sh, puedes compilar la imagen de arranque de GKI con lo siguiente:

BUILD_CONFIG=common/build.config.gki.aarch64 build/build.sh

La imagen de arranque de GKI se encuentra en $DIST_DIR.

Cómo compilar una imagen de arranque para dispositivos sin init_boot

Para dispositivos sin la partición init_boot, necesitas un objeto binario ramdisk, que puedes obtener si descargas una imagen de arranque de GKI y la desempaquetas. Cualquier imagen de arranque de GKI de la versión de Android asociada funcionará.

tools/mkbootimg/unpack_bootimg.py --boot_img=boot-5.4-gz.img
mv $KERNEL_ROOT/out/ramdisk gki-ramdisk.lz4

La carpeta de destino es el directorio de nivel superior del árbol del kernel (directorio de trabajo actual).

Si estás desarrollando con la rama principal de AOSP, puedes descargar el artefacto de compilación ramdisk-recovery.img de una compilación aosp_arm64 en ci.android.com y usarlo como objeto binario de ramdisk.

Si tienes un objeto binario de ramdisk y lo copias en gki-ramdisk.lz4, en el directorio raíz de la compilación del kernel, puedes generar una imagen de arranque ejecutando lo siguiente:

BUILD_BOOT_IMG=1 SKIP_VENDOR_BOOT=1 KERNEL_BINARY=Image GKI_RAMDISK_PREBUILT_BINARY=gki-ramdisk.lz4 BUILD_CONFIG=common/build.config.gki.aarch64 build/build.sh

Si estás trabajando con una arquitectura que se basa en x86, reemplaza Image por bzImage y aarch64 por x86_64:

BUILD_BOOT_IMG=1 SKIP_VENDOR_BOOT=1 KERNEL_BINARY=bzImage GKI_RAMDISK_PREBUILT_BINARY=gki-ramdisk.lz4 BUILD_CONFIG=common/build.config.gki.x86_64 build/build.sh

Ese archivo se encuentra en el directorio de artefactos $KERNEL_ROOT/out/$KERNEL_VERSION/dist.

La imagen de arranque se encuentra en out/<kernel branch>/dist/boot.img.