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 6 (Pirol)
Pixel 6 Pro (Rabe)
device/google/raviole-kernel android-gs-raviole-5.10-android12L
Pixel 5a (Barbet) device/google/barbet-kernel android-msm-barbet-4.19-android12L
Pixel 5 (Rotflosse)
Pixel 4a (5G) (Dorn)
gerät/google/redbull-kernel android-msm-redbull-4.19-android12L
Pixel 4a (Mondbarsch) device/google/sunfish-kernel android-msm-sunfish-4.14-android12L
Pixel 4 (Flamme)
Pixel 4 XL (Koralle)
device/google/coral-kernel android-msm-coral-4.14-android12L
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
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-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 .

Erstellen der GKI-Module

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

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

Der Build-Prozess und das Ergebnis können 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 tools/mkbootimg/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 .