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

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

خيارات ضبط النواة

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

CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODVERSIONS=y

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

توقيع الوحدة

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

أماكن الملفات

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

وضع التشغيل مساحة التخزين الشاشة لوحة المفاتيح البطارية PMIC الشاشة التي تعمل باللمس تقنية NFC وWi-Fi و
البلوتوث
أجهزة الاستشعار الكاميرا
الاسترداد
شاحن
Android

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

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

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

توافق نظام تصميم Android

في BoardConfig.mk، يحدِّد إصدار Android متغيّرًا BOARD_VENDOR_KERNEL_MODULES يقدّم قائمة كاملة بوحدات النواة المخصّصة لصورة المورّد. يتم نسخ الوحدات المدرَجة في هذا المتغيّر إلى صورة المورّد في /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

في هذا المثال، تمّ ربط مستودع مُنشئ مسبقًا لمكوّن kernel الخاص بالمورّد في إصدار 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 ...

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

لتفعيل تحديث صورة النواة بشكل منفصل عن صورة المورّد، فعِّل CONFIG_MODVERSIONS. يتيح ذلك إجراء تعديلات صغيرة على ملف التمهيد (مثل إصلاحات الأخطاء من الإصدار LTS) مع الحفاظ على التوافق مع وحدات ملف التمهيد الحالية في صورة المورّد. ومع ذلك، CONFIG_MODVERSIONS لا يصلح مشكلة تعذُّر توفُّر ABI من تلقاء نفسه. إذا تغيّر ملف النموذج الأولي لرمز تم تصديره في النواة، إما بسبب تعديل المصدر أو بسبب تغيير إعدادات النواة، يؤدي ذلك إلى إيقاف التوافق مع وحدات النواة التي تستخدم هذا الرمز. في هذه الحالات، يجب إعادة تجميع وحدة 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.