Aufbau von Kerneln

Auf dieser Seite wird der Vorgang zum Erstellen benutzerdefinierter Kernel für Android-Geräte beschrieben. Diese Anweisungen führen Sie durch den Prozess der Auswahl der richtigen Quellen, der Erstellung des Kernels und der Einbettung der Ergebnisse in ein Systemabbild, das aus dem Android Open Source Project (AOSP) erstellt wurde.

Sie können neuere Kernel-Quellen erwerben, indem Sie Repo verwenden; Erstellen Sie sie ohne weitere Konfiguration, indem build/build.sh im Stammverzeichnis Ihres Quell-Checkouts ausführen.

Herunterladen von Quellen und Build-Tools

Verwenden Sie für neuere Kernel repo , um die Quellen, die Toolchain und die Build-Skripte herunterzuladen. Einige Kernel (z. B. die Pixel 3-Kernel) erfordern Quellen aus mehreren Git-Repositories, während andere (z. B. die gemeinsamen Kernel) nur eine einzige Quelle benötigen. Die Verwendung des repo -Ansatzes stellt eine korrekte Einrichtung des Quellverzeichnisses sicher.

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

Die folgende Tabelle listet die BRANCH Namen für Kernel auf, die über diese Methode verfügbar sind.

Gerät Binärer Pfad im AOSP-Baum Repo-Filialen
Pixel 7 (Panther)
Pixel 7 Pro (Gepard)
device/google/pantah-kernel android-gs-pantah-5.10-android13-d1
Pixel 6a (Bluejay) device/google/bluejay-kernel android-gs-bluejay-5.10-android13
Pixel 6 (Pirol)
Pixel 6 Pro (Rabe)
device/google/raviole-kernel android-gs-raviole-5.10-android13
Pixel 5a (Barbet) device/google/barbet-kernel android-msm-barbet-4.19-android13
Pixel 5 (Rotflosse)
Pixel 4a (5G) (Dorn)
gerät/google/redbull-kernel android-msm-redbull-4.19-android13
Pixel 4a (Mondbarsch) device/google/sunfish-kernel android-msm-sunfish-4.14-android13
Pixel 4 (Flamme)
Pixel 4 XL (Koralle)
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 (blaue Linie)
Pixel 3 XL (Kreuzschraffur)
device/google/crosshatch-kernel android-msm-crosshatch-4.9-android12
Pixel 2 (Zander)
Pixel 2 XL (Taimen)
device/google/wahoo-kernel android-msm-wahoo-4.4-android10-qpr3
Pixel (Segelfisch)
Pixel XL (Marline)
gerät/google/marlin-kernel android-msm-marlin-3.18-pie-qpr2
Hikey960 gerät/linaro/hikey-kernel walky-linaro-android-4.14
walky-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
Gemeinsamer Android-Kernel 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-android-mainline

Aufbau des Kernels

Bauen Sie dann den Kernel damit:

build/build.sh

Die Kernel-Binärdatei, die Module und das entsprechende Image befinden sich im Verzeichnis out/ BRANCH /dist .

Bauen mit Bazel (Kleaf)

Android 13 führte das Bauen von Kerneln mit Bazel ein und ersetzte build/build.sh .

Um den GKI-Kernel für die aarch64-Architektur zu erstellen, checken Sie einen Android Common Kernel-Zweig nicht früher als Android 13 aus und führen Sie dann den folgenden Befehl aus:

tools/bazel build //common:kernel_aarch64_dist

Um eine Verteilung zu erstellen, führen Sie Folgendes aus:

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

Danach befinden sich die Kernel-Binärdatei, Module und entsprechende Bilder im Verzeichnis $DIST_DIR . Wenn --dist_dir nicht angegeben ist, finden Sie die Position der Artefakte in der Ausgabe des Befehls. Einzelheiten finden Sie in der Dokumentation zu AOSP .

Erstellen der Anbietermodule für das virtuelle Gerät

Android 11 führte GKI ein, das den Kernel in ein von Google verwaltetes Kernel-Image und vom Hersteller verwaltete Module aufteilt, die separat erstellt werden.

Dieses Beispiel zeigt eine Kernel-Image-Konfiguration:

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

In Android 12 konvergieren Cuttlefish und Goldfish, sodass sie denselben Kernel teilen: virtual_device . Um die Module dieses Kernels zu erstellen, verwenden Sie diese Build-Konfiguration:

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

Android 13 führte Baukerne mit Bazel (Kleaf) ein und ersetzte build.sh .

Um die Module von virtual_device zu erstellen, führen Sie Folgendes aus:

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

Um eine Verteilung zu erstellen, führen Sie Folgendes aus:

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

Weitere Einzelheiten zum Erstellen von Android-Kernels mit Bazel finden Sie unter. Kleaf – Erstellen von Android-Kernels mit Bazel .

Einzelheiten zur Kleaf-Unterstützung für einzelne Architekturen finden Sie unter Kleaf-Unterstützung für Geräte und Kernel .

Kleaf-Unterstützung für Geräte und Kernel

Die folgende Tabelle listet die Kleaf-Unterstützung für einzelne Gerätekerne auf. Bei nicht aufgeführten Geräten wenden Sie sich bitte an den Gerätehersteller.

Gerät Repo-Filialen Kleaf-Unterstützung build/build.sh Unterstützung
Gemeinsamer Android-Kernel
db845c
Virtuelles Gerät (x86_64, arm64)
Virtuelles Gerät (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
Gemeinsamer Android-Kernel common-android13-5.10
common-android13-5.15
✅ (offiziell) 1
Gemeinsamer Android-Kernel common-android14-5.15
common-android-mainline
db845c common-android13-5.10
db845c common-android13-5.15 ✅ (offiziell) 1
db845c common-android14-5.15
common-android-mainline
Virtuelles Gerät (x86_64, arm64) common-android13-5.10
common-android13-5.15
✅ (offiziell) 1 ⚠️ (ungewartet) 2
Virtuelles Gerät (x86_64, arm64) common-android14-5.15
common-android-mainline
Virtuelles Gerät (i686, arm) common-android13-5.10
common-android13-5.15
Virtuelles Gerät (i686, Arm) common-android14-5.15
common-android-mainline
Rockpi4 common-android13-5.10
common-android13-5.15
Rockpi4 common-android14-5.15
common-android-mainline
Hikey960 walky-linaro-android-4.14
walky-linaro-android-4.19
common-android12-5.4
common-android13-5.10
fips140-Modul common-android12-5.10
common-android13-5.10
common-android13-5.15
fips140-Modul common-android14-5.15
common-android-mainline

1 „Offiziell“ bedeutet, dass dies der offizielle Weg ist, den Kernel zu bauen, obwohl auch der alternative Weg zum Bauen des Kernels verwendet werden könnte.

2 „Unmaintained“ bedeutet, dass das Bauen des Kernels mit dieser Methode funktionieren sollte, aber die Baumethode wird nicht kontinuierlich getestet. Es kann sein, dass der Bau in Zukunft eingestellt wird. Verwenden Sie stattdessen die "offizielle" Methode zum Erstellen.

Ausführen des Kernels

Es gibt mehrere Möglichkeiten, einen benutzerdefinierten Kernel auszuführen. Das Folgende sind bekannte Wege, die für verschiedene Entwicklungsszenarien geeignet sind.

Einbetten in den Android-Image-Build

Kopieren Image.lz4-dtb an den entsprechenden binären Speicherort des Kernels innerhalb des AOSP-Baums und erstellen Sie das Boot-Image neu.

Definieren Sie alternativ die Variable TARGET_PREBUILT_KERNEL , während Sie make bootimage verwenden (oder eine andere 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. Zum Beispiel:

export TARGET_PREBUILT_KERNEL=DIST_DIR/Image.lz4-dtb

Kernel mit Fastboot flashen und booten

Die neuesten Geräte verfügen über eine Bootloader-Erweiterung, um den Prozess des Generierens und Bootens eines Boot-Images zu optimieren.

So booten Sie den Kernel ohne zu flashen:

adb reboot bootloader
fastboot boot Image.lz4-dtb

Bei dieser Methode wird der Kernel nicht wirklich geflasht und bleibt auch bei einem Neustart nicht bestehen.

Anpassen des Kernel-Builds

Informationen zum Anpassen der Kernel-Builds für Kleaf-Builds finden Sie in der Kleaf-Dokumentation .

Bei build/build.sh können der Build-Prozess und das Ergebnis durch Umgebungsvariablen beeinflusst werden. Die meisten von ihnen sind optional und jeder Kernel-Zweig sollte mit einer geeigneten Standardkonfiguration geliefert werden. Die am häufigsten verwendeten sind hier aufgelistet. Eine vollständige (und aktuelle) Liste finden Sie unter build/build.sh .

Umgebungsvariable Beschreibung Beispiel
BUILD_CONFIG Build-Konfigurationsdatei, von der aus Sie die Build-Umgebung initialisieren. Der Speicherort muss relativ zum Repo-Stammverzeichnis definiert werden. build.config .
Obligatorisch für gängige Kernel.
BUILD_CONFIG=common/build.config.gki.aarch64
CC Zu verwendenden Compiler überschreiben. Fällt auf den von build.config definierten Standardcompiler zurück. CC=clang
DIST_DIR Basis-Ausgabeverzeichnis 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 make defconfig SKIP_DEFCONFIG=1
SKIP_MRPROPER make mrproper SKIP_MRPROPER=1

Benutzerdefinierte Kernel-Konfiguration für lokale Builds

Wenn Sie eine Kernel-Konfigurationsoption regelmäßig wechseln müssen, beispielsweise 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.

Setzen Sie die Variable POST_DEFCONFIG_CMDS auf eine Anweisung, die ausgewertet wird, nachdem der übliche Schritt make defconfig wurde. Da die build.config Dateien in die Build-Umgebung eingespeist werden, können in build.config definierte Funktionen als Teil der post-defconfig-Befehle aufgerufen werden.

Ein gängiges Beispiel ist das Deaktivieren der Verbindungszeitoptimierung (LTO) für Crosshatch-Kernel während der Entwicklung. Während LTO für freigegebene Kernel vorteilhaft ist, kann der Overhead zur Build-Zeit erheblich sein. Das folgende zur lokalen build.config hinzugefügte Snippet deaktiviert LTO dauerhaft, wenn 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)
}

Identifizieren von Kernel-Versionen

Sie können die richtige zu erstellende Version aus zwei Quellen ermitteln: dem AOSP-Baum und dem Systemabbild.

Kernel-Version aus dem AOSP-Baum

Der AOSP-Baum enthält vorgefertigte Kernel-Versionen. Das Git-Log zeigt die korrekte Version als Teil der Commit-Nachricht:

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

Wenn die Kernel-Version nicht im Git-Protokoll aufgeführt ist, beziehen Sie sie wie unten beschrieben aus dem System-Image.

Kernel-Version aus System-Image

Um die in einem Systemabbild verwendete Kernelversion zu ermitteln, führen Sie den folgenden Befehl für die Kerneldatei aus:

file kernel

Führen Sie für Image.lz4-dtb Dateien Folgendes aus:

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

Erstellen eines Boot-Images

Es ist möglich, ein Boot-Image mit der Kernel-Build-Umgebung zu erstellen. Dazu benötigen Sie eine Ramdisk-Binärdatei, die Sie erhalten, indem Sie ein GKI-Boot-Image herunterladen und entpacken. Jedes GKI-Boot-Image aus der zugehörigen Android-Version 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 Kernelbaums (das aktuelle Arbeitsverzeichnis).

Wenn Sie mit AOSP-Master entwickeln, können Sie stattdessen das Build-Artefakt ramdisk ramdisk-recovery.img von einem aosp_arm64-Build auf ci.android.com herunterladen und dieses als Ihre Ramdisk-Binärdatei verwenden.

Wenn Sie eine Ramdisk-Binärdatei haben und diese nach gki-ramdisk.lz4 im Stammverzeichnis des Kernel-Builds 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 Artifact-Verzeichnis $KERNEL_ROOT/out/$KERNEL_VERSION/dist .

Das Boot-Image befindet sich unter out/<kernel branch>/dist/boot.img .