ساخت هسته ها

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

با استفاده از Repo می توانید منابع هسته اخیر را بدست آورید. آنها را بدون پیکربندی بیشتر با اجرای build/build.sh از ریشه پرداخت منبع خود بسازید.

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

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

دانلود منابع برای شاخه مناسب:

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

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

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

ساختن هسته

ساختمان با بازل (کلیف)

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

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

tools/bazel build //common:kernel_aarch64_dist

برای ایجاد توزیع، اجرا کنید:

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

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

ساختمان با build.sh (میراث)

برای شعبه هایی در اندروید 12 یا پایین تر، یا شاخه های بدون Kleaf:

build/build.sh

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

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

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

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

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

برای ایجاد توزیع، اجرا کنید:

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

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

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

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

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

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

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

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

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

این مثال پیکربندی ماژول (Cuttlefish and 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 start را با آرتیفکت‌های هسته هدف به عنوان پارامتر اجرا کنید. دستور مثال زیر از آرتیفکت‌های هسته برای هدف arm64 از مانیفست هسته 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

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

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

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

سفارشی سازی ساخت هسته با build.sh (میراث)

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

متغیر محیطی شرح مثال
BUILD_CONFIG فایل کانفیگ را از جایی که محیط ساخت را مقداردهی اولیه می کنید بسازید. مکان باید نسبت به دایرکتوری ریشه Repo تعریف شود. پیش فرض های 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

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

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

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

در اندروید 13 و پایین تر، موارد زیر را ببینید.

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

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

یک مثال رایج، غیرفعال کردن بهینه سازی زمان لینک (LTO) برای کرنل های متقاطع در طول توسعه است. در حالی که 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 شامل نسخه های هسته از پیش ساخته شده است. گزارش git نسخه صحیح را به عنوان بخشی از پیام commit نشان می دهد:

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

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

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

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

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 -- --dist_dir=$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 main هستید، می توانید در عوض مصنوع ساخت 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 قرار دارد.