בדף הזה מתוארים השינויים במנהל התקן של קלסרים ב-Android 8, פרטים על השימוש ב-binder IPC ורשימות של מדיניות SELinux נדרשת.
שינויים במנהל ההתקן של הקישור
החל מגרסת Android 8, מסגרת Android ומכשירי HAL מתקשרים עכשיו עם באמצעות קלסרים. התקשורת הזו מגדילה משמעותית את קלסרים תנועה, Android 8 כולל כמה שיפורים שנועדו לשמור על IPC של קישור מהר. ספקי SoC ויצרני ציוד מקורי צריכים למזג ישירות מהסניפים הרלוונטיים של android-4.4, android-4.9 ואילך kernel/common.
דומיינים מרובים של כלי קישור (הקשרים)
Common-4.4 ואילך, כולל upstreamכדי לפצל באופן ברור את התנועה ב-Binder בין framework (תלוי מכשיר) לבין קוד של ספק (ספציפי למכשיר), Android 8 הוסיפה את הקונספט של קלסר הקשר מסוים. לכל הקשר של קישור יש צומת מכשיר משלו והקשר משלו מנהל (שירות). אפשר לגשת אל מנהל ההקשר רק דרך המכשיר שאליו הוא שייך, ובעת העברת צומת של קישור דרך הוא זמין מאותו הקשר רק באמצעות תהליך אחר, לבודד לגמרי את הדומיינים זה מזה. פרטים על השימוש זמינים במאמר vndbinder וגם vndservicemanager.
פיזור
Common-4.4 ואילך, כולל upstreamבגרסאות קודמות של Android, כל פיסת נתונים בקריאה ל-binder הועתקה שלוש פעמים:
- פעם אחת כדי להפוך אותו לסדרה
Parcel
בתהליך השיחה - אחרי שנכנסים למנהל התקן הליבה כדי להעתיק את
Parcel
אל היעד תהליך דיפוזיה הפוך - פעם אחת כדי לבטל את הסדרת
Parcel
בתהליך היעד
במכשיר Android 8
פיזור-איסוף
כדי להפחית את מספר העותקים מ-3 ל-1. במקום
ראשית, הסדרת נתונים בParcel
נשארת במקור
של המודל ופריסת הזיכרון, והנהג מעתיק אותו מיד ליעד
תהליך האימות. אחרי שהנתונים נמצאים בתהליך היעד, המבנה והזיכרון
זהה ואפשר לקרוא את הנתונים בלי צורך בעותק נוסף.
נעילה פרטנית
Common-4.4 ואילך, כולל upstreamבגרסאות קודמות של Android, מנהל ההתקן של קלסר השתמש בנעילה גלובלית כדי להגן מפני גישה בו-זמנית למבני נתונים קריטיים. אומנם הייתה תקופה מינימלית תחרות לגבי המנעול, הבעיה העיקרית הייתה שאם שרשור עם עדיפות נמוכה השגת את הנעילה ואז קיבלת התראה מוקדמת, זה עלול להוביל לעיכוב חמור שרשורים בעדיפות גבוהה יותר שצריכים לקבל את אותה נעילה. הדבר גרם לבעיות בממשק הפלטפורמה.
הניסיונות הראשוניים לפתור את הבעיה כללו השבתה של המבצע בזמן ומחזיקים את המנעול הגלובלי. אבל זו הייתה יותר פריצה מאשר פתרון אמיתי, ובסופו של דבר נדחה על ידי ה-upstream ונמחק. הניסיונות הבאים שמתמקד בנעילה פרטנית יותר, שגרסה שלה כבר פועלת במכשירי Pixel מאז ינואר 2017. למרות שרוב השינויים האלה היו באופן ציבורי, בוצעו שיפורים משמעותיים בגרסאות הבאות.
אחרי שזיהינו בעיות קלות בהטמעת הנעילה פרטנית, הם פיתחו פתרון משופר עם ארכיטקטורת נעילה שונה, את השינויים בכל הסתעפויות הליבה (kernel) הנפוצות. אנחנו ממשיכים לבדוק לבצע הטמעה במספר גדול של מכשירים שונים, מכיוון שאנחנו לא מודעים עדיין לא טופלו, זהו ההטמעה המומלצת עבור משלוח של מכשירים עם Android 8.
ירושה של עדיפות בזמן אמת
Common-4.4 ו-Common-4.9 (בקרוב)מנהל ההתקן של הקישור תמיד תומך בירושה בעדיפות גבוהה. בתור הולך וגדל מספר התהליכים ב-Android שפועלים בעדיפות בזמן אמת, בחלק עכשיו הגיוני שאם שרשור בזמן אמת מבצע קריאה ל-Binder, בתהליך הטיפול הזה פועל גם הוא בעדיפות בזמן אמת. שפת תרגום שתומכים בתרחישים כאלה, ב-Android 8 מתבצעת עכשיו ירושה של עדיפות בזמן אמת במנהל הקישורים.
בנוסף לירושה של עדיפות ברמת העסקה, עדיפות של צומת ירושה מאפשרת לצומת (אובייקט שירות קישור) לציין שבו יש לבצע קריאות לצומת הזה. גרסאות קודמות של מערכת Android כבר תומכת בירושה של עדיפות צמתים עם ערכים נחמדים, אבל ב-Android 8 נוספה תמיכה בירושה של צמתים במדיניות לתזמון בזמן אמת.
שינויים במרחב המשתמשים
Android 8 כולל את כל השינויים במרחב המשתמשים שנדרשים כדי לעבוד עם הגרסה הנוכחית
של מנהל התקן binder בליבה המשותפת, למעט חריג אחד:
כדי להשבית ירושה של עדיפות בזמן אמת
/dev/binder
השתמש/ה ב
ioctl. בקרת העדיפות שונתה מהפיתוח הבא
ירושה לשיטה פרטנית יותר שפועלת לפי מצב קישור (ולא
הקשר מסוים). לכן, ה-ioctl לא נמצא בהסתעפות המשותפת של Android אלא
נשלחות בליבה (kernel) המשותפת שלנו.
ההשפעה של השינוי הזה היא שירושה של עדיפות בזמן אמת מושבתת על ידי
ברירת מחדל עבור כל צומת. צוות הביצועים של Android מצא
לאפשר ירושה בעדיפות גבוהה בזמן אמת לכל הצמתים
דומיין hwbinder
. כדי להשיג את אותו אפקט, בחרו
השינוי הזה במרחב המשתמשים.
SHAs לליבות נפוצות
כדי לקבל את השינויים הנדרשים במנהל ההתקן של הקישור, צריך לסנכרן עם SHA המתאים:
- Common-3.18
cc8b90c121de ANDROID: binder: לא לבדוק הרשאות prio במהלך השחזור. - Common-4.4
76b376eac7a2 ANDROID: binder: לא צריך לבדוק את ההרשאות ב-Prio במהלך השחזור. - Common-4.9
ecd972d4f9b5 ANDROID: binder: לא לבדוק הרשאות prio במהלך השחזור.
עבודה עם IPC של binder
בעבר, תהליכי ספקים השתמשו בתקשורת בין תהליכים של קלסרים
(IPC) כדי לתקשר. ב-Android 8, הצומת של המכשיר /dev/binder
הופכת לבלעדית לתהליכי framework, כלומר, תהליכי ספק כבר לא זמינים
יכולים לגשת אליו. לתהליכי ספקים יש גישה אל /dev/hwbinder
, אבל
חייבים להמיר את ממשקי ה-AIDL שלהם כדי להשתמש ב-HIDL. לספקים שרוצים להמשיך
באמצעות ממשקי AIDL בין תהליכי ספק, מערכת Android תומכת ב-Binder IPC,
שמתואר בהמשך. ב-Android 10, מערכת Stable AIDL מאפשרת את כל סוגי התוכן
לשימוש ב-/dev/binder
תוך פתרון בעיות היציבות
מובטחות HIDL ו-/dev/hwbinder
שנפתרו. איך להשתמש בערוץ יציב
AIDL, מידע נוסף
AIDL ל-HALs.
Vndbinder
ב-Android 8 יש תמיכה בדומיין חדש של binder לשימוש של שירותי ספקים, שיש גישה אליו
באמצעות /dev/vndbinder
במקום /dev/binder
. עם
התוספת של /dev/vndbinder
, Android כוללת עכשיו את שלושת הסוגים הבאים
דומיינים של IPC:
דומיין IPC | תיאור |
---|---|
/dev/binder |
IPC בין תהליכי framework ואפליקציה עם ממשקי AIDL |
/dev/hwbinder |
IPC בין תהליכי framework/ספק עם ממשקי HIDL
IPC בין תהליכי ספק עם ממשקי HIDL |
/dev/vndbinder |
IPC בין תהליכי ספק/ספק באמצעות ממשקי AIDL |
כדי ש-/dev/vndbinder
יופיע, צריך לוודא שהגדרת הליבה (kernel)
הפריט CONFIG_ANDROID_BINDER_DEVICES
מוגדר
"binder,hwbinder,vndbinder"
(זו ברירת המחדל במכשירי Android
עצי ליבה נפוצים).
בדרך כלל, תהליכי ספק לא פותחים את מנהל ההתקן של הקישור ישירות, ובמקום זאת
קישור לספריית מרחב המשתמשים libbinder
, שפותחת את
התקן קלסר. מתבצעת הוספה של שיטה עבור ::android::ProcessState()
בוחר את מנהל ההתקן של הקישור עבור libbinder
. תהליכי הספק
קוראים לשיטה הזו לפני שקוראים ל-ProcessState,
IPCThreadState
, או לפני ביצוע של קריאות כלשהן ב-Binder. שפת תרגום
להשתמש, לבצע את הקריאה הבאה אחרי main()
של תהליך ספק
(לקוח ושרת):
ProcessState::initWithDriver("/dev/vndbinder");
vndservicemanager
בעבר, שירותי binder נרשמו אצל servicemanager
,
שבו אפשר לאחזר אותם באמצעות תהליכים אחרים. ב-Android 8,
האפליקציה servicemanager
נמצאת עכשיו בשימוש רק במסגרת ה-framework והאפליקציה
ותהליכי ספקים לא יכולים יותר לגשת אליו.
אבל עכשיו שירותי ספקים יכולים להשתמש ב-vndservicemanager
,
מופע של servicemanager
שמשתמש ב-/dev/vndbinder
במקום /dev/binder
, והוא מבוסס על אותם מקורות כמו
מסגרת servicemanager
. תהליכי הספק לא צריכים לבצע
שינויים לדיבור עם vndservicemanager
; כשנפתח תהליך של ספק
/dev/vndbinder
, חיפושי שירותים עוברים באופן אוטומטי אל
vndservicemanager
הקובץ הבינארי vndservicemanager
כלול בברירת המחדל של Android
makefiles.
מדיניות SELinux
תהליכים של ספקים שרוצים להשתמש בפונקציונליות של קלסר כדי לתקשר איתם זה לזה צריך את הדברים הבאים:
- גישה אל
/dev/vndbinder
. - צריך לקשר את
{transfer, call}
קטעי הוקים אל תוךvndservicemanager
. binder_call(A, B)
עבור כל דומיין ספק א' שרוצה להתקשר בדומיין הספק ב' בממשק של קישור הספק.- הרשאה ל-
{add, find}
שירותים ב-vndservicemanager
.
כדי לעמוד בדרישות 1 ו-2, צריך להשתמש בvndbinder_use()
מאקרו:
vndbinder_use(some_vendor_process_domain);
כדי לעמוד בדרישה 3, binder_call(A, B)
של הספק
תהליכים א' וב' שצריכים לדבר דרך קלסרים יכולים להישאר במקומם
צריך לשנות שם.
כדי לעמוד בדרישה 4, יש לבצע שינויים באופן שבו שמות השירותים, תוויות שירות וכללים מטופלים.
לפרטים על SELinux, ראו אבטחה משופרת 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;