استخدام binder IPC

تصف هذه الصفحة التغييرات التي طرأت على برنامج تشغيل المجلدات في 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

عمليات المورد التي تريد استخدام وظيفة المثبت للتواصل مع على بعضنا البعض ما يلي:

  1. إذن الوصول إلى "/dev/vndbinder"
  2. وصل {transfer, call} خطّافات vndservicemanager
  3. binder_call(A, B) لأي نطاق مورّد "أ" يريد الاتصال إلى مجال المورد B عبر واجهة أداة ربط البائع.
  4. إذن بالوصول إلى {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;