המקשר הדינמי מטפל בשני אתגרים בתכנון של Treble VNDK:
- ספריות משותפות של SP-HAL ויחסי התלות שלהן, כולל ספריות VNDK-SP, נטענות בתהליכי המסגרת. צריכים להיות מנגנונים מסוימים למניעת התנגשויות בין סמלים.
dlopen()
ו-android_dlopen_ext()
יכולים להוסיף יחסי תלות מסוימים בסביבת זמן הריצה שלא גלויים בזמן ה-build, וקשה לזהות אותם באמצעות ניתוח סטטי.
אפשר לפתור את שתי הבעיות האלה באמצעות המנגנון של מרחב השמות של הקישור. המנגנון הזה מסופק על ידי הקישור הדינמי. הוא יכול לבודד את הספריות המשותפות במרחבי שמות שונים של קישורים, כדי שלא יהיו התנגשויות בין ספריות עם אותו שם ספרייה אבל עם סמלים שונים.
לעומת זאת, מנגנון מרחב השמות של ה-linker מספק את הגמישות שמאפשרת לייצא חלק מספריות משותפות באמצעות מרחב שמות של linker ולהשתמש בהן באמצעות מרחב שמות אחר של linker. ספריות משותפות שיוצאו יכולות להפוך לממשקי תכנות ל-Application (API) שגלויים לתוכנות אחרות, תוך הסתרת פרטי ההטמעה שלהן במרחבי השמות של ה-Linker.
לדוגמה, /system/lib[64]/libcutils.so
ו-/system/lib[64]/vndk-sp-${VER}/libcutils.so
הן שתי ספריות משותפות. לכל אחת משתי הספריות האלה יכולים להיות סמלים שונים. הם נטענים במרחבי שמות שונים של קישורים, כדי שממשקי ה-framework יוכלו להסתמך על /system/lib[64]/libcutils.so
וספריות משותפות של SP-HAL יוכלו להסתמך על /system/lib[64]/vndk-sp-${VER}/libcutils.so
.
לעומת זאת, /system/lib[64]/libc.so
היא דוגמה לספרייה ציבורית שמיוצאת על ידי מרחב שמות של קישור ומיובאת למרחבי שמות רבים של קישורים. יחסי התלות של /system/lib[64]/libc.so
, כמו libnetd_client.so
, נטענים במרחב השמות שבו /system/lib[64]/libc.so
נמצא. למרחבי שמות אחרים לא תהיה גישה ליחסי התלות האלה. המנגנון הזה מכיל את פרטי ההטמעה ומספק את הממשקים הציבוריים.
איך זה עובד
מחבר הקישורים הדינמי אחראי לטעינת הספריות המשותפות שצוינו ברשאות DT_NEEDED
או בספריות המשותפות שצוינו בארגומנט של dlopen()
או android_dlopen_ext()
. בשני המקרים, מחבר הקבצים הדינמי מוצא את מרחב השמות של מחבר הקבצים שבו נמצא מבצע הקריאה החוזרת ומנסה לטעון את יחסי התלות לאותו מרחב שמות של מחבר הקבצים. אם מקשר הדינמי לא יכול לטעון את הספרייה המשותפת למרחב השמות של המקשר שצוין, הוא מבקש ממרחב השמות המקושר של המקשר למצוא ספריות משותפות שיוצאו.
הפורמט של קובץ התצורה
פורמט קובץ התצורה מבוסס על פורמט קובץ ה-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}
קובץ התצורה כולל:
- כמה מאפייני מיפוי של קטעי ספריות בתחילת הקובץ, כדי שהמקשר הדינמי יוכל לבחור את הקטע היעיל.
-
כמה קטעי הגדרה של מרחבי שמות של קישורים:
- כל קטע מכיל כמה מרחבי שמות (קודקודים בתרשים) וכמה קישורי חלופיים בין מרחבי שמות (קשתות בתרשים).
- לכל מרחב שמות יש בידוד, נתיבי חיפוש, נתיבים מותרים והגדרות חשיפה משלו.
בטבלאות הבאות מוסבר בפירוט מה המשמעות של כל מאפיין.
מאפיין של מיפוי של קטע בספרייה
נכס | תיאור | דוגמה |
---|---|---|
|
נתיב לספרייה שאליה חל הקטע כל מאפיין ממפה את קובצי ההפעלה שבספרייה לקטע תצורה של מרחבי שמות של קישורים. יכול להיות שיהיו שני נכסים (או יותר) עם אותו |
המשמעות היא שההגדרה שצוינה בקטע ההגדרה שצוינה בקטע |
מאפייני הקשר
נכס | תיאור | דוגמה |
---|---|---|
additional. |
רשימה מופרדת בפסיקים של מרחבי שמות נוספים (בנוסף למרחב השמות |
המשמעות היא שיש שלושה מרחבי שמות ( |
namespace. |
רשימה מופרדת בפסיקים של מרחבי שמות חלופיים. אם לא ניתן למצוא ספרייה משותפת במרחב השמות הנוכחי, הקישור הדינמי מנסה לטעון את הספרייה המשותפת ממרחב השמות החלופי. למרחב השמות שצוין בתחילת הרשימה יש עדיפות גבוהה יותר. |
אם ספרייה משותפת או קובץ הפעלה מבקשים ספרייה משותפת שלא ניתן לטעון למרחב השמות אם גם לא ניתן לטעון את הספרייה המשותפת ממרחב השמות לבסוף, אם כל הניסיונות נכשלו, מחבר הקבצים הדינמי מחזיר שגיאה. |
namespace. |
רשימה של ספריות משותפות מופרדות בפסיקים, שאפשר לחפש אותן במרחבי השמות אי אפשר להשתמש בנכס הזה עם |
המשמעות היא שאפשר להזין בקישור החלופי רק את הערכים |
namespace. |
ערך בוליאני שמציין אם אפשר לחפש את כל הספריות המשותפות במרחב השמות אי אפשר להשתמש בנכס הזה עם |
המשמעות היא שכל שמות הספריות יכולים לעבור דרך הקישור החלופי ממרחב השמות |
מאפייני מרחב שמות
נכס | תיאור | דוגמה |
---|---|---|
namespace. |
ערך בוליאני שמציין אם מחבר הקבצים הדינמי צריך לבדוק איפה נמצאת הספרייה המשותפת. אם הערך של אם הערך של |
המשמעות היא שרק הספריות המשותפות ב- |
namespace. |
רשימה של ספריות מופרדות בפסיקים, שבהן יתבצע חיפוש של ספריות משותפות. הספריות שצוינו ב- כשהערך של לדוגמה, אם הערך של |
המשמעות היא שהמקשר הדינמי מחפש ספריות משותפות ב- |
namespace. |
רשימה של ספריות מופרדות בפסיקים, שבהן מתבצע חיפוש של ספריות משותפות כשAddressSanitizer (ASan) מופעל. המערכת מתעלמת מ- |
המשמעות היא שכאשר ASan מופעל, ה-linker הדינמי מחפש קודם את |
namespace. |
רשימה של ספריות (כולל ספריות משנה) מופרדות בפסיקים, שבהן הקישור הדינמי יכול לטעון את הספריות המשותפות (בנוסף ל- אפשר גם לטעון את הספריות המשותפות שנמצאות בתיקיות המשנה של אם |
המשמעות היא שאפשר לטעון את הספריות המשותפות שמתחת למרחב השמות לדוגמה, בלי |
namespace. |
רשימה של ספריות מופרדות בפסיקים שבהן המקשר הדינמי יכול לטעון את הספריות המשותפות כש-ASan מופעל. המערכת מתעלמת מ- |
המשמעות היא שכאשר ASan מופעל, אפשר לטעון ספריות משותפות ב- |
namespace. |
ערך בוליאני שמציין אם התוכנית (לא אם אם הערך של |
המשמעות היא ש- |
יצירת מרחב שמות של קישורים
ב-Android 11, הגדרות הקישור נוצרות במהלך זמן הריצה בקטע /linkerconfig
במקום להשתמש בקובצי טקסט רגילים בקטע ${android-src}/system/core/rootdir/etc
. ההגדרות נוצרות בזמן האתחול על סמך סביבת זמן הריצה, שכוללת את הפריטים הבאים:
- אם המכשיר תומך ב-VNDK
- גרסת היעד של VNDK במחיצה של הספק
- גרסת VNDK של חלוקת המוצרים
- מודולים מותקנים של APEX
תצורת ה-Linker נוצרת על ידי פתרון יחסי התלות בין מרחבי השמות של ה-Linker. לדוגמה, אם יש עדכונים במודולים של APEX שכוללים עדכוני יחסי תלות, הגדרות הקישור נוצרות בהתאם לשינויים האלה. פרטים נוספים על יצירת הגדרות של קישור זמינים במאמר ${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, זהו קובץ התצורה של קישור דינמי כש-PRODUCT_TREBLE_LINKER_NAMESPACES
הוא true
.
הגדרת VNDK מבודדת גם את הספריות המשותפות של SP-HAL ו-VNDK-SP. בנוסף, ההגדרה הזו מספקת את הבידוד המלא של קישור הדינמי. כך מוודאים שהמודולים במחיצה של המערכת לא יהיו תלויים בספריות המשותפות במחיצות של הספקים, ולהפך.
ב-Android מגרסה 8.1 ואילך, הגדרת VNDK היא הגדרת ברירת המחדל, ומומלץ מאוד להפעיל בידוד מלא של קישור דינמי על ידי הגדרת 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. בידוד של מרחב השמות של ה-Linker (הגדרת 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
החל מגרסה 8.0 של Android, הקישור הדינמי מוגדר לבודד את הספריות המשותפות של SP-HAL ו-VNDK-SP, כך שהסמלים שלהן לא ייכנסו לעימות עם ספריות משותפות אחרות של המסגרת. הקשר בין מרחבי השמות של ה-linker מוצג בהמשך.

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, מרחב השמות של ה-linker
vndk
מתווסף לתהליכים של הספק, וספריות VNDK המשותפות מבודדות ממרחב השמות של ה-linker שמוגדר כברירת מחדל. - מחליפים את
PRODUCT_FULL_TREBLE
ב-PRODUCT_TREBLE_LINKER_NAMESPACES
ספציפי יותר. - ב-Android 9 השתנו השמות של קובצי התצורה הבאים של קישור דינמי.
Android 8.x Android 9 תיאור ld.config.txt.in
ld.config.txt
במכשירים עם בידוד של מרחב השמות של מקשר בסביבת זמן ריצה ld.config.txt
ld.config.vndk_lite.txt
במכשירים עם בידוד של מרחב השמות של ה-linker ב-VNDK-SP ld.config.legacy.txt
ld.config.legacy.txt
במכשירים ישנים עם Android מגרסה 7.x ומטה - מסירים את
android.hardware.graphics.allocator@2.0.so
. - נוספות המחיצות
product
ו-odm
.