Membangun Kernel

Halaman ini merinci proses pembuatan kernel khusus untuk perangkat Android. Petunjuk ini memandu Anda melalui proses memilih sumber yang tepat, membuat kernel, dan menyematkan hasilnya ke dalam image sistem yang dibuat dari Android Open Source Project (AOSP).

Anda dapat memperoleh sumber kernel terbaru dengan menggunakan Repo ; bangun tanpa konfigurasi lebih lanjut dengan menjalankan build/build.sh dari root checkout sumber Anda.

Mengunduh sumber dan membuat alat

Untuk kernel terbaru, gunakan repo untuk mengunduh sumber, rantai alat, dan skrip pembuatan. Beberapa kernel (misalnya, kernel Pixel 3) memerlukan sumber dari beberapa repositori git, sementara yang lain (misalnya, kernel umum) hanya memerlukan satu sumber. Menggunakan pendekatan repo memastikan pengaturan direktori sumber yang benar.

Unduh sumber untuk cabang yang sesuai:

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

Untuk daftar cabang repo ( BRANCH ) yang dapat digunakan dengan perintah `repo init` sebelumnya, lihat Cabang kernel dan sistem pembangunannya .

Untuk detail tentang cara mendownload dan mengompilasi kernel untuk perangkat Pixel, Lihat Membuat Kernel Pixel .

Membangun kernel

Membangun dengan Bazel (Kleaf)

Android 13 memperkenalkan pembuatan kernel dengan Bazel .

Untuk membangun kernel GKI untuk arsitektur aarch64, periksa cabang Android Common Kernel tidak lebih awal dari Android 13, lalu jalankan perintah berikut:

tools/bazel build //common:kernel_aarch64_dist

Untuk membuat distribusi, jalankan:

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

Setelah itu biner kernel, modul, dan gambar terkait ditempatkan di direktori $DIST_DIR . Jika --dist_dir tidak ditentukan, lihat output perintah untuk mengetahui lokasi artefak. Untuk detailnya, lihat dokumentasi di AOSP .

Membangun dengan build.sh (warisan)

Untuk cabang di atau di bawah Android 12, ATAU cabang tanpa Kleaf:

build/build.sh

Biner kernel, modul, dan gambar terkait terletak di direktori out/ BRANCH /dist .

Membangun Modul Vendor untuk Perangkat Virtual

Android 13 memperkenalkan pembuatan kernel dengan Bazel (Kleaf), menggantikan build.sh .

Untuk membuat modul virtual_device , jalankan:

tools/bazel build //common-modules/virtual-device:virtual_device_x86_64_dist

Untuk membuat distribusi, jalankan:

tools/bazel run //common-modules/virtual-device:virtual_device_x86_64_dist -- --dist_dir=$DIST_DIR

Untuk detail selengkapnya tentang membangun kernel Android dengan Bazel, lihat. Kleaf - Membangun Kernel Android dengan Bazel .

Untuk detail tentang dukungan Kleaf untuk arsitektur individual, lihat Dukungan Kleaf untuk perangkat dan kernel .

Membangun Modul Vendor untuk Perangkat Virtual dengan build.sh (warisan)

Di Android 12, Sotong dan Ikan Mas bertemu, sehingga keduanya berbagi kernel yang sama: virtual_device . Untuk membangun modul kernel tersebut, gunakan konfigurasi build ini:

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

Android 11 memperkenalkan GKI , yang memisahkan kernel menjadi image kernel yang dikelola Google dan modul yang dikelola vendor, yang dibuat secara terpisah.

Contoh ini menunjukkan konfigurasi image kernel:

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

Contoh ini menunjukkan konfigurasi modul (Cuttlefish dan Emulator):

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

Menjalankan kernel

Ada beberapa cara untuk menjalankan kernel yang dibuat khusus. Berikut ini adalah cara-cara yang diketahui cocok untuk berbagai skenario pengembangan.

Menyematkan ke dalam build image Android

Salin Image.lz4-dtb ke lokasi biner kernel masing-masing dalam pohon AOSP dan buat kembali image boot.

Alternatifnya, tentukan variabel TARGET_PREBUILT_KERNEL saat menggunakan make bootimage (atau baris perintah make lainnya yang membuat image boot). Variabel ini didukung oleh semua perangkat karena dikonfigurasi melalui device/common/populate-new-device.sh . Misalnya:

export TARGET_PREBUILT_KERNEL=DIST_DIR/Image.lz4-dtb

Mem-flash dan mem-boot kernel dengan fastboot

Perangkat terbaru memiliki ekstensi bootloader untuk menyederhanakan proses pembuatan dan boot image boot.

Untuk mem-boot kernel tanpa mem-flash:

adb reboot bootloader
fastboot boot Image.lz4-dtb

Dengan menggunakan metode ini, kernel tidak benar-benar di-flash, dan tidak akan bertahan saat reboot.

Menjalankan kernel pada Sotong

Anda dapat menjalankan kernel dalam arsitektur pilihan Anda pada perangkat Cuttlefish .

Untuk mem-boot perangkat Cuttlefish dengan kumpulan artefak kernel tertentu, jalankan perintah cvd start dengan artefak kernel target sebagai parameter. Contoh perintah berikut menggunakan artefak kernel untuk target arm64 dari manifes 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

Untuk informasi lebih lanjut, lihat Mengembangkan kernel pada Sotong .

Menyesuaikan build kernel

Untuk menyesuaikan versi kernel untuk versi Kleaf, lihat dokumentasi Kleaf .

Menyesuaikan build kernel dengan build.sh (legacy)

Untuk build/build.sh , proses dan hasil pembangunan dapat dipengaruhi oleh variabel lingkungan. Kebanyakan darinya bersifat opsional dan setiap cabang kernel harus dilengkapi dengan konfigurasi default yang tepat. Yang paling sering digunakan tercantum di sini. Untuk daftar lengkap (dan terkini), lihat build/build.sh .

Variabel lingkungan Keterangan Contoh
BUILD_CONFIG Buat file konfigurasi dari tempat Anda menginisialisasi lingkungan build. Lokasi harus ditentukan relatif terhadap direktori root Repo. Defaultnya adalah build.config .
Wajib untuk kernel umum.
BUILD_CONFIG=common/build.config.gki.aarch64
CC Ganti kompiler yang akan digunakan. Kembali ke kompiler default yang ditentukan oleh build.config . CC=clang
DIST_DIR Direktori keluaran dasar untuk distribusi kernel. DIST_DIR=/path/to/my/dist
OUT_DIR Direktori keluaran dasar untuk pembuatan kernel. OUT_DIR=/path/to/my/out
SKIP_DEFCONFIG Lewati make defconfig SKIP_DEFCONFIG=1
SKIP_MRPROPER Lewati make mrproper SKIP_MRPROPER=1

Konfigurasi kernel khusus untuk build lokal

Di Android 14 dan yang lebih baru, Anda dapat menggunakan fragmen defconfig untuk menyesuaikan konfigurasi kernel. lihat dokumentasi Kleaf tentang fragmen defconfig .

Konfigurasi kernel khusus untuk build lokal dengan konfigurasi build (warisan)

Di Android 13 dan yang lebih lama, lihat yang berikut ini.

Jika Anda perlu mengganti opsi konfigurasi kernel secara rutin, misalnya, saat mengerjakan suatu fitur, atau jika Anda memerlukan opsi untuk disetel untuk tujuan pengembangan, Anda dapat mencapai fleksibilitas tersebut dengan mempertahankan modifikasi lokal atau salinan konfigurasi build.

Setel variabel POST_DEFCONFIG_CMDS ke pernyataan yang dievaluasi tepat setelah langkah make defconfig yang biasa dilakukan. Karena file build.config bersumber ke lingkungan build, fungsi yang ditentukan di build.config dapat dipanggil sebagai bagian dari perintah pasca-defconfig.

Contoh umum adalah menonaktifkan optimasi waktu tautan (LTO) untuk kernel crosshatch selama pengembangan. Meskipun LTO bermanfaat untuk kernel yang dirilis, biaya overhead pada waktu pembuatan bisa sangat besar. Cuplikan berikut yang ditambahkan ke build.config lokal menonaktifkan LTO secara terus-menerus saat menggunakan 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)
}

Mengidentifikasi versi kernel

Anda dapat mengidentifikasi versi yang benar untuk dibangun dari dua sumber: pohon AOSP dan citra sistem.

Versi kernel dari pohon AOSP

Pohon AOSP berisi versi kernel bawaan. Git log menampilkan versi yang benar sebagai bagian dari pesan komit:

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

Jika versi kernel tidak tercantum di git log, dapatkan versi tersebut dari image sistem, seperti dijelaskan di bawah.

Versi kernel dari image sistem

Untuk menentukan versi kernel yang digunakan dalam citra sistem, jalankan perintah berikut pada file kernel:

file kernel

Untuk file Image.lz4-dtb , jalankan:

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

Membangun Gambar Boot

Dimungkinkan untuk membuat image boot menggunakan lingkungan build kernel.

Membangun Image Boot untuk Perangkat dengan init_boot

Untuk perangkat dengan partisi init_boot , image boot dibuat bersama dengan kernel. Gambar initramfs tidak tertanam dalam gambar boot.

Misalnya, dengan Kleaf, Anda dapat membuat image boot GKI dengan:

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

Dengan build/build.sh (legacy), Anda dapat membuat image boot GKI dengan:

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

Gambar boot GKI terletak di $DIST_DIR .

Membangun Image Boot untuk Perangkat tanpa init_boot (warisan)

Untuk perangkat tanpa partisi init_boot , Anda memerlukan biner ramdisk, yang dapat diperoleh dengan mengunduh image boot GKI dan membongkarnya. Image boot GKI apa pun dari rilis Android terkait akan berfungsi.

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

Folder target adalah direktori tingkat atas dari pohon kernel (direktori kerja saat ini).

Jika Anda mengembangkan dengan AOSP main, Anda dapat mengunduh artefak build ramdisk-recovery.img dari build aosp_arm64 di ci.android.com dan menggunakannya sebagai biner ramdisk Anda.

Ketika Anda memiliki biner ramdisk dan telah menyalinnya ke gki-ramdisk.lz4 di direktori root build kernel, Anda dapat membuat image boot dengan menjalankan:

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

Jika Anda bekerja dengan arsitektur berbasis x86, ganti Image dengan bzImage , dan aarch64 dengan 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

File itu terletak di direktori artefak $KERNEL_ROOT/out/$KERNEL_VERSION/dist .

Gambar boot terletak di out/<kernel branch>/dist/boot.img .