Auf dieser Seite wird beschrieben, wie Sie benutzerdefinierte Kernel für Android-Geräte erstellen. In dieser Anleitung wird beschrieben, wie Sie die richtigen Quellen auswählen, den Kernel erstellen und die Ergebnisse in ein System-Image einbetten, das aus dem Open-Source-Projekt für Android (AOSP) erstellt wurde.
Quellen und Build-Tools herunterladen
Verwenden Sie für aktuelle Kernel repo, um die Quellen, die Toolchain und die Build-Skripts herunterzuladen.
Für einige Kernel (z. B. die Pixel 3-Kernel) sind Quellen aus mehreren Git-Repositories erforderlich, während für andere (z. B. die gemeinsamen Kernel) nur eine Quelle erforderlich ist. Mit dem repo-Ansatz wird sichergestellt, dass das Quellverzeichnis richtig eingerichtet ist.
Laden Sie die Quellen für den entsprechenden Branch herunter:
mkdir android-kernel && cd android-kernel
repo init -u https://android.googlesource.com/kernel/manifest -b BRANCH
repo sync
Eine Liste der Repository-Zweige (BRANCH), die mit dem vorherigen `repo init`-Befehl verwendet werden können, finden Sie unter Kernel-Zweige und ihre Build-Systeme.
Weitere Informationen zum Herunterladen und Kompilieren von Kernels für Pixel-Geräte finden Sie unter Pixel-Kernels erstellen.
Kernel erstellen
Mit Bazel erstellen (Kleaf)
In Android 13 wurde die Möglichkeit eingeführt, Kernel mit Bazel zu erstellen.
Wenn Sie eine Distribution für den GKI-Kernel für die AArch64-Architektur erstellen möchten, prüfen Sie, ob ein Android Common Kernel-Zweig vorhanden ist, der nicht älter als Android 13 ist, und führen Sie dann den folgenden Befehl aus:
tools/bazel run //common:kernel_aarch64_dist [-- --destdir=$DIST_DIR]
Danach befinden sich die Kernel-Binärdatei, die Module und die entsprechenden Images im Verzeichnis $DIST_DIR. Wenn --destdir nicht angegeben ist, sehen Sie in der Ausgabe des Befehls nach, wo sich die Artefakte befinden. Weitere Informationen finden Sie in der AOSP-Dokumentation.
Mit build.sh erstellen (Legacy)
Für Branches mit Android 12 oder niedriger ODER Branches ohne Kleaf:
build/build.sh
Die Kernel-Binärdatei, die Module und das entsprechende Image befinden sich im Verzeichnis out/BRANCH/dist.
Anbietermodule für das virtuelle Gerät erstellen
In Android 13 wurde die Möglichkeit eingeführt, Kernel mit Bazel (Kleaf) zu erstellen. Dadurch wurde build.sh ersetzt.
So erstellen Sie eine Verteilung für die Module von virtual_device:
tools/bazel run //common-modules/virtual-device:virtual_device_x86_64_dist [-- --destdir=$DIST_DIR]
Weitere Informationen zum Erstellen von Android-Kernels mit Bazel finden Sie unter. Kleaf - Building Android Kernels with Bazel
Weitere Informationen zur Kleaf-Unterstützung für einzelne Architekturen finden Sie unter Kleaf-Unterstützung für Geräte und Kernel.
Anbietermodule für das virtuelle Gerät mit „build.sh“ erstellen (Legacy)
In Android 12 werden Cuttlefish und Goldfish zusammengeführt, sodass sie denselben Kernel verwenden: virtual_device. Verwenden Sie diese Build-Konfiguration, um die Module des Kernels zu erstellen:
BUILD_CONFIG=common-modules/virtual-device/build.config.virtual_device.x86_64 build/build.sh
Mit Android 11 wurde GKI eingeführt. Dabei wird der Kernel in ein von Google verwaltetes Kernel-Image und von Anbietern verwaltete Module unterteilt, die separat erstellt werden.
Dieses Beispiel zeigt eine Kernel-Image-Konfiguration:
BUILD_CONFIG=common/build.config.gki.x86_64 build/build.sh
In diesem Beispiel sehen Sie eine Modulkonfiguration (Cuttlefish und Emulator):
BUILD_CONFIG=common-modules/virtual-device/build.config.cuttlefish.x86_64 build/build.sh
Kernel ausführen
Es gibt mehrere Möglichkeiten, einen benutzerdefinierten Kernel auszuführen. Im Folgenden finden Sie bekannte Methoden, die sich für verschiedene Entwicklungsszenarien eignen.
In den Android-Image-Build einbetten
Kopieren Sie Image.lz4-dtb in den entsprechenden Speicherort für das Kernel-Binärprogramm im AOSP-Baum und erstellen Sie das Boot-Image neu.
Alternativ können Sie die Variable TARGET_PREBUILT_KERNEL definieren, wenn Sie make bootimage (oder eine andere make-Befehlszeile, mit der ein Boot-Image erstellt wird) verwenden. Diese Variable wird von allen Geräten unterstützt, da sie über device/common/populate-new-device.sh eingerichtet wird. Beispiel:
export TARGET_PREBUILT_KERNEL=DIST_DIR/Image.lz4-dtb
Kernel mit Fastboot flashen und starten
Die meisten aktuellen Geräte haben eine Bootloader-Erweiterung, um das Erstellen und Booten eines Boot-Images zu vereinfachen.
So booten Sie den Kernel ohne Flashen:
adb reboot bootloaderfastboot boot Image.lz4-dtb
Bei dieser Methode wird der Kernel nicht geflasht und bleibt auch nach einem Neustart nicht erhalten.
Kernel auf Cuttlefish ausführen
Sie können Kerne auf Cuttlefish-Geräten in der Architektur Ihrer Wahl ausführen.
Wenn Sie ein Cuttlefish-Gerät mit einer bestimmten Gruppe von Kernel-Artefakten starten möchten, führen Sie den Befehl cvd create mit den Ziel-Kernel-Artefakten als Parameter aus. Im folgenden Beispielbefehl werden Kernel-Artefakte für ein arm64-Ziel aus dem Kernel-Manifest common-android14-6.1 verwendet.
cvd create \-kernel_path=/$PATH/$TO/common-android14-6.1/out/android14-6.1/dist/Image \-initramfs_path=/$PATH/$TO/common-android14-6.1/out/android14-6.1/dist/initramfs.img
Weitere Informationen finden Sie unter Kernel auf Cuttlefish entwickeln.
Kernel-Build anpassen
Informationen zum Anpassen der Kernel-Builds für Kleaf-Builds finden Sie in der Kleaf-Dokumentation.
Kernel-Build mit build.sh anpassen (Legacy)
Bei build/build.sh können der Build-Prozess und das Ergebnis durch Umgebungsvariablen beeinflusst werden.
Die meisten sind optional und jeder Kernel-Zweig sollte mit einer geeigneten Standardkonfiguration geliefert werden. Die am häufigsten verwendeten werden hier aufgeführt. Eine vollständige und aktuelle Liste finden Sie unter build/build.sh.
| Umgebungsvariable | Beschreibung | Beispiel |
|---|---|---|
BUILD_CONFIG |
Build-Konfigurationsdatei, über die Sie die Build-Umgebung initialisieren.
Der Speicherort muss relativ zum Stammverzeichnis des Repositorys definiert werden. Die Standardeinstellung ist build.config.Für allgemeine Kernel erforderlich. |
BUILD_CONFIG=common/build.config.gki.aarch64 |
CC |
Überschreibt den zu verwendenden Compiler. Greift auf den Standardcompiler zurück, der von build.config definiert wird. |
CC=clang |
DIST_DIR |
Basisausgabeverzeichnis für die Kernel-Distribution. | DIST_DIR=/path/to/my/dist |
OUT_DIR |
Das Basisausgabeverzeichnis für den Kernel-Build. | OUT_DIR=/path/to/my/out |
SKIP_DEFCONFIG |
Überspringen make defconfig |
SKIP_DEFCONFIG=1 |
SKIP_MRPROPER |
Überspringen make mrproper |
SKIP_MRPROPER=1 |
Benutzerdefinierte Kernelkonfiguration für lokale Builds
In Android 14 und höher können Sie defconfig-Fragmente verwenden, um Kernelkonfigurationen anzupassen. Weitere Informationen finden Sie in der Kleaf-Dokumentation zu defconfig-Fragmenten.
Benutzerdefinierte Kernelkonfiguration für lokale Builds mit Build-Konfigurationen (Legacy)
Unter Android 13 und niedriger gilt Folgendes.
Wenn Sie eine Kernelkonfigurationsoption regelmäßig wechseln müssen, z. B. wenn Sie an einem Feature arbeiten, oder wenn Sie eine Option für Entwicklungszwecke festlegen müssen, können Sie diese Flexibilität erreichen, indem Sie eine lokale Änderung oder Kopie der Build-Konfiguration beibehalten.
Legen Sie die Variable POST_DEFCONFIG_CMDS auf eine Anweisung fest, die direkt nach dem üblichen make defconfig-Schritt ausgewertet wird. Da die build.config-Dateien in die Build-Umgebung eingefügt werden, können Funktionen, die in build.config definiert sind, als Teil der Post-Defconfig-Befehle aufgerufen werden.
Ein häufiges Beispiel ist das Deaktivieren der Link Time Optimization (LTO) für Crosshatch-Kernel während der Entwicklung. LTO ist zwar für veröffentlichte Kernel von Vorteil, der Aufwand zur Build-Zeit kann jedoch erheblich sein. Das folgende Snippet, das der lokalen build.config hinzugefügt wird, deaktiviert LTO dauerhaft, wenn build/build.sh verwendet wird.
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)
}
Kernel-Versionen identifizieren
Sie können die richtige Version für den Build aus zwei Quellen ermitteln: dem AOSP-Baum und dem System-Image.
Kernel-Version aus dem AOSP-Baum
Der AOSP-Baum enthält vorgefertigte Kernelversionen. Das Git-Log zeigt die richtige Version als Teil der Commit-Nachricht an:
cd $AOSP/device/VENDOR/NAMEgit log --max-count=1
Wenn die Kernel-Version nicht im Git-Log aufgeführt ist, rufen Sie sie wie unten beschrieben aus dem Systemimage ab.
Kernel-Version aus dem System-Image
Führen Sie den folgenden Befehl für die Kerneldatei aus, um die im Systemimage verwendete Kernelversion zu ermitteln:
file kernel
Führen Sie für Image.lz4-dtb-Dateien Folgendes aus:
grep -a 'Linux version' Image.lz4-dtb
Boot-Image erstellen
Es ist möglich, ein Boot-Image mit der Kernel-Build-Umgebung zu erstellen.
Boot-Image für Geräte mit init_boot erstellen
Bei Geräten mit der Partition init_boot wird das Boot-Image zusammen mit dem Kernel erstellt. Das initramfs-Bild ist nicht in das Boot-Image eingebettet.
Mit Kleaf können Sie beispielsweise das GKI-Boot-Image mit folgendem Befehl erstellen:
tools/bazel run //common:kernel_aarch64_dist [-- --destdir=$DIST_DIR]
Mit build/build.sh (Legacy) können Sie das GKI-Boot-Image mit folgendem Befehl erstellen:
BUILD_CONFIG=common/build.config.gki.aarch64 build/build.sh
Das GKI-Boot-Image befindet sich in $DIST_DIR.
Boot-Image für Geräte ohne init_boot erstellen (Legacy)
Für Geräte ohne init_boot-Partition benötigen Sie eine Ramdisk-Binärdatei, die Sie erhalten, indem Sie ein GKI-Boot-Image herunterladen und es entpacken. Jedes GKI-Boot-Image aus dem zugehörigen Android-Release funktioniert.
tools/mkbootimg/unpack_bootimg.py --boot_img=boot-5.4-gz.img
mv $KERNEL_ROOT/out/ramdisk gki-ramdisk.lz4
Der Zielordner ist das oberste Verzeichnis des Kernel-Baums (das aktuelle Arbeitsverzeichnis).
Wenn Sie mit dem neuesten AOSP-Release-Branch entwickeln, können Sie stattdessen das Build-Artefakt ramdisk-recovery.img aus einem aosp_arm64-Build auf ci.android.com herunterladen und als Ramdisk-Binärdatei verwenden.
Wenn Sie ein Ramdisk-Binärprogramm haben und es in das Stammverzeichnis des Kernel-Builds in gki-ramdisk.lz4 kopiert haben, können Sie ein Boot-Image generieren, indem Sie Folgendes ausführen:
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
Wenn Sie mit einer x86-basierten Architektur arbeiten, ersetzen Sie Image durch bzImage und aarch64 durch 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
Diese Datei befindet sich im Artefaktverzeichnis $KERNEL_ROOT/out/$KERNEL_VERSION/dist.
Das Boot-Image befindet sich unter out/<kernel branch>/dist/boot.img.