Creazione di kernel

Questa pagina descrive in dettaglio la procedura di creazione di kernel per i dispositivi Android. Questi istruzioni ti guidano nella procedura di selezione del giusto sorgente, creare il kernel e incorporare i risultati in un'immagine di sistema basato su Android Open Source Project (AOSP).

Puoi acquisire origini kernel più recenti utilizzando Repo; creandoli senza dover eseguire eseguendo build/build.sh dalla directory principale pagamento sorgente.

Scarica origini e strumenti di creazione

Per i kernel recenti, usa repo per scaricare i sorgenti, la toolchain e gli script di creazione. Alcuni kernel (ad esempio quelli di Pixel 3) richiedono origini da più file Git mentre altri (ad esempio i kernel comuni) richiedono una singola sorgente. L'utilizzo dell'approccio repo garantisce che la fonte sia corretta configurazione della directory di amministrazione.

Scarica le origini per il ramo appropriato:

mkdir android-kernel && cd android-kernel
repo init -u https://android.googlesource.com/kernel/manifest -b BRANCH
repo sync

Per un elenco di rami di repository (BRANCH) che possono essere utilizzati con la precedente il comando "repo init", consulta Ramo del kernel e relativi sistemi di build.

Per maggiori dettagli sul download e la compilazione dei kernel per i dispositivi Pixel, vedi Creazione dei kernel Pixel.

crea il kernel

Crea con Bazel (Kleaf)

Android 13 ha introdotto la creazione di kernel con Bazel.

Per creare il kernel GKI per l'architettura aarch64, controlla un ramo Android Common Kernel non precedente ad Android 13 e quindi esegui questo comando:

tools/bazel build //common:kernel_aarch64_dist

Per creare una distribuzione, esegui:

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

Dopodiché il programma binario del kernel, i moduli e le immagini corrispondenti si trovano Directory $DIST_DIR. Se --dist_dir non è specificato, visualizza l'output del comando per la posizione degli artefatti. Per maggiori dettagli, consulta documentazione su AOSP.

Crea con build.sh (legacy)

Per rami con Android 12 o versioni precedenti, OPPURE rami senza Kleaf:

build/build.sh

Il file binario del kernel, i moduli e l'immagine corrispondente si trovano nella Directory out/BRANCH/dist.

Crea i moduli del fornitore per il dispositivo virtuale

Android 13 ha introdotto la creazione di kernel con Bazel (Kleaf), in sostituzione di 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, esegui:

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, vedi. Kleaf - Building Android Kernels with Bazel.

Per maggiori dettagli sul supporto di Kleaf per le singole architetture, vedi Supporto di Kleaf per dispositivi e kernel.

Crea i moduli del fornitore per il dispositivo virtuale con build.sh (legacy)

In Android 12 Seppia e Pesce rosso convergono, quindi lo stesso kernel: virtual_device. Per creare i moduli del kernel, usa questa build configurazione:

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

Introduzione ad Android 11 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 la configurazione di un'immagine kernel:

BUILD_CONFIG=common/build.config.gki.x86_64 build/build.sh

Questo esempio mostra la configurazione di un modulo (Seppia ed Emulatore):

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

esegui il kernel

Ci sono diversi modi per eseguire un kernel personalizzato. Di seguito sono riportate le metodi noti adatti a vari scenari di sviluppo.

Incorpora nella build di immagini Android

Copia Image.lz4-dtb nella rispettiva posizione binaria del kernel nell'albero AOSP e ricreare l'immagine di avvio.

In alternativa, definisci il valore TARGET_PREBUILT_KERNEL mentre utilizzi make bootimage (o qualsiasi altra variabile make che crea un'immagine di avvio). Questa variabile è supportata da tutti i dispositivi così come è configurata tramite device/common/populate-new-device.sh. Ad esempio:

export TARGET_PREBUILT_KERNEL=DIST_DIR/Image.lz4-dtb

Flash e avvio dei kernel con fastboot

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

Per avviare il kernel senza flashare:

adb reboot bootloader
fastboot boot Image.lz4-dtb

Con questo metodo, il kernel non esegue il flashing e non viene mantenuto durante un riavvio.

Eseguire kernel su Seppia

Puoi eseguire i kernel nell'architettura che preferisci su Dispositivi seppia.

Per avviare un dispositivo Seppia con un determinato insieme di kernel artefatti, esegui il comando cvd start con gli artefatti del kernel di destinazione parametri. Il comando di esempio seguente utilizza gli artefatti del kernel per una destinazione arm64 dal Manifest del kernel common-android14-6.1.

cvd start \
    -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

Per ulteriori informazioni, vedi Sviluppare kernel su Cuttlefish.

Personalizza la build del kernel

Per personalizzare le build del kernel per le build Kleaf, vedi Documentazione di Kleaf.

Personalizza la build del kernel con build.sh (legacy)

Per build/build.sh, il processo di compilazione e i risultati possono essere influenzati in base alle variabili di ambiente. La maggior parte è facoltativa e ogni ramo del kernel dovrebbe avere un indirizzo configurazione predefinita. Quelli più utilizzati sono elencati qui. Per un elenco completo (e aggiornato), consulta build/build.sh.

Variabile di ambiente Descrizione Esempio
BUILD_CONFIG Il file di configurazione della build da cui inizializza l'ambiente di build. La località deve essere definita rispetto alla radice del repository . Il valore predefinito è build.config.
Obbligatorio per i kernel comuni.
BUILD_CONFIG=common/build.config.gki.aarch64
CC Esegui l'override del compilatore da utilizzare. Torna al valore predefinito compilatore 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 kernel personalizzata per build locali

In Android 14 e versioni successive, puoi utilizzare frammenti defconfig per personalizzare le configurazioni del kernel. vedi Documentazione di Kleaf sui frammenti defconfig.

Configurazione kernel personalizzata per build locali con configurazioni di build (legacy)

In Android 13 e versioni precedenti, vedi quanto segue.

Se devi cambiare regolarmente un'opzione di configurazione del kernel, ad esempio, quando si lavora a una funzionalità o se è necessario impostare un'opzione per lo sviluppo degli scopi, puoi raggiungere tale flessibilità mantenendo un ambiente una modifica o una copia della configurazione della build.

Imposta la variabile POST_DEFCONFIG_CMDS su un'istruzione che sia valutato subito dopo il solito make defconfig passaggio fatto. Poiché i file build.config provengono dalla build le funzioni definite in build.config possono essere chiamate come parte dei comandi post-defconfig.

Un esempio comune è la disattivazione dell'ottimizzazione del tempo dei link (LTO) per i crosshatch durante lo sviluppo. Sebbene LTO sia vantaggioso per i kernel rilasciati, l'overhead al momento della creazione può essere significativo. È stato aggiunto il seguente snippet al build.config locale disabilita l'LTO in modo permanente quando utilizzando 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

Puoi identificare la versione corretta da creare da due origini: l'albero AOSP e l'immagine di sistema.

Versione kernel dall'albero AOSP

L'albero AOSP contiene versioni del kernel predefinite. Git mostra la versione corretta del messaggio di commit:

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

Se la versione del kernel non è elencata nel log git, recuperala dal sistema come descritto di seguito.

Versione kernel dall'immagine di sistema

Per determinare la versione del kernel utilizzata in un'immagine di sistema, esegui questo comando sul file del kernel:

file kernel

Per Image.lz4-dtb file, esegui:

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

Crea un'immagine di avvio

È possibile creare un'immagine di avvio utilizzando l'ambiente di build del kernel.

Crea un'immagine di avvio per i 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 (legacy), 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.

Crea un'immagine di avvio per i dispositivi senza init_boot (legacy)

Per i dispositivi senza la partizione init_boot, ti serve un file binario ramdisk, che puoi ottenere download di un'immagine di avvio GKI e lo decomprime. Qualsiasi immagine di avvio GKI della release di Android associata funzionerà.

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 (l'interfaccia directory di lavoro).

Se stai sviluppando con il programma principale AOSP, puoi scaricare il file ramdisk-recovery.img artefatto della build da una build aosp_arm64 su ci.android.com e lo useremo come binario ramdisk.

Dopo aver copiato un file binario ramdisk in gki-ramdisk.lz4 nella directory radice 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 utilizzi 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

Il file si trova nella directory Artifact Registry $KERNEL_ROOT/out/$KERNEL_VERSION/dist.

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