Questa pagina descrive in dettaglio il processo di creazione di kernel personalizzati per dispositivi Android. Queste istruzioni ti guidano attraverso il processo di selezione delle fonti giuste, compilazione del kernel e incorporamento dei risultati in un'immagine di sistema creata dall'Android Open Source Project (AOSP).
Puoi acquisire sorgenti del kernel più recenti usando Repo ; creali senza ulteriore configurazione eseguendo build/build.sh
dalla radice del tuo checkout di origine.
Download di fonti e strumenti di compilazione
Per i kernel recenti, usa repo
per scaricare i sorgenti, la toolchain e gli script di compilazione. Alcuni kernel (ad esempio, i kernel Pixel 3) richiedono fonti da più repository git, mentre altri (ad esempio, i kernel comuni) richiedono solo una singola fonte. L'utilizzo dell'approccio repo
garantisce una corretta configurazione della directory di origine.
Scarica i sorgenti per il ramo appropriato:
mkdir android-kernel && cd android-kernel
repo init -u https://android.googlesource.com/kernel/manifest -b BRANCH
repo sync
La tabella seguente elenca i nomi BRANCH per i kernel disponibili tramite questo metodo.
Dispositivo | Percorso binario nell'albero AOSP | Filiali Repo |
---|---|---|
Pixel 7 (pantera) Pixel 7 Pro (ghepardo) | dispositivo/google/pantah-kernel | android-gs-pantah-5.10-android13-qpr2 |
Pixel 6a (bluejay) | dispositivo/google/bluejay-kernel | android-gs-bluejay-5.10-android13-qpr2 |
Pixel 6 (rigogolo) Pixel 6 Pro (corvo) | dispositivo/google/raviole-kernel | android-gs-raviole-5.10-android13-qpr2 |
Pixel 5a (Barbet) Pixel 5 (pinna rossa) Pixel 4a (5G) (rovo) | dispositivo/google/redbull-kernel | android-msm-redbull-4.19-android13-qpr2 |
Pixel 4a (pesce luna) | dispositivo/google/sunfish-kernel | android-msm-sunfish-4.14-android13-qpr2 |
Pixel 4 (fiamma) Pixel 4 XL (corallo) | dispositivo/google/coral-kernel | android-msm-corallo-4.14-android13 |
Pixel 3a (sargo) Pixel 3a XL (bonito) | dispositivo/google/bonito-kernel | android-msm-bonito-4.9-android12L |
Pixel 3 (linea blu) Pixel 3 XL (tratteggio incrociato) | dispositivo/google/crosshatch-kernel | android-msm-crosshatch-4.9-android12 |
Pixel 2 (occhio di lupo) Pixel 2 XL (taimen) | dispositivo/google/wahoo-kernel | android-msm-wahoo-4.4-android10-qpr3 |
Pixel (pesce vela) Pixel XL (marlin) | dispositivo/google/marlin-kernel | android-msm-marlin-3.18-pie-qpr2 |
Hikey960 | device/linaro/hikey-kernel | Hikey-linaro-android-4.14 Hikey-linaro-android-4.19 android-comune12-5.4 android-comune13-5.10 |
Beagle x15 | dispositivo/ti/beagle_x15-kernel | omap-beagle-x15-android-4.14 omap-beagle-x15-android-4.19 |
Kernel comune di Android | N / A | android-comune-4.4 android-comune-4.9 android-comune-4.14 android-comune-4.19 common-android-4.19-stabile android-comune11-5.4 android-comune12-5.4 android-comune 12-5.10 android-comune13-5.10 android-comune13-5.15 android-comune 14-5.15 android-comune 14-6.1 common-android-mainline |
Costruire il kernel
Quindi compila il kernel con questo:
build/build.sh
Il binario del kernel, i moduli e l'immagine corrispondente si trovano nella directory out/ BRANCH /dist
.
Costruire con Bazel (Kleaf)
Android 13 ha introdotto la creazione di kernel con Bazel , sostituendo build/build.sh
.
Per creare il kernel GKI per l'architettura aarch64, controlla un ramo Android Common Kernel non prima di Android 13 e quindi esegui il seguente comando:
tools/bazel build //common:kernel_aarch64_dist
Per creare una distribuzione, eseguire:
tools/bazel run //common:kernel_aarch64_dist -- --dist_dir=$DIST_DIR
Successivamente il binario del kernel, i moduli e le immagini corrispondenti si trovano nella directory $DIST_DIR
. Se --dist_dir
non è specificato, vedere l'output del comando per la posizione degli artefatti. Per i dettagli, fare riferimento alla documentazione su AOSP .
Creazione dei moduli del fornitore per il dispositivo virtuale
Android 11 ha introdotto GKI , che separa il kernel in un'immagine del kernel gestita da Google e in moduli gestiti dal fornitore, che vengono creati separatamente.
Questo esempio mostra una configurazione dell'immagine del kernel:
BUILD_CONFIG=common/build.config.gki.x86_64 build/build.sh
Questo esempio mostra una configurazione del modulo (Cuttlefish ed Emulator):
BUILD_CONFIG=common-modules/virtual-device/build.config.cuttlefish.x86_64 build/build.sh
In Android 12 Cuttlefish e Goldfish convergono, quindi condividono lo stesso kernel: virtual_device
. Per compilare i moduli di quel kernel, usa questa configurazione di compilazione:
BUILD_CONFIG=common-modules/virtual-device/build.config.virtual_device.x86_64 build/build.sh
Android 13 ha introdotto la creazione di kernel con Bazel (Kleaf), sostituendo build.sh
.
Per creare i moduli di virtual_device
, esegui:
tools/bazel build //common-modules/virtual-device:virtual_device_x86_64_dist
Per creare una distribuzione, eseguire:
tools/bazel run //common-modules/virtual-device:virtual_device_x86_64_dist -- --dist_dir=$DIST_DIR
Per maggiori dettagli sulla creazione di kernel Android con Bazel, vedere. Kleaf - Creazione di kernel Android con Bazel .
Per dettagli sul supporto Kleaf per le singole architetture, vedere Supporto Kleaf per dispositivi e kernel .
Supporto Kleaf per dispositivi e kernel
La tabella seguente elenca il supporto Kleaf per i kernel dei singoli dispositivi. Per i dispositivi non in elenco, contattare il produttore del dispositivo.
Dispositivo | Filiali Repo | Supporto Kleaf | supporto build/build.sh |
---|---|---|---|
Kernel comune di Android db845c Dispositivo virtuale (x86_64, arm64) Dispositivo virtuale (i686, braccio) Rockpi4 | android-comune-4.4 android-comune-4.9 android-comune-4.14 android-comune-4.19 common-android-4.19-stabile android-comune11-5.4 android-comune12-5.4 android-comune 12-5.10 | ❌ | ✅ |
Kernel comune di Android | android-comune13-5.10 android-comune13-5.15 | ✅ | ✅ (ufficiale) 1 |
Kernel comune di Android | android-comune 14-5.15 android-comune 14-6.1 common-android-mainline | ✅ | ❌ |
db845c | android-comune13-5.10 | ❌ | ✅ |
db845c | android-comune13-5.15 | ✅ | ✅ (ufficiale) 1 |
db845c | android-comune 14-5.15 android-comune 14-6.1 common-android-mainline | ✅ | ❌ |
Dispositivo virtuale (x86_64, arm64) | android-comune13-5.10 android-comune13-5.15 | ✅ (ufficiale) 1 | ⚠️ (non mantenuto) 2 |
Dispositivo virtuale (x86_64, arm64) | android-comune 14-5.15 android-comune 14-6.1 common-android-mainline | ✅ | ❌ |
Dispositivo virtuale (i686, braccio) | android-comune13-5.10 android-comune13-5.15 | ❌ | ✅ |
Dispositivo virtuale (i686, braccio) | android-comune 14-5.15 android-comune 14-6.1 common-android-mainline | ✅ | ❌ |
Rockpi4 | android-comune13-5.10 android-comune13-5.15 | ❌ | ✅ |
Rockpi4 | android-comune 14-5.15 android-comune 14-6.1 common-android-mainline | ✅ | ❌ |
Hikey960 | Hikey-linaro-android-4.14 Hikey-linaro-android-4.19 android-comune12-5.4 android-comune13-5.10 | ❌ | ✅ |
modulo fips140 | android-comune 12-5.10 android-comune13-5.10 android-comune13-5.15 | ❌ | ✅ |
modulo fips140 | android-comune 14-5.15 | ✅ | ❌ |
1 "Ufficiale" significa che questo è il modo ufficiale per compilare il kernel, anche se potrebbe essere utilizzato anche il modo alternativo per compilare il kernel. 2 "Unmaintained" significa che la compilazione del kernel con questo metodo dovrebbe funzionare, ma il metodo di compilazione non viene testato continuamente. Potrebbe smettere di costruire in futuro. Usa invece il modo "ufficiale" per costruire. |
Esecuzione del kernel
Esistono diversi modi per eseguire un kernel personalizzato. I seguenti sono modi noti adatti a vari scenari di sviluppo.
Incorporamento nella build dell'immagine Android
Copia Image.lz4-dtb
nella rispettiva posizione binaria del kernel all'interno dell'albero AOSP e ricostruisci l'immagine di avvio.
In alternativa, definisci la variabile TARGET_PREBUILT_KERNEL
mentre usi make bootimage
(o qualsiasi altra riga di comando make
che crea un'immagine di avvio). Questa variabile è supportata da tutti i dispositivi poiché è configurata tramite device/common/populate-new-device.sh
. Per esempio:
export TARGET_PREBUILT_KERNEL=DIST_DIR/Image.lz4-dtb
Flashing e avvio del kernel con fastboot
I dispositivi più recenti hanno un'estensione bootloader per semplificare il processo di generazione e avvio di un'immagine di avvio.
Per avviare il kernel senza eseguire il flashing:
adb reboot bootloader
fastboot boot Image.lz4-dtb
Usando questo metodo, il kernel non viene effettivamente aggiornato e non persisterà dopo un riavvio.
Personalizzare la build del kernel
Per personalizzare le build del kernel per le build di Kleaf, consulta la documentazione di Kleaf .
Per build/build.sh
, il processo di compilazione e il risultato possono essere influenzati dalle variabili di ambiente. La maggior parte di essi è facoltativa e ogni ramo del kernel dovrebbe avere una corretta configurazione predefinita. Quelli più frequentemente utilizzati sono elencati qui. Per un elenco completo (e aggiornato), fare riferimento a build/build.sh
.
Variabile d'ambiente | Descrizione | Esempio |
---|---|---|
BUILD_CONFIG | Compila il file di configurazione da dove inizializzi l'ambiente di compilazione. La posizione deve essere definita in relazione alla directory radice di Repo. L'impostazione predefinita è build.config .Obbligatorio per kernel comuni. | BUILD_CONFIG=common/build.config.gki.aarch64 |
CC | Sovrascrivi il compilatore da usare. Ritorna al compilatore predefinito definito da build.config . | CC=clang |
DIST_DIR | Directory di output di base per la distribuzione del kernel. | DIST_DIR=/path/to/my/dist |
OUT_DIR | Directory di output di base per la build del kernel. | OUT_DIR=/path/to/my/out |
SKIP_DEFCONFIG | Salta make defconfig | SKIP_DEFCONFIG=1 |
SKIP_MRPROPER | Salta make mrproper | SKIP_MRPROPER=1 |
Configurazione del kernel personalizzata per build locali
Se è necessario cambiare regolarmente un'opzione di configurazione del kernel, ad esempio, quando si lavora su una funzionalità, o se è necessario impostare un'opzione per scopi di sviluppo, è possibile ottenere tale flessibilità mantenendo una modifica locale o una copia della configurazione di build.
Imposta la variabile POST_DEFCONFIG_CMDS su un'istruzione che viene valutata subito dopo il consueto passaggio make defconfig
. Poiché i file build.config
provengono dall'ambiente di compilazione, le funzioni definite in build.config
possono essere chiamate come parte dei comandi post-defconfig.
Un esempio comune è la disabilitazione dell'ottimizzazione del tempo di collegamento (LTO) per i kernel crosshatch durante lo sviluppo. Sebbene LTO sia vantaggioso per i kernel rilasciati, il sovraccarico al momento della compilazione può essere significativo. Il seguente frammento aggiunto al build.config
locale disabilita LTO in modo persistente quando si utilizza 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)
}
Identificare le versioni del kernel
È possibile identificare la versione corretta da compilare da due origini: l'albero AOSP e l'immagine del sistema.
Versione del kernel dall'albero AOSP
L'albero AOSP contiene versioni del kernel predefinite. Il registro git rivela la versione corretta come parte del messaggio di commit:
cd $AOSP/device/VENDOR/NAME
git log --max-count=1
Se la versione del kernel non è elencata nel registro git, ottenerla dall'immagine di sistema, come descritto di seguito.
Versione del kernel dall'immagine di sistema
Per determinare la versione del kernel utilizzata in un'immagine di sistema, esegui il seguente comando sul file del kernel:
file kernel
Per i file Image.lz4-dtb
, eseguire:
grep -a 'Linux version' Image.lz4-dtb
Creazione di un'immagine di avvio
È possibile creare un'immagine di avvio utilizzando l'ambiente di compilazione del kernel.
Creazione di un'immagine di avvio per dispositivi con init_boot
Per i dispositivi con la partizione init_boot
, l'immagine di avvio viene creata insieme al kernel. L'immagine initramfs
non è incorporata nell'immagine di avvio.
Ad esempio, con Kleaf, puoi creare l'immagine di avvio GKI con:
tools/bazel run //common:kernel_aarch64_dist -- --dist_dir=$DIST_DIR
Con build/build.sh
, puoi creare l'immagine di avvio GKI con:
BUILD_CONFIG=common/build.config.gki.aarch64 build/build.sh
L'immagine di avvio GKI si trova in $DIST_DIR .
Creazione di un'immagine di avvio per dispositivi senza init_boot
Per i dispositivi senza la partizione init_boot
, è necessario un binario ramdisk, che è possibile ottenere scaricando un'immagine di avvio GKI e decomprimendola. Funzionerà qualsiasi immagine di avvio GKI della versione Android associata.
tools/mkbootimg/unpack_bootimg.py --boot_img=boot-5.4-gz.img
mv $KERNEL_ROOT/out/ramdisk gki-ramdisk.lz4
La cartella di destinazione è la directory di primo livello dell'albero del kernel (la directory di lavoro corrente).
Se stai sviluppando con il master AOSP, puoi invece scaricare l'artefatto build ramdisk-recovery.img
da una build aosp_arm64 su ci.android.com e usarlo come binario ramdisk.
Quando hai un binario ramdisk e lo hai copiato in gki-ramdisk.lz4
nella directory principale della build del kernel, puoi generare un'immagine di avvio eseguendo:
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
Se stai lavorando con un'architettura basata su x86, sostituisci Image
con bzImage
e aarch64
con 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
Quel file si trova nella directory degli artefatti $KERNEL_ROOT/out/$KERNEL_VERSION/dist
.
L'immagine di avvio si trova in out/<kernel branch>/dist/boot.img
.