Costruzione di kernel

Questa pagina descrive in dettaglio il processo di creazione di kernel personalizzati per i dispositivi Android. Queste istruzioni guidano l'utente attraverso il processo di selezione delle fonti corrette, creazione 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 ; compilali senza ulteriore configurazione eseguendo build/build.sh dalla radice del tuo checkout del codice sorgente.

Download di sorgenti e strumenti di compilazione

Per i kernel recenti, usa il repo per scaricare i sorgenti, la toolchain e gli script di build. Alcuni kernel (ad esempio, i kernel Pixel 3) richiedono sorgenti da più repository git, mentre altri (ad esempio, i kernel comuni) richiedono solo una singola sorgente. L'utilizzo dell'approccio repo garantisce una corretta configurazione della directory di origine.

Scarica i sorgenti per la filiale appropriata:

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 di pronti contro termine
Pixel 6 (rigogolo)
Pixel 6 Pro (corvo)
dispositivo/google/raviole-kernel android-gs-raviole-5.10-android12L
Pixel 5a (barbetto) dispositivo/google/barbet-kernel android-msm-barbet-4.19-android12L
Pixel 5 (pinna rossa)
Pixel 4a (5G) (rovo)
dispositivo/google/redbull-kernel android-msm-redbull-4.19-android12L
Pixel 4a (pesce luna) dispositivo/google/sunfish-kernel android-msm-sunfish-4.14-android12L
Pixel 4 (fiamma)
Pixel 4 XL (corallo)
dispositivo/google/coral-kernel android-msm-coral-4.14-android12L
Pixel 3a (sargo)
Pixel 3a XL (buongustaio)
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 (walleye)
Pixel 2 XL (nero)
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 hiking-linaro-android-4.14
hiking-linaro-android-4.19
common-android12-5.4
Beagle x15 dispositivo/ti/beagle_x15-kernel omap-beagle-x15-android-4.14
omap-beagle-x15-android-4.19
Kernel comune Android N / A common-android-4.4
common-android-4.9
common-android-4.14
common-android-4.19
common-android-4.19-stabile
common-android11-5.4
common-android12-5.4
common-android12-5.10
common-android-mainline

Costruire il kernel

Quindi costruisci 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 i moduli GKI

Android 11 ha introdotto GKI , che separa il kernel in un'immagine del kernel gestita da Google e moduli gestiti dal fornitore, che sono costruiti 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 (Seppia ed Emulatore):

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 costruire i moduli di quel kernel, usa questa configurazione di build:

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

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, definire la variabile TARGET_PREBUILT_KERNEL durante l'utilizzo make bootimage (o qualsiasi altra riga di comando make che costruisce un'immagine di avvio). Questa variabile è supportata da tutti i dispositivi poiché è impostata tramite device/common/populate-new-device.sh . Per esempio:

export TARGET_PREBUILT_KERNEL=DIST_DIR/Image.lz4-dtb

Kernel lampeggiante e di avvio con fastboot

I dispositivi più recenti hanno un'estensione del bootloader per semplificare il processo di generazione e avvio di un'immagine di avvio.

Per avviare il kernel senza lampeggiare:

adb reboot bootloader
fastboot boot Image.lz4-dtb

Usando questo metodo, il kernel non viene effettivamente eseguito il flashing e non persisterà durante un riavvio.

Personalizzazione della build del kernel

Il processo di costruzione e il risultato possono essere influenzati da variabili ambientali. La maggior parte di essi sono opzionali e ogni ramo del kernel dovrebbe avere una configurazione predefinita adeguata. Quelli più 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 rispetto alla directory principale del Repo. Il valore predefinito build.config .
Obbligatorio per i kernel comuni.
BUILD_CONFIG=common/build.config.gki.aarch64
CC Eseguire l'override del compilatore da utilizzare. 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 è necessaria un'opzione da impostare per scopi di sviluppo, è possibile ottenere tale flessibilità mantenendo una modifica locale o una copia della configurazione di build.

Impostare la variabile POST_DEFCONFIG_CMDS su un'istruzione che viene valutata subito dopo il normale passaggio make defconfig . Poiché i file build.config vengono originati nell'ambiente di build, 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 in fase di compilazione può essere significativo. Il frammento di codice seguente 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)
}

Identificazione delle versioni del kernel

È possibile identificare la versione corretta da compilare da due fonti: l'albero AOSP e l'immagine di sistema.

Versione del kernel dall'albero AOSP

L'albero AOSP contiene versioni del kernel precompilate. 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, eseguire il comando seguente sul file del kernel:

file kernel

Per i file Image.lz4-dtb , eseguire:

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

Costruire un'immagine di avvio

È possibile creare un'immagine di avvio utilizzando l'ambiente di compilazione del kernel. Per fare ciò è necessario un binario ramdisk, che è possibile ottenere scaricando un'immagine di avvio GKI e decomprimendola. Qualsiasi immagine di avvio GKI dalla versione Android associata funzionerà.

tools/mkbootimg/unpack_bootimg.py --boot_img=boot-5.4-gz.img
mv tools/mkbootimg/out/ramdisk gki-ramdisk.lz4

La cartella di destinazione è la directory di livello superiore dell'albero del kernel (la directory di lavoro corrente).

Se stai sviluppando con AOSP master, 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 $KERNEL_ROOT/out/$KERNEL_VERSION/dist .

L'immagine di avvio si trova in out/<kernel branch>/dist/boot.img .