הקשר הדינמי מתמודד עם שני אתגרים בתכנון של Treble VNDK:
- ספריות משותפות של SP-HAL והתלויות שלהן, כולל ספריות VNDK-SP, נטענות לתהליכי framework. צריכים להיות מנגנונים מסוימים למניעת התנגשויות בין סמלים.
-
dlopen()
ו-android_dlopen_ext()
יכולים להוסיף תלות בזמן ריצה שלא נראית בזמן הבנייה, וקשה לזהות אותה באמצעות ניתוח סטטי.
אפשר לפתור את שתי הבעיות האלה באמצעות המנגנון של מרחב השמות של הכלי לקישור תגים. המנגנון הזה מסופק על ידי המקשר הדינמי. הוא יכול לבודד את הספריות המשותפות במרחבי שמות שונים של מקשרים, כך שלא יהיה עימות בין ספריות עם אותו שם אבל עם סמלים שונים.
מצד שני, מנגנון מרחב השמות של ה-linker מספק גמישות, כך שאפשר לייצא ספריות משותפות מסוימות על ידי מרחב שמות של ה-linker ולהשתמש בהן על ידי מרחב שמות אחר של ה-linker. ספריות משותפות מיוצאות יכולות להפוך לממשקי תכנות אפליקציות (API) שגלויים לתוכניות אחרות, תוך הסתרת פרטי ההטמעה שלהן במרחבי השמות של המקשר.
לדוגמה, /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. יכול להיות שיש שני נכסים (או יותר)
עם אותו |
ההערה הזו מציינת שההגדרה שצוינה בקטע ההגדרה שצוינה בקטע |
מאפייני קשר
נכס | תיאור | דוגמה |
---|---|---|
additional. |
רשימה של מרחבי שמות נוספים (בנוסף למרחב השמות |
המשמעות היא שיש שלושה מרחבי שמות ( |
namespace. |
רשימה מופרדת בפסיקים של מרחבי שמות חלופיים. אם לא ניתן למצוא ספרייה משותפת במרחב השמות הנוכחי, ה-linker הדינמי מנסה לטעון את הספרייה המשותפת ממרחבי השמות של הגיבוי. המרחב שצוין בתחילת הרשימה הוא בעדיפות גבוהה יותר. |
אם ספרייה משותפת או קובץ הפעלה מבקשים ספרייה משותפת שלא ניתן לטעון למרחב השמות לאחר מכן, אם אי אפשר לטעון את הספרייה המשותפת ממרחב השמות לבסוף, אם כל הניסיונות נכשלים, המקשר הדינמי מחזיר שגיאה. |
namespace. |
רשימה של ספריות משותפות שמופרדות באמצעות נקודתיים, שאפשר לחפש במרחבי השמות אי אפשר להשתמש בנכס הזה עם |
המשמעות היא שקישור הגיבוי מקבל רק את |
namespace. |
ערך בוליאני שמציין אם אפשר לחפש את כל הספריות המשותפות במרחב השמות אי אפשר להשתמש בנכס הזה עם |
המשמעות היא שכל שמות הספריות יכולים לעבור דרך קישור הגיבוי
ממרחב השמות |
מאפיינים של מרחב שמות
נכס | תיאור | דוגמה |
---|---|---|
namespace. |
ערך בוליאני שמציין אם ה-linker הדינמי צריך לבדוק איפה נמצאת הספרייה המשותפת. אם אם |
ההגדרה הזו מציינת שרק הספריות המשותפות בנתיב |
namespace. |
רשימה של ספריות שמופרדות בנקודתיים, שבהן יתבצע חיפוש של ספריות משותפות. הספריות שצוינו ב- אם הערך של לדוגמה, אם |
המשמעות היא שהמקשר הדינמי מחפש את |
namespace. |
רשימה של ספריות שמופרדות באמצעות נקודתיים, לחיפוש ספריות משותפות כשמופעל AddressSanitizer (ASan). המערכת מתעלמת מהמדיניות |
המשמעות היא שכאשר ASan מופעל, המקשר הדינמי מחפש קודם ב- |
namespace. |
רשימה של ספריות (כולל ספריות משנה) שמופרדות באמצעות נקודתיים, שבהן המקשר הדינמי יכול לטעון את הספריות המשותפות (בנוסף ל- אפשר גם לטעון את הספריות המשותפות שנמצאות בספריות המשנה של
אם |
המשמעות היא שאפשר לטעון את הספריות המשותפות שמופיעות מתחת ל- לדוגמה, בלי |
namespace. |
רשימה של ספריות שמופרדות באמצעות נקודתיים, שבהן המקשר הדינמי יכול לטעון את הספריות המשותפות כש-ASan מופעל. המערכת מתעלמת מהמדיניות |
המשמעות היא שכאשר ASan מופעל, אפשר לטעון ספריות משותפות ב- |
namespace. |
ערך בוליאני שמציין אם התוכנית (מלבד אם אם הערך של |
המשמעות היא שהפונקציה |
יצירת מרחב שמות של Linker
ב-Android 11, הגדרת ה-linker נוצרת בזמן הריצה בתיקייה /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
.
- נוצרים מרחבי השמות
האיור הבא ממחיש את הקשר בין מרחבי השמות של הכלי לקישור.

איור 1. בידוד של מרחב שמות של מקשר (הגדרת VNDK).
בתמונה שלמעלה, LL-NDK ו-VNDK-SP מייצגים את הספריות המשותפות הבאות:
-
LL-NDK
libEGL.so
libGLESv1_CM.so
libGLESv2.so
libGLESv3.so
libandroid_net.so
libc.so
libdl.so
liblog.so
libm.so
libnativewindow.so
libneuralnetworks.so
libsync.so
libvndksupport.so
libvulkan.so
-
VNDK-SP
android.hardware.graphics.common@1.0.so
android.hardware.graphics.mapper@2.0.so
android.hardware.renderscript@1.0.so
android.hidl.memory@1.0.so
libRSCpuRef.so
libRSDriver.so
libRS_internal.so
libbase.so
libbcinfo.so
libc++.so
libcutils.so
libhardware.so
libhidlbase.so
libhidlmemory.so
libhidltransport.so
libhwbinder.so
libion.so
libutils.so
libz.so
פרטים נוספים זמינים ב/linkerconfig/ld.config.txt
מהמכשיר.
הגדרת VNDK Lite
החל מ-Android 8.0, ה-linker הדינמי מוגדר כך שהוא מבודד את הספריות המשותפות SP-HAL ו-VNDK-SP, כדי שהסמלים שלהן לא יתנגשו עם ספריות משותפות אחרות של framework. הקשר בין מרחבי השמות של הכלי לקישור מוצג בהמשך.

LL-NDK ו-VNDK-SP מייצגים את הספריות המשותפות הבאות:
-
LL-NDK
libEGL.so
libGLESv1_CM.so
libGLESv2.so
libc.so
libdl.so
liblog.so
libm.so
libnativewindow.so
-
libstdc++.so
(לא בהגדרה) libsync.so
libvndksupport.so
-
libz.so
(הועבר אל VNDK-SP בהגדרה)
-
VNDK-SP
android.hardware.graphics.common@1.0.so
android.hardware.graphics.mapper@2.0.so
android.hardware.renderscript@1.0.so
android.hidl.memory@1.0.so
libbase.so
libc++.so
libcutils.so
libhardware.so
libhidlbase.so
libhidlmemory.so
libhidltransport.so
libhwbinder.so
libion.so
libutils.so
בטבלה שלמטה מפורטת הגדרת מרחבי השמות לתהליכי המסגרת, והיא לקוחה מהקטע [system]
בהגדרת VNDK Lite.
מרחב שמות | נכס | ערך |
---|---|---|
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.so libft2.so
|
|
link.vndk.shared_libs |
VNDK-SP |
בטבלה שלמטה מוצגת הגדרת מרחבי השמות לתהליכי ספקים, והיא לקוחה מהקטע [vendor]
בהגדרת VNDK Lite.
מרחב שמות | נכס | ערך |
---|---|---|
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.in
ld.config.txt
למכשירים עם בידוד של מרחבי שמות של מקשרים בזמן ריצה ld.config.txt
ld.config.vndk_lite.txt
למכשירים עם בידוד של מרחב השמות של המקשר VNDK-SP ld.config.legacy.txt
ld.config.legacy.txt
למכשירים מדור קודם עם Android מגרסה 7.x ומטה - הסרה של
android.hardware.graphics.allocator@2.0.so
. - נוספו מחיצות
product
ו-odm
.