Questa pagina descrive in dettaglio il processo di creazione di kernel personalizzati per i dispositivi Android. Queste istruzioni ti guidano nel processo di selezione delle fonti corrette, creazione del kernel e incorporamento dei risultati in un'immagine di sistema creata a partire dall'Android Open Source Project (AOSP).
Scarica le origini e gli strumenti di compilazione
Per i kernel recenti, utilizza repo
per scaricare le origini, 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 una sola sorgente. L'utilizzo dell'approccio repo
garantisce una configurazione corretta
della directory di origine.
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 dei rami del repository (BRANCH) che possono essere utilizzati con il comando `repo init` precedente, consulta Rami del kernel e relativi sistemi di build.
Per informazioni dettagliate sul download e la compilazione dei kernel per i dispositivi Pixel, consulta Creazione di kernel Pixel.
Crea il kernel
Build with Bazel (Kleaf)
Android 13 ha introdotto la creazione di kernel con Bazel.
Per creare una distribuzione per il kernel GKI per l'architettura aarch64, controlla un ramo del kernel comune Android non precedente ad Android 13 e poi esegui questo comando:
tools/bazel run //common:kernel_aarch64_dist [-- --destdir=$DIST_DIR]
Successivamente, il file binario del kernel, i moduli e le immagini corrispondenti si trovano nella directory
$DIST_DIR
. Se --destdir
non è specificato, consulta l'output
del comando per la posizione degli artefatti. Per maggiori dettagli, consulta la
documentazione su AOSP.
Creare con build.sh (legacy)
Per i 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), sostituendo build.sh
.
Per creare una distribuzione per i moduli di virtual_device
, esegui:
tools/bazel run //common-modules/virtual-device:virtual_device_x86_64_dist [-- --destdir=$DIST_DIR]
Per maggiori dettagli sulla creazione di kernel Android con Bazel, consulta. Kleaf - Building Android Kernels with Bazel.
Per informazioni dettagliate 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 Cuttlefish e Goldfish convergono, quindi condividono
lo stesso kernel: virtual_device
. Per creare i moduli del kernel, utilizza questa configurazione
di build:
BUILD_CONFIG=common-modules/virtual-device/build.config.virtual_device.x86_64 build/build.sh
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 compilati 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
Esegui il kernel
Esistono diversi modi per eseguire un kernel personalizzato. Di seguito sono riportati metodi noti adatti a vari scenari di sviluppo.
Incorporare nella build dell'immagine Android
Copia Image.lz4-dtb
nella posizione del file binario del kernel corrispondente
all'interno della struttura AOSP e ricompila l'immagine di avvio.
In alternativa, definisci la variabile TARGET_PREBUILT_KERNEL
durante l'utilizzo di make bootimage
(o di qualsiasi altra
riga di comando make
che crea un'immagine di avvio). Questa variabile è
supportata da tutti i dispositivi perché è configurata tramite
device/common/populate-new-device.sh
. Ad esempio:
export TARGET_PREBUILT_KERNEL=DIST_DIR/Image.lz4-dtb
Flashare e avviare i kernel 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 eseguire il flashing:
adb reboot bootloader
fastboot boot Image.lz4-dtb
Se utilizzi questo metodo, il kernel non viene effettivamente flashato e non viene mantenuto dopo un riavvio.
Esegui kernel su Cuttlefish
Puoi eseguire kernel nell'architettura che preferisci sui dispositivi Cuttlefish.
Per avviare un dispositivo Cuttlefish con un particolare insieme di artefatti
del kernel, esegui il comando cvd create
con gli artefatti del kernel di destinazione come
parametri. Il seguente comando di esempio utilizza gli artefatti del kernel per una destinazione arm64 dal
manifest del kernel common-android14-6.1
.
cvd create \
-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 saperne di più, consulta Sviluppare kernel su Cuttlefish.
Personalizzare la build del kernel
Per personalizzare le build del kernel per le build Kleaf, consulta la documentazione di Kleaf.
Personalizzare la build del kernel con build.sh (legacy)
Per build/build.sh
, il processo di compilazione e il risultato possono essere influenzati
dalle variabili di ambiente.
La maggior parte sono facoltative e ogni ramo del kernel deve essere fornito con una configurazione predefinita corretta. Di seguito sono elencati quelli più utilizzati. Per un elenco
completo e aggiornato, consulta build/build.sh
.
Variabile di ambiente | Descrizione | Esempio |
---|---|---|
BUILD_CONFIG |
File di configurazione della build da cui inizializzi l'ambiente di build.
La posizione deve essere definita rispetto alla directory 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. Esegue il fallback 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 personalizzata del kernel per le build locali
In Android 14 e versioni successive, puoi utilizzare i frammenti di defconfig per personalizzare le configurazioni del kernel. Consulta la documentazione di Kleaf sui frammenti di defconfig.
Configurazione del 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 lavori su una funzionalità o se hai bisogno di un'opzione da impostare per scopi di sviluppo, puoi ottenere questa flessibilità mantenendo una modifica o una copia locale della configurazione di build.
Imposta la variabile POST_DEFCONFIG_CMDS su un'istruzione che viene
valutata subito dopo il completamento del passaggio make defconfig
standard. Poiché i file build.config
vengono inseriti nell'ambiente di build, le funzioni definite in build.config
possono essere chiamate nell'ambito dei comandi post-defconfig.
Un esempio comune è la disattivazione dell'ottimizzazione in fase di collegamento (LTO) per i kernel crosshatch
durante lo sviluppo. Sebbene l'LTO sia utile per i kernel rilasciati,
l'overhead in fase di compilazione può essere significativo. Il seguente snippet aggiunto
al file build.config
locale disabilita LTO in modo permanente quando
utilizzi 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 cui eseguire la build da due origini: l'albero AOSP e l'immagine di sistema.
Versione del kernel dall'albero AOSP
L'albero AOSP contiene versioni del kernel precompilate. Il log 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 log Git, recuperala 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
, esegui:
grep -a 'Linux version' Image.lz4-dtb
Crea un'immagine di avvio
È possibile creare un'immagine di avvio utilizzando l'ambiente di compilazione 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 [-- --destdir=$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 init_boot
partizione,
hai bisogno di un binario ramdisk, che puoi ottenere
scaricando un'immagine di avvio GKI
e decomprimendola. Qualsiasi immagine di avvio GKI della release 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 (la directory di lavoro corrente).
Se sviluppi con il ramo di rilascio AOSP più recente, puoi scaricare l'artefatto di build ramdisk-recovery.img
da una build aosp_arm64 su ci.android.com e utilizzarlo 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 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
Questo 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
.