با استفاده از Binder IPC

این صفحه تغییرات درایور binder در Android 8 را توضیح می دهد ، جزئیاتی در مورد استفاده از IPC binder ارائه می دهد و خط مشی SELinux مورد نیاز را لیست می کند.

تغییرات در درایور binder

با شروع از Android 8 ، چارچوب Android و HALs اکنون با استفاده از binder با یکدیگر ارتباط برقرار می کنند. از آنجا که این ارتباط به طور چشمگیری ترافیک اتصال دهنده را افزایش می دهد ، اندروید 8 شامل چندین پیشرفت است که برای حفظ سریع IPC اتصال دهنده طراحی شده است. SoC با فروشندگان و OEM ها باید به طور مستقیم از شاخه مربوط به اندروید 4.4 ادغام، اندیشه-4.9 و بالاتر از هسته / مشترک پروژه.

دامنه های متعدد اتصال دهنده (زمینه)

رایج-4.4 و بالاتر ، از جمله بالادست

به تقسیم پاک ترافیک چسب بین چارچوب (دستگاه مستقل) و فروشنده (ویژه دستگاه) کد، آندروید 8 مفهوم یک زمینه چسب معرفی شده است. هر زمینه اتصال دهنده گره دستگاه خاص خود و مدیر زمینه (سرویس) خاص خود را دارد. شما فقط از طریق گره دستگاهی که به آن تعلق دارد می توانید به مدیر زمینه دسترسی داشته باشید و هنگام عبور یک گره اتصال دهنده از یک زمینه خاص ، فقط با یک فرایند دیگر از همان زمینه قابل دسترسی است ، بنابراین دامنه ها را کاملاً از یکدیگر جدا می کند. برای جزئیات در مورد، و vndbinder و vndservicemanager .

پراکنده-جمع کردن

رایج-4.4 و بالاتر ، از جمله بالادست

در نسخه های قبلی اندروید ، هر قطعه داده در یک تماس گیرنده سه بار کپی شد:

  • هنگامی که به مرتب آن را به یک Parcel در روند خواستار
  • هنگامی که در درایور هسته برای کپی کردن Parcel به فرایند هدف
  • هنگامی که به unserialize Parcel در فرایند هدف

آندروید 8 استفاده پراکنده جمع آوری بهینه سازی به منظور کاهش تعداد کپی از 3 تا 1. به جای serialize کردن داده ها در یک Parcel برای اولین بار، داده باقی مانده در ساختار و حافظه طرح اصلی آن و راننده بلافاصله نسخه آن را به روند هدف. بعد از اینکه داده ها در فرایند مورد نظر قرار گرفتند ، ساختار و طرح حافظه یکسان است و داده ها بدون نیاز به کپی دیگر قابل خواندن هستند.

قفل دانه ریز

رایج-4.4 و بالاتر ، از جمله بالادست

در نسخه های قبلی Android ، درایور binder از قفل جهانی برای محافظت در برابر دسترسی همزمان به ساختارهای مهم داده استفاده می کرد. در حالی که حداقل بحث برای قفل وجود داشت ، مشکل اصلی این بود که اگر یک نخ با اولویت پایین قفل را بدست آورد و سپس پیشگیری شود ، می تواند نخ های با اولویت بالاتر را که نیاز به قفل یکسان دارند به طور جدی به تأخیر بیندازد. این باعث تکان خوردن در سکو شد.

تلاش های اولیه برای حل این مشکل شامل غیرفعال کردن preemption در حالی که قفل سراسری را نگه می داشت ، می شد. با این حال ، این بیشتر یک هک بود تا یک راه حل واقعی ، و در نهایت توسط بالادست رد شد و کنار گذاشته شد. تلاشهای بعدی بر روی قفل سازی بسیار دقیق تر تمرکز کرد ، نسخه ای که از ژانویه 2017 روی دستگاههای Pixel اجرا می شود. در حالی که اکثر این تغییرات به صورت عمومی منتشر شد ، پیشرفت های قابل توجهی در نسخه های بعدی انجام شد.

پس از شناسایی مسائل کوچک در اجرای قفل ریز ریز ، ما یک راه حل بهبود یافته با معماری قفل متفاوت طراحی کردیم و تغییرات را در تمام شاخه های هسته رایج ارائه کردیم. ما همچنان این پیاده سازی را روی تعداد زیادی از دستگاه های مختلف آزمایش می کنیم. از آنجا که ما از هیچ مشکل برجسته ای بی اطلاع هستیم ، این پیاده سازی توصیه شده برای دستگاه هایی است که با Android 8 ارسال می شوند.

ارث اولویت در زمان واقعی

مشترک -4.4 و رایج -4.9 (بالادست به زودی)

درایور binder همیشه از ارث اولویت خوب پشتیبانی می کند. از آنجا که تعداد فزاینده فرآیندها در Android با اولویت زمان واقعی اجرا می شوند ، در برخی موارد منطقی به نظر می رسد که اگر یک موضوع زمان واقعی یک تماس گیرنده انجام دهد ، نخ در فرآیند که آن تماس را مدیریت می کند نیز با اولویت زمان واقعی اجرا می شود به برای پشتیبانی از موارد استفاده ، اندروید 8 در حال حاضر ارث اولویت در زمان واقعی را در درایور binder پیاده سازی می کند.

علاوه بر سطح معامله ارث اولویت، ارث اولویت گره اجازه می دهد تا یک گره (چسب جسم خدمات) برای مشخص کردن یک اولویت حداقل که در آن تماس به این گره باید اعدام شوند. نسخه های قبلی آندروید قبلاً از ارث اولویت گره با مقادیر خوب پشتیبانی می کردند ، اما اندروید 8 از سیاست های زمانبندی زمانبندی وراثت گره پشتیبانی می کند.

تغییر فضای کاربری

آندروید 8 شامل تمام فضای کاربری تغییرات مورد نیاز برای کار با راننده چسب فعلی در هسته مشترک با یک استثنا: اجرای اصلی به غیر فعال کردن زمان واقعی ارث اولویت برای /dev/binder مورد استفاده قرار IOCTL . توسعه بعدی کنترل وراثت اولویت را به روشی دانه ریزتر تبدیل کرد که در هر حالت اتصال دهنده (و نه در هر زمینه) است. بنابراین، IOCTL است در شعبه مشترک آندروید نیست و به جای آن در دانه مشترک ما ارسال .

اثر این تغییر این است که در زمان واقعی ارث اولویت به طور پیش فرض برای هر گره غیر فعال است. تیم عملکرد آندروید آن را سودمند برای فعال زمان واقعی ارث اولویت برای تمام گره ها در پیدا کرده است hwbinder دامنه. برای رسیدن به این همان اثر، گیلاس-انتخاب این تغییر در فضای کاربری.

SHA برای هسته های معمولی

برای به دست آوردن تغییرات لازم در درایور اتصال دهنده ، با SHA مناسب همگام سازی کنید:

  • مشترک -3.18
    cc8b90c121de ANDROID: binder: مجوزهای اولیه را در هنگام بازیابی بررسی نکنید.
  • رایج -4.4
    76b376eac7a2 ANDROID: binder: مجوزهای اولیه را در هنگام بازیابی بررسی نکنید.
  • مشترک -4.9
    ecd972d4f9b5 ANDROID: binder: مجوزهای اولیه را در هنگام بازیابی بررسی نکنید.

استفاده از IPC اتصال دهنده

از لحاظ تاریخی ، فرآیندهای فروشنده برای برقراری ارتباط از اتصال بین پردازش های اتصال دهنده (IPC) استفاده کرده اند. در آندروید 8، /dev/binder گره دستگاه منحصر به فرد به فرآیندهای چارچوب می شود، به این معنی فرآیندهای فروشنده دیگر به آن دسترسی دارند. فرآیندهای فروشنده می تواند دسترسی /dev/hwbinder ، اما باید رابط AIDL خود را به استفاده HIDL تبدیل کنید. برای فروشندگانی که مایل به استفاده از رابط AIDL بین فرآیندهای فروشنده هستند ، Android از IPC اتصال دهنده به شرح زیر پشتیبانی می کند.

vndbinder

آندروید 8 پشتیبانی از دامنه چسب جدید برای استفاده توسط خدمات فروشنده، دیده با استفاده از /dev/vndbinder به جای /dev/binder . علاوه بر این با /dev/vndbinder ، آندروید در حال حاضر در بر داشت زیر سه حوزه 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 کتابخانه فضای کاربری، که راننده چسب باز می شود. اضافه کردن یک روش برای ::android::ProcessState() را انتخاب راننده چسب برای libbinder . فرآیندهای فروشنده باید از این روش قبل از تماس به پاسخ ProcessState, IPCThreadState ، یا قبل از ساخت هر گونه تماس چسب به طور کلی. برای استفاده، تماس زیر را بعد از main() از یک فرآیند فروشنده (کلاینت و سرور):

ProcessState::initWithDriver("/dev/vndbinder");

vndservicemanager

پیش از این، خدمات چسب با ثبت نام کرده بودند servicemanager ، جایی که آنها را می توان با فرآیندهای دیگر بازیابی می شوند. در آندروید 8، servicemanager در حال حاضر به طور انحصاری توسط چارچوب و برنامه فرآیندها و فرآیندهای فروشنده می تواند دسترسی دیگر آن استفاده می شود.

با این حال، خدمات فروشنده هم اکنون می توانید vndservicemanager ، یک نمونه جدید از servicemanager که با استفاده از /dev/vndbinder به جای /dev/binder و است که از همان منابع به عنوان چارچوب ساخته شده servicemanager . فرآیندهای فروشنده نیازی به ایجاد تغییرات به صحبت vndservicemanager ؛ هنگامی که یک فرآیند فروشنده باز می شود / dev/vndbinder ، متغیر سرویس به طور خودکار به vndservicemanager .

vndservicemanager برنامه در Makefile ها دستگاه پیش فرض آندروید گنجانده شده است.

سیاست SELinux

فرآیندهای فروشنده که می خواهند از قابلیت اتصال دهنده برای ارتباط با یکدیگر استفاده کنند به موارد زیر نیاز دارند:

  1. دسترسی به /dev/vndbinder .
  2. بند {transfer, call} قلاب به vndservicemanager .
  3. binder_call(A, B) برای هر فروشنده دامین A که می خواهد به پاسخ به دامنه فروشنده ب بیش از رابط کاربری فروشنده چسب.
  4. اجازه {add, find} خدمات در vndservicemanager .

در تطابق با الزامات 1 و 2، با استفاده از vndbinder_use() ماکرو:

vndbinder_use(some_vendor_process_domain);

برای تحقق نیاز 3، binder_call(A, B) برای فروشنده فرآیندهای A و B که نیاز به صحبت کردن بیش از چسب می توانید در محل باقی بماند، و تغییر نام نیاز ندارد.

برای برآوردن شرط 4 ، باید در نحوه مدیریت نام خدمات ، برچسب خدمات و قوانین تغییراتی ایجاد کنید.

برای جزئیات در مورد نصب SELinux، و امنیت پیشرفته لینوکس در آندروید . برای جزئیات در مورد SELinux را در آندروید 8.0، و نصب SELinux برای آندروید 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

در آندروید 8، vndservicemanager بارهای vndservice_contexts به جای فایل. خدمات مهاجرت به فروشنده vndservicemanager (و در حال حاضر در قدیمی service_contexts فایل) باید به جدید اضافه شده vndservice_contexts فایل.

برچسب خدمات

پیش از این، خدمات برچسب مانند u:object_r:atfwd_service:s0 در یک تعریف شد service.te فایل. مثال:

type atfwd_service,      service_manager_type;

در آندروید 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;

در اندروید 8 ، چنین قوانینی می توانند ثابت بمانند و از یک کلاس استفاده کنند. مثال:

allow atfwd atfwd_service:service_manager find;
allow some_vendor_app atfwd_service:service_manager add;