بناء النواة

تعرض هذه الصفحة تفاصيل عملية إنشاء نواة مخصصة لأجهزة Android. ترشدك هذه الإرشادات خلال عملية اختيار المصادر الصحيحة، وبناء النواة، وتضمين النتائج في صورة نظام تم إنشاؤها من مشروع Android مفتوح المصدر (AOSP).

يمكنك الحصول على مصادر أحدث للنواة باستخدام Repo ؛ قم بإنشائها دون مزيد من التكوين عن طريق تشغيل build/build.sh من جذر الخروج المصدر الخاص بك.

تنزيل المصادر وأدوات البناء

بالنسبة للنوى الحديثة، استخدم repo لتنزيل المصادر وسلسلة الأدوات وبناء البرامج النصية. تتطلب بعض النوى (على سبيل المثال، نواة Pixel 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` السابق، راجع فروع Kernel وأنظمة البناء الخاصة بها .

للحصول على تفاصيل حول تنزيل وتجميع النوى لأجهزة Pixel، راجع إنشاء Pixel Kernels .

بناء النواة

البناء مع بازل (كليف)

قدم Android 13 بناء النوى باستخدام Bazel .

لإنشاء نواة GKI لبنية aarch64، تحقق من فرع Android Common Kernel في موعد لا يتجاوز Android 13 ثم قم بتشغيل الأمر التالي:

tools/bazel build //common:kernel_aarch64_dist

لإنشاء توزيعة، قم بتشغيل:

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

بعد ذلك، يتم وضع ثنائيات kernel والوحدات والصور المقابلة لها في الدليل $DIST_DIR . إذا كان --dist_dir غير محدد، فراجع مخرجات الأمر الخاص بموقع العناصر. للحصول على التفاصيل، راجع الوثائق الموجودة على AOSP .

البناء باستخدام build.sh (قديم)

بالنسبة للفروع التي تعمل بنظام Android 12 أو أقل منه، أو الفروع التي لا تحتوي على Kleaf:

build/build.sh

يوجد ثنائي النواة والوحدات النمطية والصورة المقابلة في الدليل out/ BRANCH /dist .

بناء وحدات البائع للجهاز الظاهري

قدم Android 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

لمزيد من التفاصيل حول بناء نواة Android باستخدام Bazel، راجع. Kleaf - بناء نواة Android باستخدام 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

قدم Android 11 GKI ، الذي يفصل النواة إلى صورة نواة يتم صيانتها بواسطة Google ووحدات يحتفظ بها البائع، والتي يتم إنشاؤها بشكل منفصل.

يوضح هذا المثال تكوين صورة kernel:

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

تشغيل النواة

هناك طرق متعددة لتشغيل نواة مخصصة. فيما يلي طرق معروفة مناسبة لسيناريوهات التطوير المختلفة.

التضمين في بناء صورة Android

انسخ Image.lz4-dtb إلى موقع kernel الثنائي المعني داخل شجرة AOSP وأعد إنشاء صورة التمهيد.

وبدلاً من ذلك، قم بتعريف المتغير TARGET_PREBUILT_KERNEL أثناء استخدام make bootimage (أو أي سطر make آخر لإنشاء صورة تمهيد). هذا المتغير مدعوم من قبل جميع الأجهزة حيث تم إعداده عبر device/common/populate-new-device.sh . على سبيل المثال:

export TARGET_PREBUILT_KERNEL=DIST_DIR/Image.lz4-dtb

تفليش وإقلاع النوى باستخدام fastboot

تحتوي معظم الأجهزة الحديثة على ملحق أداة تحميل التشغيل لتبسيط عملية إنشاء صورة تمهيد وتشغيلها.

لتشغيل النواة بدون وميض:

adb reboot bootloader
fastboot boot Image.lz4-dtb

باستخدام هذه الطريقة، لا يتم وميض النواة فعليًا، ولن تستمر أثناء عملية إعادة التشغيل.

تشغيل النوى على الحبار

يمكنك تشغيل النواة في البنية التي تختارها على أجهزة Cuttlefish .

لتشغيل جهاز Cuttlefish بمجموعة معينة من عناصر kernel ، قم بتشغيل الأمر cvd start مع عناصر kernel المستهدفة كمعلمات. يستخدم أمر المثال التالي عناصر kernel لهدف Arm64 من بيان 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

لمزيد من المعلومات، راجع تطوير النوى على Cuttlefish .

تخصيص بناء النواة

لتخصيص إصدارات kernel لإصدارات Kleaf، راجع وثائق Kleaf .

تخصيص بناء النواة باستخدام build.sh (القديم)

بالنسبة إلى build/build.sh ، يمكن أن تتأثر عملية البناء والنتيجة بمتغيرات البيئة. معظمها اختيارية ويجب أن يأتي كل فرع من فروع kernel بتكوين افتراضي مناسب. الأكثر استخداما مدرجة هنا. للحصول على قائمة كاملة (ومحدثة)، راجع build/build.sh .

متغيرات البيئة وصف مثال
BUILD_CONFIG قم ببناء ملف التكوين من حيث تقوم بتهيئة بيئة البناء. يجب تحديد الموقع بالنسبة إلى دليل جذر الريبو. الإعدادات الافتراضية هي 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

تكوين kernel مخصص للبنيات المحلية

في نظام التشغيل Android 14 والإصدارات الأحدث، يمكنك استخدام أجزاء إلغاء التكوين لتخصيص تكوينات kernel. راجع وثائق Kleaf حول أجزاء defconfig .

تكوين kernel مخصص للإصدارات المحلية مع تكوينات البناء (القديمة)

في نظام التشغيل Android 13 والإصدارات الأقدم، راجع ما يلي.

إذا كنت بحاجة إلى تبديل خيار تكوين kernel بانتظام، على سبيل المثال، عند العمل على إحدى الميزات، أو إذا كنت بحاجة إلى تعيين خيار لأغراض التطوير، فيمكنك تحقيق هذه المرونة عن طريق الحفاظ على تعديل محلي أو نسخة من تكوين البناء.

قم بتعيين المتغير POST_DEFCONFIG_CMDS إلى عبارة يتم تقييمها مباشرة بعد الانتهاء من خطوة make defconfig المعتادة. نظرًا لأن ملفات build.config يتم الحصول عليها من بيئة البناء، فيمكن استدعاء الوظائف المحددة في build.config كجزء من أوامر ما بعد 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 على إصدارات kernel مسبقة الصنع. يكشف سجل git عن الإصدار الصحيح كجزء من رسالة الالتزام:

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

إذا لم يكن إصدار kernel مدرجًا في سجل git، فاحصل عليه من صورة النظام، كما هو موضح أدناه.

إصدار النواة من صورة النظام

لتحديد إصدار kernel المستخدم في صورة النظام، قم بتشغيل الأمر التالي على ملف kernel:

file kernel

بالنسبة لملفات Image.lz4-dtb ، قم بتشغيل:

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

بناء صورة التمهيد

من الممكن إنشاء صورة تمهيد باستخدام بيئة بناء kernel.

إنشاء صورة تمهيد للأجهزة التي تحتوي على 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 ، فأنت بحاجة إلى قرص ذاكرة ثنائي، والذي يمكنك الحصول عليه عن طريق تنزيل صورة تمهيد GKI وتفريغها. ستعمل أي صورة تمهيد GKI من إصدار Android المرتبط بها.

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 في الدليل الجذر لبناء kernel، يمكنك إنشاء صورة تمهيد عن طريق تنفيذ:

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 .