הקשר הדינמי מתמודד עם שני אתגרים בתכנון של Treble VNDK:
- ספריות משותפות של SP-HAL והתלויות שלהן, כולל ספריות VNDK-SP, נטענות לתהליכי framework. צריכים להיות מנגנונים למניעת התנגשויות בין סמלים.
-
dlopen()ו-android_dlopen_ext()יכולים להוסיף תלות בזמן ריצה שלא נראית בזמן הבנייה, וקשה לזהות אותה באמצעות ניתוח סטטי.
אפשר לפתור את שתי הבעיות האלה באמצעות המנגנון של מרחב השמות של הכלי Linker. המנגנון הזה מסופק על ידי המקשר הדינמי. הוא יכול לבודד את הספריות המשותפות במרחבי שמות שונים של מקשרים, כך שלא יהיה עימות בין ספריות עם אותו שם אבל עם סמלים שונים.
מצד שני, מנגנון מרחב השמות של ה-linker מספק גמישות, כך שאפשר לייצא ספריות משותפות מסוימות על ידי מרחב שמות של ה-linker ולהשתמש בהן על ידי מרחב שמות אחר של ה-linker. ספריות משותפות מיוצאות יכולות להפוך לממשקי תכנות אפליקציות שגלויים לתוכניות אחרות, תוך הסתרת פרטי ההטמעה שלהן במרחבי השמות של המקשר.
לדוגמה, /system/lib[64]/libcutils.so ו-/system/lib[64]/vndk-sp-${VER}/libcutils.so הן שתי ספריות משותפות. יכולים להיות סמלים שונים בשתי הספריות האלה. הן נטענות למרחבי שמות שונים של מקשרים, כך שמודולים של מסגרות יכולים להסתמך על /system/lib[64]/libcutils.so וספריות משותפות של SP-HAL יכולות להסתמך על /system/lib[64]/vndk-sp-${VER}/libcutils.so.
לעומת זאת, /system/lib[64]/libc.so היא דוגמה לספרייה ציבורית שמיוצאת על ידי מרחב שמות של linker ומיובאת למרחבי שמות רבים של linker. הפניות הקשורות של /system/lib[64]/libc.so, כמו libnetd_client.so, נטענות למרחב השמות שבו נמצא /system/lib[64]/libc.so. למרחבי שמות אחרים לא תהיה גישה לתלות האלה. המנגנון הזה כולל את פרטי ההטמעה ומספק את הממשקים הציבוריים.
איך זה עובד
הקשר הדינמי אחראי לטעינת הספריות המשותפות שצוינו ברשומות DT_NEEDED או הספריות המשותפות שצוינו בארגומנט של dlopen() או android_dlopen_ext(). בשני המקרים, ה-linker הדינמי מוצא את מרחב השמות של ה-linker שבו נמצא המתקשר ומנסה לטעון את התלות באותו מרחב שמות של ה-linker. אם ה-linker הדינמי לא יכול לטעון את הספרייה המשותפת במרחב השמות של ה-linker שצוין, הוא מבקש מספריות משותפות מיוצאות ממרחב השמות המקושר של ה-linker.
פורמט קובץ התצורה
פורמט קובץ ההגדרות מבוסס על פורמט קובץ ה-INI. קובץ תצורה טיפוסי נראה כך:
dir.system = /system/bin dir.system = /system/xbin dir.vendor = /vendor/bin [system] additional.namespaces = sphal,vndk namespace.default.isolated = true namespace.default.search.paths = /system/${LIB} namespace.default.permitted.paths = /system/${LIB}/hw namespace.default.asan.search.paths = /data/asan/system/${LIB}:/system/${LIB} namespace.default.asan.permitted.paths = /data/asan/system/${LIB}/hw:/system/${LIB}/hw namespace.sphal.isolated = true namespace.sphal.visible = true namespace.sphal.search.paths = /odm/${LIB}:/vendor/${LIB} namespace.sphal.permitted.paths = /odm/${LIB}:/vendor/${LIB} namespace.sphal.asan.search.paths = /data/asan/odm/${LIB}:/odm/${LIB} namespace.sphal.asan.search.paths += /data/asan/vendor/${LIB}:/vendor/${LIB} namespace.sphal.asan.permitted.paths = /data/asan/odm/${LIB}:/odm/${LIB} namespace.sphal.asan.permitted.paths += /data/asan/vendor/${LIB}:/vendor/${LIB} namespace.sphal.links = default,vndk namespace.sphal.link.default.shared_libs = libc.so:libm.so namespace.sphal.link.vndk.shared_libs = libbase.so:libcutils.so namespace.vndk.isolated = true namespace.vndk.search.paths = /system/${LIB}/vndk-sp-29 namespace.vndk.permitted.paths = /system/${LIB}/vndk-sp-29 namespace.vndk.links = default namespace.vndk.link.default.shared_libs = libc.so:libm.so [vendor] namespace.default.isolated = false namespace.default.search.paths = /vendor/${LIB}:/system/${LIB}
קובץ התצורה כולל:
- כמה מאפיינים של מיפוי קטעים בספרייה בתחילת הקובץ, כדי שהמקשר הדינמי יוכל לבחור את הקטע הרלוונטי.
-
כמה קטעי הגדרה של מרחבי שמות של כלי Linker:
- כל קטע מכיל כמה מרחבי שמות (קודקודי גרף) וכמה קישורי חזרה בין מרחבי שמות (קשתות גרף).
- לכל מרחב שמות יש בידוד משלו, נתיבי חיפוש, נתיבים מותרים והגדרות חשיפה.
בטבלאות הבאות מפורטת המשמעות של כל מאפיין.
מאפיין מיפוי של קטע בספרייה
| מאפיין (property) | תיאור | דוגמה |
|---|---|---|
|
נתיב לספרייה שהקטע כל מאפיין ממפה את קובצי ההפעלה בספרייה לקטע ההגדרות של מרחבי השמות של ה-linker. יכול להיות שיש שני נכסים (או יותר)
עם אותו |
ההערה הזו מציינת שההגדרה שצוינה בקטע ההגדרה שצוינה בקטע |
מאפייני קשר
| מאפיין (property) | תיאור | דוגמה |
|---|---|---|
additional. |
רשימה מופרדת בפסיקים של מרחבי שמות נוספים (בנוסף למרחב השמות |
המשמעות היא שיש שלושה מרחבי שמות ( |
namespace. |
רשימה מופרדת בפסיקים של מרחבי שמות חלופיים. אם לא ניתן למצוא ספרייה משותפת במרחב השמות הנוכחי, המקשר הדינמי מנסה לטעון את הספרייה המשותפת ממרחבי השמות של הגיבוי. מרחב השמות שצוין בתחילת הרשימה הוא בעדיפות גבוהה יותר. |
אם ספרייה משותפת או קובץ הפעלה מבקשים ספרייה משותפת שלא ניתן לטעון במרחב השמות לאחר מכן, אם אי אפשר לטעון את הספרייה המשותפת ממרחב השמות לבסוף, אם כל הניסיונות נכשלים, המקשר הדינמי מחזיר שגיאה. |
namespace. |
רשימה של ספריות משותפות שמופרדות באמצעות נקודתיים, שאפשר לחפש במרחבי השמות אי אפשר להשתמש בנכס הזה עם |
הערך הזה מציין שקישור הגיבוי מקבל רק את הערכים |
namespace. |
ערך בוליאני שמציין אם אפשר לחפש את כל הספריות המשותפות במרחב השמות אי אפשר להשתמש בנכס הזה עם |
המשמעות היא שכל שמות הספריות יכולים לעבור דרך קישור הגיבוי
ממרחב השמות |
מאפיינים של מרחב שמות
| מאפיין (property) | תיאור | דוגמה |
|---|---|---|
namespace. |
ערך בוליאני שמציין אם ה-linker הדינמי צריך לבדוק איפה נמצאת הספרייה המשותפת. אם אם |
ההגדרה הזו מציינת שרק הספריות המשותפות ב- |
namespace. |
רשימה של ספריות שמופרדות בנקודתיים, שבהן יתבצע חיפוש של ספריות משותפות. הספריות שצוינו ב- אם לדוגמה, אם |
ההגדרה הזו מציינת שהמקשר הדינמי מחפש את הספריות המשותפות בנתיב |
namespace. |
רשימה של ספריות שמופרדות באמצעות נקודתיים, שבהן יתבצע חיפוש של ספריות משותפות כשמופעל AddressSanitizer (ASan). המערכת מתעלמת מ- |
המשמעות היא שכאשר ASan מופעל, המקשר הדינמי מחפש קודם ב- |
namespace. |
רשימה של ספריות (כולל ספריות משנה) שמופרדות באמצעות נקודתיים, שבהן המקשר הדינמי יכול לטעון את הספריות המשותפות (בנוסף ל- אפשר גם לטעון ספריות משותפות שנמצאות בספריות המשנה של
אם |
ההגדרה הזו מציינת שאפשר לטעון את הספריות המשותפות שמופיעות מתחת ל- לדוגמה, בלי |
namespace. |
רשימה של ספריות שמופרדות באמצעות נקודתיים, שבהן המקשר הדינמי יכול לטעון את הספריות המשותפות כש-ASan מופעל. המערכת מתעלמת מהמדיניות |
ההגדרה הזו מציינת שכאשר ASan מופעל, אפשר לטעון ספריות משותפות ב- |
namespace. |
ערך בוליאני שמציין אם התוכנית (מלבד אם אם הערך של |
המשמעות היא ש- |
יצירת מרחב שמות של Linker
ב-Android 11, הגדרת המקשר נוצרת בזמן הריצה בתיקייה /linkerconfig במקום להשתמש בקובצי טקסט פשוט בתיקייה ${android-src}/system/core/rootdir/etc. ההגדרה נוצרת בזמן האתחול על סמך סביבת זמן הריצה, שכוללת את הפריטים הבאים:
- אם המכשיר תומך ב-VNDK
- גרסת היעד של VNDK במחיצת הספק
- גרסת ה-VNDK של חלוקת המוצרים
- מודולים מותקנים של APEX
הגדרות ה-Linker נוצרות על ידי פתרון תלויות בין מרחבי שמות של ה-Linker. לדוגמה, אם יש עדכונים במודולי APEX שכוללים עדכוני תלות, נוצרת הגדרת linker שמשקפת את השינויים האלה. פרטים נוספים על יצירת הגדרות של כלי לקישור המרות זמינים במאמר ${android-src}/system/linkerconfig.
בידוד מרחב השמות של Linker
יש שלושה סוגי הגדרות. בהתאם לערך של PRODUCT_TREBLE_LINKER_NAMESPACES ושל BOARD_VNDK_VERSION ב-BoardConfig.mk, התצורה המתאימה נוצרת בזמן האתחול.
PRODUCT_TREBLE_LINKER_NAMESPACES |
BOARD_VNDK_VERSION |
ההגדרות שנבחרו | דרישה ל-VTS |
|---|---|---|---|
true |
current |
VNDK |
חובה למכשירים שהושקו עם Android מגרסה 9 ואילך |
| ריק | VNDK Lite |
חובה למכשירים שהושקו עם Android 8.x | |
false |
ריק | Legacy |
במכשירים שאינם Treble |
ההגדרה של VNDK Lite מבודדת את הספריות המשותפות SP-HAL ו-VNDK-SP. ב-Android 8.0, זה חייב להיות קובץ התצורה של ה-linker הדינמי כש-PRODUCT_TREBLE_LINKER_NAMESPACES הוא true.
ההגדרה של VNDK מבודדת גם את הספריות המשותפות של SP-HAL ו-VNDK-SP. בנוסף, ההגדרה הזו מספקת בידוד מלא של ה-linker הדינמי. כך מוודאים שהמודולים במחיצת המערכת לא יהיו תלויים בספריות המשותפות במחיצות הספק, ולהפך.
ב-Android מגרסה 8.1 ואילך, הגדרת VNDK היא הגדרת ברירת המחדל, ומומלץ מאוד להפעיל בידוד מלא של ה-linker הדינמי על ידי הגדרת BOARD_VNDK_VERSION ל-current.
הגדרת VNDK
ההגדרה של VNDK מבודדת את התלויות של הספרייה המשותפת בין מחיצת המערכת לבין מחיצות הספק. בהשוואה להגדרות שצוינו בסעיף המשנה הקודם, ההבדלים הם כדלקמן:
-
תהליכי Framework
- נוצרים מרחבי השמות
default,vndk,sphalו-rs. - כל מרחבי השמות מבודדים.
- ספריות משותפות של המערכת נטענות במרחב השמות
default. - קובצי SP-HAL נטענים למרחב השמות
sphal. - ספריות משותפות של VNDK-SP נטענות למרחב השמות
vndk.
- נוצרים מרחבי השמות
-
תהליכי ספק
- נוצרים מרחבי השמות
default,vndkו-system. - מרחב השמות
defaultמבודד. - ספריות משותפות של ספקים נטענות למרחב השמות
default. - ספריות משותפות של VNDK ו-VNDK-SP נטענות למרחב השמות
vndk. - LL-NDK והתלויות שלו נטענים למרחב השמות
system.
- נוצרים מרחבי השמות
האיור הבא מציג את הקשר בין מרחבי השמות של ה-Linker.
איור 1. בידוד של מרחב שמות של מקשר (הגדרת VNDK).
בתמונה שלמעלה, LL-NDK ו-VNDK-SP מייצגים את הספריות המשותפות הבאות:
-
LL-NDK
libEGL.solibGLESv1_CM.solibGLESv2.solibGLESv3.solibandroid_net.solibc.solibdl.soliblog.solibm.solibnativewindow.solibneuralnetworks.solibsync.solibvndksupport.solibvulkan.so
-
VNDK-SP
android.hardware.graphics.common@1.0.soandroid.hardware.graphics.mapper@2.0.soandroid.hardware.renderscript@1.0.soandroid.hidl.memory@1.0.solibRSCpuRef.solibRSDriver.solibRS_internal.solibbase.solibbcinfo.solibc++.solibcutils.solibhardware.solibhidlbase.solibhidlmemory.solibhidltransport.solibhwbinder.solibion.solibutils.solibz.so
פרטים נוספים זמינים ב/linkerconfig/ld.config.txt מהמכשיר.
הגדרת VNDK Lite
החל מ-Android 8.0, ה-linker הדינמי מוגדר כך שהוא מבודד את ספריות ה-SP-HAL ואת ספריות ה-VNDK-SP המשותפות, כדי שהסמלים שלהן לא יתנגשו עם ספריות משותפות אחרות של framework. הקשר בין מרחבי השמות של ה-linker מוצג בהמשך.
LL-NDK ו-VNDK-SP מייצגים את הספריות המשותפות הבאות:
-
LL-NDK
libEGL.solibGLESv1_CM.solibGLESv2.solibc.solibdl.soliblog.solibm.solibnativewindow.so-
libstdc++.so(לא בהגדרה) libsync.solibvndksupport.so-
libz.so(הועבר אל VNDK-SP בהגדרה)
-
VNDK-SP
android.hardware.graphics.common@1.0.soandroid.hardware.graphics.mapper@2.0.soandroid.hardware.renderscript@1.0.soandroid.hidl.memory@1.0.solibbase.solibc++.solibcutils.solibhardware.solibhidlbase.solibhidlmemory.solibhidltransport.solibhwbinder.solibion.solibutils.so
בטבלה שלמטה מפורטת הגדרת מרחבי השמות לתהליכי framework, והיא לקוחה מהקטע [system] בהגדרת VNDK Lite.
| מרחב שמות | מאפיין (property) | ערך |
|---|---|---|
default |
search.paths |
/system/${LIB}/odm/${LIB}/vendor/${LIB}/product/${LIB}
|
isolated |
false |
|
sphal |
search.paths |
/odm/${LIB}/vendor/${LIB}
|
permitted.paths |
/odm/${LIB}/vendor/${LIB}
|
|
isolated |
true |
|
visible |
true |
|
links |
default,vndk,rs |
|
link.default.shared_libs |
LL-NDK | |
link.vndk.shared_libs |
VNDK-SP | |
link.rs.shared_libs |
libRS_internal.so |
|
vndk (ל-VNDK-SP) |
search.paths |
/odm/${LIB}/vndk-sp/vendor/${LIB}/vndk-sp/system/${LIB}/vndk-sp-${VER}
|
permitted.paths |
/odm/${LIB}/hw/odm/${LIB}/egl/vendor/${LIB}/hw/vendor/${LIB}/egl/system/${LIB}/vndk-sp-${VER}/hw |
|
isolated |
true |
|
visible |
true |
|
links |
default |
|
link.default.shared_libs |
LL-NDK | |
rs (ל-RenderScript) |
search.paths |
/odm/${LIB}/vndk-sp/vendor/${LIB}/vndk-sp/system/${LIB}/vndk-sp-${VER}/odm/${LIB}/vendor/${LIB}
|
permitted.paths |
/odm/${LIB}/vendor/${LIB}/data (לליבת RS מהודרת)
|
|
isolated |
true |
|
visible |
true |
|
links |
default,vndk |
|
link.default.shared_libs |
LL-NDKlibmediandk.solibft2.so
|
|
link.vndk.shared_libs |
VNDK-SP |
בטבלה שלמטה מוצגת הגדרת מרחבי השמות לתהליכי ספקים, והיא לקוחה מהקטע [vendor] בהגדרת VNDK Lite.
| מרחב שמות | מאפיין (property) | ערך |
|---|---|---|
default |
search.paths |
/odm/${LIB}/odm/${LIB}/vndk/odm/${LIB}/vndk-sp/vendor/${LIB}/vendor/${LIB}/vndk/vendor/${LIB}/vndk-sp/system/${LIB}/vndk-${VER}/system/${LIB}/vndk-sp-${VER}/system/${LIB} (הוצאה משימוש)/product/${LIB} (הוצאה משימוש)
|
isolated |
false |
פרטים נוספים זמינים ב/linkerconfig/ld.config.txt מהמכשיר.
היסטוריית המסמך
שינויים ב-Android 11
- ב-Android 11, הקבצים הסטטיים
ld.config.*.txtמוסרים מבסיס הקוד, ו-LinkerConfig יוצר אותם בזמן הריצה במקום זאת.
שינויים ב-Android 9
- ב-Android 9, מרחב השמות של המקשר
vndkנוסף לתהליכי הספק וספריות משותפות של VNDK מבודדות ממרחב השמות של המקשר שמוגדר כברירת מחדל. - מחליפים את
PRODUCT_FULL_TREBLEב-PRODUCT_TREBLE_LINKER_NAMESPACESספציפי יותר. - ב-Android 9, השמות של קובצי ההגדרה הבאים של ה-linker הדינמי השתנו.
Android 8.x Android 9 תיאור ld.config.txt.inld.config.txtלמכשירים עם בידוד של מרחבי שמות של מקשרים בזמן ריצה ld.config.txtld.config.vndk_lite.txtלמכשירים עם בידוד של מרחב שמות של מקשר VNDK-SP ld.config.legacy.txtld.config.legacy.txtלמכשירים מדור קודם עם Android מגרסה 7.x ומטה - הסרה של
android.hardware.graphics.allocator@2.0.so. - נוספו מחיצות
productו-odm.