Auf dieser Seite wird beschrieben, wie Sie benutzerdefinierte Kernel für Android-Geräte erstellen. In dieser Anleitung erfahren Sie, wie Sie die richtigen Quellen auswählen, den Kernel erstellen und die Ergebnisse in ein System-Image einbetten, das aus dem Android Open Source Project (AOSP) erstellt wurde.
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.
Quellcode 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 aus mehreren Git-Repositories, während andere (z. B. die gemeinsamen Kernel) nur eine einzige Quelle erfordern. Mit dem repo
-Ansatz wird die korrekte Einrichtung des Quellverzeichnisses sichergestellt.
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 Befehl „repo init“ verwendet werden können, finden Sie unter Kernel-Zweige und zugehörige Build-Systeme.
Weitere Informationen zum Herunterladen und Kompilieren von Kerneln für Pixel-Geräte finden Sie unter Google Pixel-Kernel erstellen.
Kernel erstellen
Mit Bazel (Kleaf) erstellen
Mit Android 13 wurde das Erstellen von Kerneln mit Bazel eingeführt.
Wenn Sie eine Distribution für den GKI-Kernel für die aarch64-Architektur erstellen möchten, klonen Sie einen Android Common Kernel-Branch, 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 das Kernel-Binary, die Module und die entsprechenden Images im Verzeichnis $DIST_DIR
. Wenn --destdir
nicht angegeben ist, finden Sie den Speicherort der Artefakte in der Ausgabe des Befehls. Weitere Informationen finden Sie in der Dokumentation zu AOSP.
Mit build.sh (alt) 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 wurden die Erstellung von Kernels mit Bazel (Kleaf) eingeführt und build.sh
ersetzt.
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
. Verwenden Sie diese Build-Konfiguration, um die Module dieses 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, das den Kernel in ein von Google verwaltetes Kernel-Image und von Anbietern verwaltete Module unterteilt, die separat erstellt werden.
Dieses Beispiel zeigt die Konfiguration eines Kernel-Images:
BUILD_CONFIG=common/build.config.gki.x86_64 build/build.sh
Dieses 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 das 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 die TARGET_PREBUILT_KERNEL
-Variable auch mit make bootimage
(oder einer anderen make
-Befehlszeile, mit der ein Boot-Image erstellt wird) definieren. 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 Flashing:
adb reboot bootloader
fastboot boot Image.lz4-dtb
Bei dieser Methode wird der Kernel nicht geflasht und bleibt nach einem Neustart nicht erhalten.
Kernel auf Cuttlefish ausführen
Sie können Kernel in der Architektur Ihrer Wahl auf Cuttlefish-Geräten ausführen.
Wenn Sie ein Cuttlefish-Gerät mit einem bestimmten Satz von Kernel-Artefakten starten möchten, führen Sie den Befehl cvd create
mit den Ziel-Kernel-Artefakten als Parameter aus. Im folgenden Beispiel wird ein Befehl verwendet, der 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 finden Sie in der 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 davon sind optional und jeder Kernel-Zweig sollte eine ordnungsgemäße Standardkonfiguration haben. Die am häufigsten verwendeten sind hier aufgeführt. Eine vollständige (und aktuelle) Liste finden Sie unter build/build.sh
.
Umgebungsvariable | Beschreibung | Verwendungsbeispiele |
---|---|---|
BUILD_CONFIG |
Build-Konfigurationsdatei, über die Sie die Buildumgebung 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 Kernelverteilung. | 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 |
Überspringen make mrproper |
SKIP_MRPROPER=1 |
Benutzerdefinierte Kernelkonfiguration 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 die Build-Umgebung aufgenommen werden, können in build.config
definierte Funktionen als Teil der Befehle nach der Defconfig aufgerufen werden.
Ein häufiges Beispiel ist die Deaktivierung der Linkzeitoptimierung (LTO) für Kreuzstich-Kernel während der Entwicklung. LTO ist zwar vorteilhaft für freigegebene Kernels, der Aufwand zum Build-Zeit kann jedoch erheblich sein. Das folgende Snippet, das dem 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)
}
Kernelversionen ermitteln
Sie können die richtige Version zum Erstellen aus zwei Quellen ermitteln: dem AOSP-Baum und dem System-Image.
Kernelversion aus dem AOSP-Baum
Der AOSP-Baum enthält vorgefertigte Kernelversionen. Das Git-Log zeigt die korrekte Version als Teil der Commit-Nachricht an:
cd $AOSP/device/VENDOR/NAME
git log --max-count=1
Wenn die Kernel-Version nicht im Git-Log aufgeführt ist, rufen Sie sie wie unten beschrieben aus dem System-Image ab.
Kernel-Version aus dem System-Image
Um die in einem System-Image verwendete Kernelversion zu ermitteln, führen Sie den folgenden Befehl auf die Kerneldatei aus:
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
-Image ist nicht in das Boot-Image eingebettet.
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 (alt) erstellen
Für Geräte ohne init_boot
-Partition benötigen Sie eine Ramdisk-Binärdatei. Sie können sie erhalten, indem Sie ein GKI-Boot-Image herunterladen und entpacken. 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 sie in das Stammverzeichnis des Kernel-Builds (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
.