كجزء من متطلبات نواة الوحدة التي تم تقديمها في 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
recoveryramfs
في/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
.