إنشاء نواة

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

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

بالنسبة إلى النواة الحديثة، استخدِم 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`، راجِع فروع النواة وأنظمة الإنشاء الخاصة بها.

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

إنشاء النواة

إنشاء التطبيقات باستخدام Bazel (Kleaf)

أتاح الإصدار Android 13 إمكانية إنشاء النواة باستخدام Bazel.

لإنشاء توزيع لنواة GKI لبنية aarch64، اطّلِع على فرع Android Common Kernel الذي لا يسبق Android 13، ثم نفِّذ الأمر التالي:

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

بعد ذلك، يتم تخزين ملفات kernel الثنائية والوحدات والصور ذات الصلة في الدليل $DIST_DIR. في حال عدم تحديد --destdir، راجِع ناتج الأمر لمعرفة موقع العناصر. لمزيد من التفاصيل، يُرجى الرجوع إلى المستندات المتعلّقة بنظام التشغيل AOSP.

إنشاء التطبيق باستخدام build.sh (الإصدار القديم)

بالنسبة إلى الفروع التي تعمل بالإصدار 12 من نظام التشغيل Android أو الإصدارات الأقدم، أو الفروع التي لا تتضمّن Kleaf:

build/build.sh

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

إنشاء وحدات البائع للجهاز الافتراضي

أتاح الإصدار 13 من نظام التشغيل Android إنشاء النواة باستخدام Bazel (Kleaf) بدلاً من build.sh.

لإنشاء توزيع لوحدات virtual_device، نفِّذ ما يلي:

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

لمزيد من التفاصيل حول إنشاء نِوى Android باستخدام Bazel، يُرجى الاطّلاع على. Kleaf - إنشاء نِوى Android باستخدام Bazel

للحصول على تفاصيل حول توافق Kleaf مع البُنى الفردية، يُرجى الاطّلاع على توافق Kleaf مع الأجهزة والنواة.

إنشاء وحدات المورّد للجهاز الافتراضي باستخدام build.sh (قديم)

في الإصدار 12 من نظام التشغيل Android، تتلاقى محاكيتا Cuttlefish وGoldfish، لذا تشتركان في النواة نفسها: virtual_device. لإنشاء وحدات النواة هذه، استخدِم إعدادات الإنشاء التالية:

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

قدّمت الإصدار 11 من نظام التشغيل Android صورة النواة العامة (GKI)، التي تفصل النواة إلى صورة نواة تحتفظ بها Google ووحدات يحتفظ بها المورّدون، ويتم إنشاء هذه الوحدات بشكل منفصل.

يعرض هذا المثال إعدادات صورة النواة:

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 إلى الموقع الثنائي المناسب لنواة النظام ضمن بنية 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.

لتشغيل جهاز Cuttlefish باستخدام مجموعة معيّنة من عناصر نظام التشغيل، شغِّل الأمر cvd create مع عناصر نظام التشغيل المستهدَفة كمَعلمات. يستخدم مثال الأمر التالي عناصر kernel لبرنامج arm64 من بيان common-android14-6.1 kernel.

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

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

تخصيص إصدار النواة

لتخصيص إصدارات النواة لعمليات إنشاء Kleaf، راجِع مستندات Kleaf.

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

بالنسبة إلى build/build.sh، يمكن أن تتأثر عملية الإنشاء ونتيجتها بمتغيرات البيئة. معظمها اختياري، ويجب أن يتضمّن كل فرع من نواة النظام إعدادات تلقائية مناسبة. في ما يلي قائمة بأكثرها استخدامًا. للحصول على قائمة كاملة (ومحدّثة)، يُرجى الرجوع إلى 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

إعدادات مخصّصة لنواة النظام لعمليات الإنشاء المحلية

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

إعدادات مخصّصة لنواة النظام لعمليات الإنشاء المحلية باستخدام إعدادات الإنشاء (الإصدار القديم)

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

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

اضبط المتغيّر 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 على إصدارات مسبقة الإنشاء من النواة. يكشف سجلّ git عن الإصدار الصحيح كجزء من رسالة الالتزام:

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 [-- --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 من إصدار Android المرتبط.

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 الثنائي ونسخه إلى 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.