هسته ها را بسازید

این صفحه جزئیات فرآیند ساخت هسته‌های سفارشی برای دستگاه‌های اندروید را شرح می‌دهد. این دستورالعمل‌ها شما را در فرآیند انتخاب منابع مناسب، ساخت هسته و جاسازی نتایج در یک تصویر سیستمی ساخته شده از پروژه متن‌باز اندروید (AOSP) راهنمایی می‌کنند.

دانلود منابع و ابزارهای ساخت

برای کرنل‌های جدید، repo برای دانلود منابع، زنجیره ابزار و اسکریپت‌های ساخت استفاده کنید. برخی از کرنل‌ها (به عنوان مثال، کرنل‌های Pixel 3) به منابعی از چندین مخزن گیت نیاز دارند، در حالی که برخی دیگر (به عنوان مثال، کرنل‌های رایج) فقط به یک منبع نیاز دارند. استفاده از رویکرد repo تنظیم صحیح دایرکتوری منبع را تضمین می‌کند.

منابع مربوط به شاخه‌ی مربوطه را دانلود کنید:

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

برای فهرستی از شاخه‌های مخزن ( BRANCH ) که می‌توانند با دستور قبلی `repo init` استفاده شوند، به شاخه‌های هسته و سیستم‌های ساخت آنها مراجعه کنید.

برای جزئیات بیشتر در مورد دانلود و کامپایل هسته‌ها برای دستگاه‌های پیکسل، به بخش «ساخت هسته‌های پیکسل» مراجعه کنید.

ساخت هسته

با بازل (کلاف) بسازید

اندروید ۱۳ ساخت هسته‌ها با Bazel را معرفی کرد.

برای ایجاد توزیعی برای هسته GKI برای معماری aarch64، شاخه Android Common Kernel را که زودتر از اندروید ۱۳ نباشد، بررسی کنید و سپس دستور زیر را اجرا کنید:

tools/bazel run //common:kernel_aarch64_dist [-- --destdir=$DIST_DIR]

پس از آن، فایل‌های باینری هسته، ماژول‌ها و تصاویر مربوطه در دایرکتوری $DIST_DIR قرار می‌گیرند. اگر --destdir مشخص نشده باشد، برای اطلاع از محل مصنوعات، به خروجی دستور مراجعه کنید. برای جزئیات بیشتر، به مستندات AOSP مراجعه کنید.

ساخت با build.sh (قدیمی)

برای شاخه‌هایی با اندروید ۱۲ یا پایین‌تر، یا شاخه‌هایی بدون Kleaf:

build/build.sh

فایل‌های باینری هسته، ماژول‌ها و تصویر مربوطه در دایرکتوری out/ BRANCH /dist قرار دارند.

ماژول‌های فروشنده را برای دستگاه مجازی بسازید

اندروید ۱۳ ساخت هسته‌ها با Bazel (Kleaf) را معرفی کرد و جایگزین build.sh شد.

برای ایجاد یک توزیع برای ماژول‌های virtual_device ، دستور زیر را اجرا کنید:

tools/bazel run //common-modules/virtual-device:virtual_device_x86_64_dist [-- --destdir=$DIST_DIR]

برای جزئیات بیشتر در مورد ساخت هسته‌های اندروید با Bazel، به Kleaf - ساخت هسته‌های اندروید با Bazel مراجعه کنید.

برای جزئیات بیشتر در مورد پشتیبانی Kleaf برای معماری‌های منفرد، به پشتیبانی Kleaf برای دستگاه‌ها و هسته‌ها مراجعه کنید.

ماژول‌های فروشنده را برای دستگاه مجازی با build.sh (نسخه قدیمی) بسازید

در اندروید ۱۲، Cuttlefish و Goldfish همگرا هستند، بنابراین از یک هسته مشترک به نام virtual_device استفاده می‌کنند. برای ساخت ماژول‌های آن هسته، از این پیکربندی ساخت استفاده کنید:

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

اندروید ۱۱ GKI را معرفی کرد که هسته را به یک تصویر هسته تحت مدیریت گوگل و ماژول‌های تحت مدیریت فروشنده که جداگانه ساخته می‌شوند، تفکیک می‌کند.

این مثال پیکربندی تصویر هسته را نشان می‌دهد:

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

این مثال پیکربندی ماژول (Cuttlefish و Emulator) را نشان می‌دهد:

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

هسته را اجرا کنید

روش‌های متعددی برای اجرای یک هسته سفارشی وجود دارد. در ادامه روش‌های شناخته‌شده‌ای که برای سناریوهای مختلف توسعه مناسب هستند، آورده شده است.

در ساخت تصویر اندروید جاسازی کنید

فایل Image.lz4-dtb را در محل باینری هسته مربوطه در درخت AOSP کپی کنید و تصویر بوت را بازسازی کنید.

روش دیگر، تعریف متغیر TARGET_PREBUILT_KERNEL هنگام استفاده از make bootimage (یا هر خط فرمان make دیگری که یک تصویر بوت می‌سازد) است. این متغیر توسط همه دستگاه‌ها پشتیبانی می‌شود زیرا از طریق device/common/populate-new-device.sh تنظیم شده است. برای مثال:

export TARGET_PREBUILT_KERNEL=DIST_DIR/Image.lz4-dtb

فلش کردن و بوت کردن کرنل‌ها با فست‌بوت

اکثر دستگاه‌های جدید دارای افزونه‌ای برای بوت لودر هستند تا فرآیند تولید و بوت کردن یک ایمیج بوت را ساده‌تر کنند.

برای بوت کردن کرنل بدون فلش کردن:

adb reboot bootloader
fastboot boot Image.lz4-dtb

با استفاده از این روش، هسته در واقع فلش نمی‌شود و پس از راه‌اندازی مجدد سیستم، باقی نمی‌ماند.

هسته‌ها را روی ماهی مرکب بریزید

شما می‌توانید هسته‌ها را با معماری دلخواه خود روی دستگاه‌های Cuttlefish اجرا کنید.

برای بوت کردن یک دستگاه Cuttlefish با مجموعه‌ای خاص از مصنوعات هسته ، دستور cvd create را با پارامترهای مصنوعات هسته هدف اجرا کنید. دستور مثال زیر از مصنوعات هسته برای یک هدف arm64 از مانیفست هسته 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

برای اطلاعات بیشتر، به بخش «توسعه هسته‌ها روی ماهی مرکب» مراجعه کنید.

سفارشی‌سازی ساختار هسته

برای سفارشی‌سازی نسخه‌های کرنل برای نسخه‌های Kleaf، به مستندات Kleaf مراجعه کنید.

سفارشی‌سازی ساختار هسته با build.sh (نسخه قدیمی)

برای build/build.sh ، فرآیند ساخت و نتیجه می‌تواند تحت تأثیر متغیرهای محیطی قرار گیرد. اکثر آنها اختیاری هستند و هر شاخه هسته باید با پیکربندی پیش‌فرض مناسبی ارائه شود. مواردی که بیشتر مورد استفاده قرار می‌گیرند در اینجا فهرست شده‌اند. برای مشاهده لیست کامل (و به‌روز)، به build/build.sh مراجعه کنید.

متغیر محیطی توضیحات مثال
BUILD_CONFIG فایل پیکربندی ساخت (Build config file) که محیط ساخت (build environment) را از آنجا مقداردهی اولیه می‌کنید. این مکان باید نسبت به دایرکتوری ریشه مخزن (Repo root directory) تعریف شود. مقدار پیش‌فرض build.config است.
برای هسته‌های رایج اجباری است.
BUILD_CONFIG=common/build.config.gki.aarch64
CC کامپایلر مورد استفاده را لغو می‌کند. به کامپایلر پیش‌فرض تعریف شده توسط build.config برمی‌گردد. CC=clang
DIST_DIR دایرکتوری خروجی پایه برای توزیع هسته. DIST_DIR=/path/to/my/dist
OUT_DIR دایرکتوری خروجی پایه برای ساخت هسته. OUT_DIR=/path/to/my/out
SKIP_DEFCONFIG صرف نظر کردن make defconfig SKIP_DEFCONFIG=1
SKIP_MRPROPER از make mrproper صرف نظر کنید SKIP_MRPROPER=1

پیکربندی هسته سفارشی برای نسخه‌های محلی

در اندروید ۱۴ و بالاتر، می‌توانید از قطعات defconfig برای سفارشی‌سازی پیکربندی‌های هسته استفاده کنید. برای اطلاعات بیشتر در مورد قطعات defconfig به مستندات Kleaf مراجعه کنید.

پیکربندی هسته سفارشی برای نسخه‌های محلی با پیکربندی‌های نسخه قدیمی

در اندروید ۱۳ و پایین‌تر، به موارد زیر مراجعه کنید.

اگر مثلاً هنگام کار روی یک ویژگی، نیاز دارید که مرتباً یک گزینه پیکربندی هسته را تغییر دهید، یا اگر برای اهداف توسعه به تنظیم یک گزینه نیاز دارید، می‌توانید با حفظ یک تغییر محلی یا کپی از پیکربندی ساخت، به این انعطاف‌پذیری دست یابید.

متغیر POST_DEFCONFIG_CMDS روی عبارتی تنظیم کنید که درست پس از انجام مرحله معمول make defconfig ارزیابی شود. همزمان با اینکه فایل‌های build.config در محیط ساخت قرار می‌گیرند، توابع تعریف شده در build.config می‌توانند به عنوان بخشی از دستورات post-defconfig فراخوانی شوند.

یک مثال رایج، غیرفعال کردن بهینه‌سازی زمان پیوند (LTO) برای هسته‌های crosshatch در طول توسعه است. در حالی که LTO برای هسته‌های منتشر شده مفید است، سربار در زمان ساخت می‌تواند قابل توجه باشد. قطعه کد زیر که به build.config محلی اضافه شده است، LTO را هنگام استفاده 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)
}

شناسایی نسخه‌های هسته

شما می‌توانید نسخه صحیح برای ساخت را از دو منبع شناسایی کنید: درخت AOSP و تصویر سیستم.

نسخه هسته از درخت AOSP

درخت AOSP شامل نسخه‌های از پیش ساخته شده‌ی هسته است. لاگ گیت، نسخه صحیح را به عنوان بخشی از پیام کامیت نشان می‌دهد:

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

اگر نسخه کرنل در لاگ گیت ذکر نشده است، آن را از تصویر سیستم، همانطور که در زیر توضیح داده شده است، دریافت کنید.

نسخه هسته از تصویر سیستم

برای تعیین نسخه کرنل استفاده شده در یک تصویر سیستم، دستور زیر را در مقابل فایل کرنل اجرا کنید:

file kernel

برای فایل‌های Image.lz4-dtb ، دستور زیر را اجرا کنید:

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

ساخت یک ایمیج بوت

ساخت یک ایمیج بوت با استفاده از محیط ساخت هسته امکان‌پذیر است.

ساخت ایمیج بوت برای دستگاه‌هایی با init_boot

برای دستگاه‌هایی که پارتیشن init_boot دارند، تصویر بوت به همراه هسته ساخته می‌شود. تصویر initramfs در تصویر بوت تعبیه نشده است.

برای مثال، با Kleaf، می‌توانید تصویر بوت GKI را با موارد زیر بسازید:

tools/bazel run //common:kernel_aarch64_dist [-- --destdir=$DIST_DIR]

با build/build.sh (نسخه قدیمی)، می‌توانید تصویر بوت GKI را با موارد زیر بسازید:

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

تصویر بوت GKI در مسیر $DIST_DIR قرار دارد.

ساخت یک ایمیج بوت برای دستگاه‌های بدون init_boot (قدیمی)

برای دستگاه‌هایی که پارتیشن init_boot ندارند، به یک فایل باینری ramdisk نیاز دارید که می‌توانید با دانلود یک تصویر بوت GKI و خارج کردن آن از حالت فشرده، آن را به دست آورید. هر تصویر بوت GKI از نسخه اندروید مرتبط، کار خواهد کرد.

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

پوشه هدف، دایرکتوری سطح بالای درخت هسته (دایرکتوری کاری فعلی) است.

اگر در حال توسعه با آخرین شاخه انتشار AOSP هستید، می‌توانید فایل مصنوع ساخت ramdisk-recovery.img را از یک ساخت aosp_arm64 در ci.android.com دانلود کنید و از آن به عنوان فایل باینری ramdisk خود استفاده کنید.

وقتی یک فایل باینری ramdisk دارید و آن را در gki-ramdisk.lz4 در دایرکتوری ریشه‌ی هسته کپی کرده‌اید، می‌توانید با اجرای دستور زیر یک تصویر بوت ایجاد کنید:

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

اگر با معماری مبتنی بر x86 کار می‌کنید، Image با bzImage و aarch64 با 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

آن فایل در دایرکتوری مصنوع $KERNEL_ROOT/out/$KERNEL_VERSION/dist قرار دارد.

تصویر بوت در مسیر out/<kernel branch>/dist/boot.img قرار دارد.