وحدات نواة قابلة للتحميل

كجزء من متطلبات نواة الوحدة المقدمة في Android 8.0، يجب أن تدعم جميع نواة النظام على الرقاقة (SoC) وحدات kernel القابلة للتحميل.

خيارات تكوين النواة

لدعم وحدات kernel القابلة للتحميل، يتضمن android-base.config في جميع النوى الشائعة خيارات تكوين kernel التالية (أو ما يعادلها من إصدار kernel):

CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODVERSIONS=y

يجب على كافة نواة الجهاز تمكين هذه الخيارات. يجب أن تدعم وحدات Kernel أيضًا التفريغ وإعادة التحميل كلما أمكن ذلك.

توقيع الوحدة

توقيع الوحدة غير مدعوم لوحدات موردي GKI. على الأجهزة المطلوبة لدعم التمهيد الذي تم التحقق منه، يتطلب Android وجود وحدات kernel في الأقسام التي تم تمكين dm-verity فيها. وهذا يلغي الحاجة إلى توقيع الوحدات الفردية للتأكد من صحتها. قدم Android 13 مفهوم وحدات GKI. تستخدم وحدات GKI البنية التحتية لتوقيع وقت إنشاء kernel للتمييز بين GKI والوحدات النمطية الأخرى في وقت التشغيل. يُسمح بتحميل الوحدات غير الموقعة طالما أنها تستخدم فقط الرموز التي تظهر في القائمة المسموح بها أو المقدمة من الوحدات الأخرى غير الموقعة. لتسهيل توقيع وحدات GKI أثناء إنشاء GKI باستخدام زوج مفاتيح وقت إنشاء kernel، قام تكوين GKI kernel بتمكين CONFIG_MODULE_SIG_ALL=y . لتجنب توقيع وحدات غير تابعة لـ GKI أثناء إنشاء kernel للجهاز، يجب عليك إضافة # CONFIG_MODULE_SIG_ALL is not set كجزء من أجزاء تكوين kernel الخاصة بك.

مواقع الملفات

على الرغم من أن Android 7.x والإصدارات الأحدث لا يفرض حظرًا على وحدات kernel (ويتضمن دعمًا لـ insmod و rmmod )، فإن Android 8.x والإصدارات الأحدث يوصي باستخدام وحدات kernel في النظام البيئي. يعرض الجدول التالي الدعم الطرفي المحتمل الخاص باللوحة والمطلوب عبر ثلاثة أوضاع تمهيد لنظام Android.

وضع التمهيد تخزين عرض لوحة المفاتيح بطارية بميك شاشة اللمس إن إف سي، واي فاي،
بلوتوث
أجهزة الاستشعار آلة تصوير
استعادة
شاحن
ذكري المظهر

بالإضافة إلى التوفر في أوضاع تشغيل Android، يمكن أيضًا تصنيف وحدات kernel حسب من يملكها (بائع SoC أو ODM). في حالة استخدام وحدات kernel، تكون متطلبات وضعها في نظام الملفات كما يلي:

  • يجب أن تحتوي جميع النوى على دعم مدمج لتشغيل الأقسام وتثبيتها.
  • يجب تحميل وحدات Kernel من قسم للقراءة فقط.
  • بالنسبة للأجهزة المطلوبة للتحقق من التمهيد، يجب تحميل وحدات kernel من الأقسام التي تم التحقق منها.
  • لا ينبغي أن تكون وحدات Kernel موجودة في /system .
  • يجب تحميل وحدات GKI المطلوبة للجهاز من /system/lib/modules وهو رابط رمزي إلى /system_dlkm/lib/modules .
  • يجب أن تكون وحدات Kernel من بائع SoC المطلوبة لأوضاع Android أو Charger الكاملة موجودة في /vendor/lib/modules .
  • في حالة وجود قسم ODM، يجب أن تكون وحدات kernel من ODM المطلوبة لأوضاع Android أو Charger الكاملة موجودة في /odm/lib/modules . بخلاف ذلك، يجب أن تكون هذه الوحدات موجودة في /vendor/lib/modules .
  • يجب أن تكون وحدات Kernel من بائع SoC وODM المطلوبة لوضع الاسترداد موجودة في ramfs الاسترداد في /lib/modules .
  • يجب أن تكون وحدات Kernel المطلوبة لكل من وضع الاسترداد وأوضاع Android أو Charger الكاملة موجودة في rootfs الاسترداد وإما في أقسام /vendor أو /odm (كما هو موضح أعلاه).
  • لا ينبغي أن تعتمد وحدات Kernel المستخدمة في وضع الاسترداد على الوحدات الموجودة في /vendor أو /odm فقط، حيث لا يتم تثبيت هذه الأقسام في وضع الاسترداد.
  • لا ينبغي أن تعتمد وحدات نواة بائع SoC على وحدات نواة ODM.

في Android 7.x والإصدارات الأقدم، لا يتم تثبيت أقسام /vendor و /odm مبكرًا. في Android 8.x والإصدارات الأحدث، ولجعل تحميل الوحدة من هذه الأقسام ممكنًا، تم وضع شروط لتحميل الأقسام مبكرًا لكل من الأجهزة غير A/B وA/B . ويضمن هذا أيضًا تثبيت الأقسام في وضعي Android وCharger.

دعم نظام بناء أندرويد

في BoardConfig.mk ، يحدد إصدار Android متغير BOARD_VENDOR_KERNEL_MODULES الذي يوفر قائمة كاملة بوحدات kernel المخصصة لصورة البائع. يتم نسخ الوحدات المدرجة في هذا المتغير إلى صورة البائع في /lib/modules/ ، وبعد تثبيتها على Android، تظهر في /vendor/lib/modules (وفقًا للمتطلبات المذكورة أعلاه). مثال لتكوين وحدات نواة البائع:

vendor_lkm_dir := device/$(vendor)/lkm-4.x
BOARD_VENDOR_KERNEL_MODULES := \
  $(vendor_lkm_dir)/vendor_module_a.ko \
  $(vendor_lkm_dir)/vendor_module_b.ko \
  $(vendor_lkm_dir)/vendor_module_c.ko

في هذا المثال، يتم تعيين مستودع تم إنشاؤه مسبقًا لوحدة نواة المورد في إصدار Android في الموقع المذكور أعلاه.

قد تحتوي صورة الاسترداد على مجموعة فرعية من وحدات البائع. يحدد إصدار Android المتغير BOARD_RECOVERY_KERNEL_MODULES لهذه الوحدات. مثال:

vendor_lkm_dir := device/$(vendor)/lkm-4.x
BOARD_RECOVERY_KERNEL_MODULES := \
  $(vendor_lkm_dir)/vendor_module_a.ko \
  $(vendor_lkm_dir)/vendor_module_b.ko

يعتني إصدار Android بتشغيل depmod لإنشاء ملفات modules.dep المطلوبة في /vendor/lib/modules و /lib/modules ( recovery ramfs ).

تحميل الوحدة النمطية وإصدارها

قم بتحميل جميع وحدات kernel في مسار واحد من init.rc* عن طريق استدعاء modprobe -a . يؤدي هذا إلى تجنب الحمل الزائد لتهيئة بيئة تشغيل C بشكل متكرر للثنائي modprobe . يمكن تعديل حدث early-init لاستدعاء modprobe :

on early-init
    exec u:r:vendor_modprobe:s0 -- /vendor/bin/modprobe -a -d \
        /vendor/lib/modules module_a module_b module_c ...

عادةً، يجب تجميع وحدة النواة مع النواة التي سيتم استخدام الوحدة معها (وإلا فإن النواة سترفض تحميل الوحدة). يوفر CONFIG_MODVERSIONS حلاً بديلاً عن طريق اكتشاف الأعطال في الواجهة الثنائية للتطبيق (ABI). تحسب هذه الميزة قيمة فحص التكرار الدوري (CRC) للنموذج الأولي لكل رمز مُصدر في النواة وتخزن القيم كجزء من النواة؛ بالنسبة للرموز المستخدمة بواسطة وحدة kernel، يتم تخزين القيم أيضًا في وحدة kernel. عند تحميل الوحدة، تتم مقارنة قيم الرموز المستخدمة بواسطة الوحدة مع تلك الموجودة في النواة. إذا تطابقت القيم، فسيتم تحميل الوحدة؛ وإلا فشل التحميل.

لتمكين تحديث صورة النواة بشكل منفصل عن صورة البائع، قم بتمكين CONFIG_MODVERSIONS . يؤدي القيام بذلك إلى إجراء تحديثات صغيرة للنواة (مثل إصلاحات الأخطاء من LTS) مع الحفاظ على التوافق مع وحدات kernel الموجودة في صورة البائع. ومع ذلك، لا يقوم CONFIG_MODVERSIONS بإصلاح انقطاع ABI بمفرده. إذا تغير النموذج الأولي لرمز مُصدَّر في kernel، إما بسبب تعديل المصدر أو بسبب تغيير تكوين kernel، فإن هذا يؤدي إلى انقطاع التوافق مع وحدات kernel التي تستخدم هذا الرمز. في مثل هذه الحالات، يجب إعادة ترجمة وحدة kernel.

على سبيل المثال، تحتوي بنية task_struct في النواة (المحددة في include/linux/sched.h ) على العديد من الحقول المضمنة بشكل مشروط اعتمادًا على تكوين النواة. حقل sched_info موجود فقط إذا تم تمكين CONFIG_SCHED_INFO (والذي يحدث عند تمكين CONFIG_SCHEDSTATS أو CONFIG_TASK_DELAY_ACCT ). إذا تغيرت حالة خيارات التكوين هذه، يتغير تخطيط بنية task_struct ويتم تغيير أي واجهات مصدرة من kernel تستخدم task_struct (على سبيل المثال، set_cpus_allowed_ptr في kernel/sched/core.c ). ينقطع التوافق مع وحدات kernel التي تم تجميعها مسبقًا والتي تستخدم هذه الواجهات، مما يتطلب إعادة بناء هذه الوحدات باستخدام تكوين kernel الجديد.

لمزيد من التفاصيل حول CONFIG_MODVERSIONS ، راجع الوثائق الموجودة في شجرة النواة في Documentation/kbuild/modules.rst .