تصف هذه الصفحة التغييرات التي طرأت على برنامج تشغيل المجلدات في Android 8، وتقدم تفاصيل حول استخدام binder IPC، بالإضافة إلى قائمة بسياسة SELinux المطلوبة.
تغييرات في برنامج تشغيل مادة الربط
بدءًا من نظام Android 8، أصبح إطار عمل Android وHALs يتواصلان مع بعضنا البعض باستخدام المربط. مع زيادة هذا التواصل بشكل كبير حركة البيانات، يتضمّن Android 8 العديد من التحسينات المصمّمة للحفاظ على IPC. بسرعة. يجب دمج موردي المنظومة على الرقاقة (SoC) والمصنّعين الأصليين للأجهزة بشكل مباشر من فروع android-4.4 وandroid-4.9 والإصدارات الأحدث من kernel/common.
نطاقات المجلدات المتعددة (السياقات)
Common-4.4 والإصدارات الأعلى، بما في ذلك الإعلانات الرئيسيةلتقسيم حركة بيانات الملصق بشكل نظيف بين إطار العمل (مستقل عن الجهاز) و (الخاص بالجهاز)، طرح Android 8 مفهوم ملف الربط السياقية. لكل سياق أداة ربط عقدة خاصة بها على الجهاز وسياق خاص (الخدمة). لا يمكنك الوصول إلى مدير السياق إلا من خلال الجهاز. التي تنتمي إليها، وعند تمرير عقدة ربط عبر عقدة السياق، فيمكن الوصول إليه من نفس هذا السياق فقط عن طريق عملية أخرى، وبالتالي مع عزل المجالات عن بعضها البعض تمامًا. للحصول على تفاصيل حول الاستخدام، يمكنك الاطّلاع على vndbinder vndservicemanager.
جمع مبعثر
Common-4.4 والإصدارات الأعلى، بما في ذلك الإعلانات الرئيسيةفي الإصدارات السابقة من Android، كان يتم نسخ كل جزء من البيانات في استدعاء المجلد ثلاث مرات:
- بمجرد وضعه في تسلسل
Parcel
في عملية الاتصال - بعد الدخول إلى برنامج تشغيل النواة لنسخ
Parcel
إلى الهدف. المعالجة - مرة واحدة لإلغاء تسلسل
Parcel
في العملية المستهدفة
استخدامات Android 8
الجمع بالنقاط المبعثرة
التحسين لتقليل عدد النُسخ من 3 إلى 1. بدلاً من
إنشاء تسلسل للبيانات في Parcel
أولاً، وتظل البيانات بطبيعتها
البنية وتخطيط الذاكرة وسينسخه برنامج التشغيل على الفور إلى الجهاز المستهدف
الدفع. بعد دخول البيانات في العملية المستهدفة، يتم تحديد البنية والذاكرة
هو نفسه ويمكن قراءة البيانات دون الحاجة إلى نسخة أخرى.
قفل دقيق بدقة
Common-4.4 والإصدارات الأعلى، بما في ذلك الإعلانات الرئيسيةفي إصدارات Android السابقة، استخدم برنامج تشغيل الحافظة قفلاً عامًا لحماية ضد الوصول المتزامن إلى هياكل البيانات الهامة. بينما كان هناك حد أدنى على القفل، كانت المشكلة الرئيسية هي أنه إذا لم يتم العثور على حصل على القفل ثم تمت إزالته بشكل استباقي، فقد يؤخر ذلك بشدة ذات الأولوية الأعلى التي تحتاج إلى نفس القفل. وقد تسبب هذا في عطل في بدون خادم.
تضمّنت المحاولات الأولية لحلّ هذه المشكلة إيقاف ميزة الاستباقية أثناء الضغط مع الاستمرار على القفل العام. ومع ذلك، كان هذا تحديًا أكثر من كونه حلاً حقيقيًا، وتم رفضه في النهاية من قبل التسليم وتم تجاهلها. المحاولات اللاحقة وكان التركيز على جعل قفل الباب أكثر دقّة، وهو إصدار حالي على أجهزة Pixel منذ كانون الثاني (يناير) 2017 في حين أن غالبية هذه التغييرات كانت علنًا، وتم إدخال تحسينات جوهرية في الإصدارات اللاحقة.
بعد تحديد المشكلات الصغيرة في تطبيق القفل الدقيق، وابتكرت حلاً مُحسناً ببنية قفل مختلفة وأرسلت التغييرات في جميع فروع النواة المشتركة. نواصل اختبار هذا والتنفيذ على عدد كبير من الأجهزة المختلفة؛ حيث لا نكون على دراية بأي مشاكل عالقة، فهذا هو التنفيذ الموصى به لشحن الأجهزة مع Android 8.
اكتساب الأولوية في الوقت الفعلي
Common-4.4 وcommon-4.9 (يتوفّر في مرحلة الإنتاج قريبًا)دائمًا ما يدعم برنامج تشغيل المجلَّد توريث الأولوية الجيد. على سبيل المثال، زيادة عدد العمليات في Android التي تعمل بأولوية الوقت الفعلي، وفي بعض الحالات، فمن المنطقي الآن أنه إذا قامت سلسلة تعليمات في الوقت الفعلي بإجراء استدعاء بيندر، سلسلة التعليمات في العملية التي تعالج هذا الاستدعاء تعمل أيضًا بأولوية الوقت الفعلي. إلى لدعم حالات الاستخدام هذه، يطبّق Android 8 الآن اكتساب الأولوية في الوقت الفعلي. في برنامج تشغيل الربط.
بالإضافة إلى اكتساب الأولوية على مستوى المعاملة، أولوية العقدة التوريث يسمح للعقدة (كائن خدمة الربط) بتحديد الحد الأدنى الأولوية التي يجب عندها تنفيذ الاستدعاءات في هذه العقدة. الإصدارات السابقة من كان نظام Android يتيح حاليًا اكتساب أولوية العُقد بقيم جيدة، ولكن يتيح الإصدار Android 8 إمكانية اكتساب عُقد سياسات الجدولة في الوقت الفعلي.
تغييرات مساحة المستخدم
يتضمن Android 8 جميع التغييرات المطلوبة على مساحة المستخدم للعمل مع
برنامج تشغيل المجلَّد في النواة المشتركة، مع استثناء واحد:
التنفيذ لإيقاف توريث الأولوية في الوقت الفعلي
/dev/binder
استخدم
ioctl تم تبديل الأولوية في عملية التطوير اللاحقة.
إلى طريقة أكثر دقة تتوافق مع وضع الربط (وليس وفقًا
السياق). وبالتالي، فإن الأوكتان غير موجودتين في الفرع الشائع لنظام Android وبدلاً من ذلك
في النواة الشائعة لدينا.
يتمثل تأثير هذا التغيير في إيقاف توريث الأولوية في الوقت الفعلي من خلال
الإعداد التلقائي لكل عقدة. وجد فريق أداء Android أنه
مفيد لتفعيل توريث الأولوية في الوقت الفعلي لجميع العُقد في
نطاق hwbinder
. ولتحقيق ذلك التأثير نفسه،
هذا التغيير في مساحة المستخدم.
خوارزمية SHA للنواة الشائعة
وللحصول على التغييرات اللازمة على برنامج تشغيل المجلد، يمكنك المزامنة مع خوارزمية SHA المناسبة:
- شائعة-3.18
cc8b90c121de ANDROID: binder: لا تتحقق من أذونات prio عند الاستعادة. - الشائع-4.4
76b376eac7a2 ANDROID: البيندر: عدم التحقق من أذونات Prio عند الاستعادة. - الشائع-4.9
ecd972d4f9b5 ANDROID: binder: لا تتحقق من أذونات Prio عند الاستعادة.
العمل باستخدام binder IPC
سابقًا، استخدمت عمليات البائعين الاتصال البيني للعمليات بين المرابط
(IPC) للتواصل. في Android 8، عقدة الجهاز /dev/binder
حصرية لعمليات إطار العمل، مما يعني أن عمليات البائعين لم تعد
حق الوصول إليها. يمكن لعمليات المورّدين الوصول إلى "/dev/hwbinder
"، ولكن
تحويل واجهات AIDL لاستخدام HIDL. للمورّدين الذين يريدون المتابعة
باستخدام واجهات AIDL بين عمليات المورد، يدعم Android بروتوكول binder IPC
الموضحة أدناه. في Android 10، تسمح واجهة AIDL الثابتة بجميع
استخدام /dev/binder
مع إيجاد حل لتحقيق الاستقرار أيضًا
يضمن حل مشكلة HIDL و/dev/hwbinder
. لمعرفة كيفية استخدام القناة الثابتة
AIDL، مراجعة
AIDL لشهادات HALs:
Vndbinder
يتيح Android 8 استخدام نطاق مستند جديد لاستخدامه من خلال خدمات المورّدين، ويمكن الوصول إليها.
باستخدام /dev/vndbinder
بدلاً من /dev/binder
. مع
عند إضافة /dev/vndbinder
، يتضمّن Android الآن العناصر الثلاثة التالية
نطاقات IPC:
مجال IPC | الوصف |
---|---|
/dev/binder |
IPC بين عمليات التطبيق/إطار العمل من خلال واجهات AIDL |
/dev/hwbinder |
IPC بين عمليات إطار العمل/المورّد من خلال واجهات HIDL
بروتوكول IPC بين عمليات المورّدين من خلال واجهات HIDL |
/dev/vndbinder |
IPC بين عمليات البائعين/المورِّدين باستخدام واجهات AIDL |
لكي تظهر الدالة /dev/vndbinder
، تأكَّد من ضبط النواة.
تم ضبط العنصر CONFIG_ANDROID_BINDER_DEVICES
على
"binder,hwbinder,vndbinder"
(هذا هو الخيار التلقائي في
أشجار النواة الشائعة).
عادةً، لا تفتح عمليات المورِّد برنامج الربط بشكل مباشر وبدلاً من ذلك
رابط في مكتبة مساحة المستخدم libbinder
، ما يؤدي إلى فتح
برنامج تشغيل binder. جارٍ إضافة طريقة لـ ::android::ProcessState()
يحدد برنامج تشغيل الحافظ لـ libbinder
. ينبغي أن تساعد عمليات البائعين
عليك استدعاء هذه الطريقة قبل استدعاء ProcessState,
IPCThreadState
، أو قبل إجراء أي طلبات تثبيت بشكل عام. إلى
للاستخدام، يُرجى إجراء المكالمة التالية بعد main()
من عملية معالجة المورِّد.
(العميل والخادم):
ProcessState::initWithDriver("/dev/vndbinder");
vndservicemanager
في السابق، كان يتم تسجيل خدمات التجليد لدى servicemanager
،
حيث يمكن استردادها من خلال عمليات أخرى. في Android 8،
يُستخدَم servicemanager
الآن حصريًا من خلال إطار العمل والتطبيق.
ولم يعد بإمكان العمليات وعمليات البائع الوصول إليها.
ومع ذلك، يمكن لخدمات المورّدين الآن استخدام vndservicemanager
، وهو نطاق
مثيل لـ servicemanager
يستخدم /dev/vndbinder
بدلاً من /dev/binder
والتي تم إنشاؤها من المصادر نفسها مثل
إطار العمل servicemanager
. لا تحتاج عمليات البائعين إلى إجراء
التغييرات للتحدّث إلى vndservicemanager
عندما تفتح عملية البائع
/dev/vndbinder
، تنتقل عمليات البحث عن الخدمة تلقائيًا إلى
vndservicemanager
يكون برنامج vndservicemanager
الثنائي مضمّنًا في برنامج Android التلقائي.
ملفات تصميم الجهاز.
سياسة SELinux
عمليات المورد التي تريد استخدام وظيفة المثبت للتواصل مع على بعضنا البعض ما يلي:
- إذن الوصول إلى "
/dev/vndbinder
" - وصل
{transfer, call}
خطّافاتvndservicemanager
binder_call(A, B)
لأي نطاق مورّد "أ" يريد الاتصال إلى مجال المورد B عبر واجهة أداة ربط البائع.- إذن بالوصول إلى
{add, find}
خدمة فيvndservicemanager
لاستيفاء الشرطَين 1 و2، يمكنك استخدام vndbinder_use()
.
وحدة الماكرو:
vndbinder_use(some_vendor_process_domain);
لتلبية المطلب 3، binder_call(A, B)
للمورّد
يمكن أن تظل العملية A وB اللتين تحتاجان إلى التحدث من خلال الحافظ في مكانهما، ولا
بحاجة إلى إعادة التسمية.
لتلبية المطلب 4، يجب إجراء تغييرات في طريقة أسماء الخدمات وتصنيفات الخدمة والقواعد.
للحصول على تفاصيل حول SELinux، يُرجى الاطّلاع على Security- لعب محسّن Linux في Android. للحصول على تفاصيل حول SELinux في Android 8.0، راجع SELinux لنظام Android 8.0.
أسماء الخدمات
في السابق، كان البائع يعالج أسماء الخدمات في
ملف واحد (service_contexts
) وإضافة القواعد المقابلة للوصول إليه
لهذا الملف. مثال على ملف service_contexts
من
device/google/marlin/sepolicy
:
AtCmdFwd u:object_r:atfwd_service:s0 cneservice u:object_r:cne_service:s0 qti.ims.connectionmanagerservice u:object_r:imscm_service:s0 rcs u:object_r:radio_service:s0 uce u:object_r:uce_service:s0 vendor.qcom.PeripheralManager u:object_r:per_mgr_service:s0
في Android 8، يحمّل vndservicemanager
ملف vndservice_contexts
بدلاً من ذلك. نقل خدمات المورّدين إلى
vndservicemanager
(والتي سبق أن تمّت إضافتها إلى الإصدار القديم
ملف service_contexts
) يجب إضافته إلى الملف الجديد
ملف vndservice_contexts
.
تصنيفات الخدمة
في السابق، كانت تصنيفات الخدمات مثل u:object_r:atfwd_service:s0
في ملف service.te
. مثال:
type atfwd_service, service_manager_type;
في Android 8، يجب تغيير النوع إلى
vndservice_manager_type
ونقل القاعدة إلى
ملف vndservice.te
. مثال:
type atfwd_service, vndservice_manager_type;
قواعد مدير الخدمة
في السابق، كانت القواعد تمنح النطاقات إمكانية الوصول لإضافة خدمات أو العثور عليها من
servicemanager
مثال:
allow atfwd atfwd_service:service_manager find; allow some_vendor_app atfwd_service:service_manager add;
في نظام Android 8، يمكن أن تظل هذه القواعد سارية وتستخدم الفئة نفسها. مثال:
allow atfwd atfwd_service:service_manager find; allow some_vendor_app atfwd_service:service_manager add;