Kernel erstellen

Auf dieser Seite wird das Erstellen benutzerdefinierter kernels für Android-Geräte. Diese Anleitung zur Auswahl der richtigen Quellen, Erstellung des Kernels und Einbettung der Ergebnisse in ein System-Image basierend auf dem Android Open Source Project (AOSP).

Aktuellere Kernelquellen können mit Repo abgerufen und ohne weitere Konfiguration erstellt werden, indem Sie build/build.sh im Stammverzeichnis Ihrer Quell-Kasse ausführen.

Quellen und Build-Tools herunterladen

Verwenden Sie für aktuelle Kernel repo, um die Quellcodes, die Toolchain und die Build-Scripts herunterzuladen. Einige Kernel (z. B. die Pixel 3-Kernel) benötigen Quellen von mehreren Git. und bei anderen (z. B. den allgemeinen Kerneln) nur ein einziges Quelle. Mit dem repo-Ansatz wird eine korrekte Quelle sichergestellt. Verzeichniseinrichtung.

Laden Sie die Quellen für den entsprechenden Zweig herunter:

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

Eine Liste der Repository-Branches (BRANCH), die mit dem vorherigen Befehl „repo init“ verwendet werden können, finden Sie unter Kernel-Branches und ihre Build-Systeme.

Weitere Informationen zum Herunterladen und Kompilieren von Kerneln für Pixel-Geräte finden Sie unter Pixel-Kernel erstellen.

Kernel erstellen

Mit Bazel (Kleaf) erstellen

Mit Android 13 wurde das Erstellen von Kerneln mit Bazel eingeführt.

Informationen zum Erstellen einer Distribution für den GKI-Kernel für die aarch64-Architektur finden Sie in Android Common Kernel-Zweig nicht älter als Android 13 und 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 $DIST_DIR-Verzeichnis. Wenn --destdir nicht angegeben ist, siehe Ausgabe des Befehls für den Standort der Artefakte. Weitere Informationen finden Sie in der Dokumentation zu AOSP

Mit build.sh (alte Version) erstellen

Für Branches mit Android 12 oder niedriger ODER für 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

Mit Android 13 wurde das Erstellen von Kerneln mit Bazel (Kleaf) eingeführt, wodurch build.sh ersetzt wurde.

Führen Sie folgenden Befehl aus, um eine Distribution für die Module der virtual_device zu erstellen:

tools/bazel run //common-modules/virtual-device:virtual_device_x86_64_dist [-- --destdir=$DIST_DIR]

Weitere Informationen zum Erstellen von Android-Kerneln mit Bazel finden Sie hier. Kleaf – Android-Kernel mit Bazel erstellen

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 (alt) erstellen

In Android 12 werden Cuttlefish und Goldfish zusammengeführt und teilen sich denselben Kernel: virtual_device. Verwende diesen Build, um die Module dieses Kernels zu erstellen Konfiguration:

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

Mit Android 11 wurde GKI eingeführt, das den 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

Das folgende Beispiel zeigt 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 für verschiedene Entwicklungsszenarien geeignet sind.

In den Android-Image-Build einbetten

Kopieren Sie Image.lz4-dtb an den entsprechenden Speicherort der Kernel-Binärdatei im AOSP-Baum und erstellen Sie das Boot-Image neu.

Alternativ können Sie den TARGET_PREBUILT_KERNEL definieren Variable bei Verwendung von make bootimage (oder einer anderen make-Befehlszeile, die ein Boot-Image erstellt). 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 Starten eines Boot-Images zu optimieren.

So starten Sie den Kernel ohne Flashen:

adb reboot bootloader
fastboot boot Image.lz4-dtb

Bei dieser Methode ist der Kernel nicht tatsächlich geflasht und bleibt nicht erhalten. über einen Neustart hinweg.

Kernel auf Sepia ausführen

Sie können Kernel in der Architektur Ihrer Wahl auf Tintenfisch-Geräte.

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 Zielkernel-Artefakten als Parameter aus. Im folgenden Beispielbefehl werden Kernel-Artefakte für ein arm64-Ziel aus dem common-android14-6.1-Kernelmanifest 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 findest du unter Kleaf-Dokumentation

Kernel-Build mit build.sh (alt) anpassen

Bei build/build.sh können der Buildprozess und das Ergebnis durch Umgebungsvariablen beeinflusst werden. Die meisten sind optional und jeder Kernel-Zweig sollte eine passende Standardkonfiguration. Die am häufigsten verwendeten sind hier aufgeführt. Für eine vollständige (und aktuelle) Liste finden Sie unter build/build.sh.

Umgebungsvariable Beschreibung Beispiel
BUILD_CONFIG Erstellen Sie die Konfigurationsdatei dort, wo Sie die Build-Umgebung initialisieren. Der Speicherort muss relativ zum Stammverzeichnis des Repositorys definiert sein. Die Standardeinstellung ist build.config.
Für gängige Kernel erforderlich.
BUILD_CONFIG=common/build.config.gki.aarch64
CC Überschreibt den zu verwendenden Compiler. Der Standardcompiler, der von build.config definiert wurde, wird wieder verwendet. CC=clang
DIST_DIR Basisausgabeverzeichnis für die Kernel-Distribution DIST_DIR=/path/to/my/dist
OUT_DIR Basisausgabeverzeichnis für den Kernel-Build. OUT_DIR=/path/to/my/out
SKIP_DEFCONFIG Überspringen make defconfig SKIP_DEFCONFIG=1
SKIP_MRPROPER make mrproper überspringen SKIP_MRPROPER=1

Benutzerdefinierte Kernel-Konfiguration für lokale Builds

Unter 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 (alt)

Für Android 13 und niedriger gilt Folgendes.

Wenn Sie eine Kernelkonfigurationsoption regelmäßig wechseln müssen, z. B. bei der Arbeit an einem Feature, oder wenn eine Option für Entwicklungszwecke festgelegt werden muss, können Sie diese Flexibilität durch eine lokale Änderung oder Kopie der Build-Konfiguration erreichen.

Legen Sie die Variable POST_DEFCONFIG_CMDS auf eine Anweisung fest, die direkt nach dem üblichen Schritt make defconfig ausgewertet wird. Da die build.config-Dateien in den Build bezogen werden können die in build.config definierten Funktionen aufgerufen werden als Teil der post-defconfig-Befehle.

Ein gängiges Beispiel ist das Deaktivieren der Link Time-Optimierung (LTO) für Kreuzschraffuren während der Entwicklung. LTO ist zwar für veröffentlichte Kernel von Vorteil, der Overhead bei der Buildzeit kann jedoch erheblich sein. Das folgende Snippet, das der lokalen build.config hinzugefügt wird, deaktiviert LTO dauerhaft bei Verwendung von 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)
}

Kernelversionen ermitteln

Sie können die richtige Version aus zwei Quellen ermitteln: dem AOSP-Baum und dem System-Image.

Kernel-Version aus AOSP-Baum

Die AOSP-Baumstruktur enthält vordefinierte Kernel-Versionen. Git Log zeigt die korrekte Version als Teil der Commit-Nachricht an:

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

Wenn die Kernelversion nicht im Git-Log aufgeführt ist, rufen Sie sie wie unten beschrieben aus dem System-Image ab.

Kernel-Version aus dem System-Image

Führen Sie den folgenden Befehl aus, um die in einem System-Image verwendete Kernel-Version zu ermitteln: für die Kernel-Datei:

file kernel

Führen Sie für Image.lz4-dtb-Dateien folgenden Befehl 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 Bild initramfs ist nicht eingebettet im Boot-Image befinden.

Mit Kleaf können Sie das GKI-Boot-Image beispielsweise mit folgendem Befehl erstellen:

tools/bazel run //common:kernel_aarch64_dist [-- --destdir=$DIST_DIR]

Mit build/build.sh (alt) können Sie das GKI-Boot-Image mit folgenden Tools erstellen:

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

Das GKI-Boot-Image befindet sich unter $DIST_DIR.

Boot-Image für Geräte ohne init_boot erstellen (Legacy)

Für Geräte ohne Partition init_boot benötigen Sie ein Ramdisk-Binärprogramm, das Sie erhalten, indem Sie GKI-Boot-Image herunterladen und auspacken. Es kann jedes GKI-Boot-Image aus der zugehörigen Android-Version verwendet werden.

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 AOSP main entwickeln, können Sie stattdessen das ramdisk-recovery.img-Build-Artefakt aus einem aosp_arm64-Build auf ci.android.com herunterladen und als Ramdisk-Binärdatei verwenden.

Wenn Sie eine Ramdisk-Binärdatei haben und diese nach gki-ramdisk.lz4 im Stammverzeichnis kopiert haben des Kernel-Builds enthält, können Sie mit dem folgenden Befehl ein Boot-Image generieren:

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 mit bzImage und aarch64 mit 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.