ตัวลิงก์แบบไดนามิกจะจัดการกับความท้าทาย 2 อย่างในการออกแบบ VNDK ของ Treble ดังนี้
- ระบบจะโหลดไลบรารีที่ใช้ร่วมกันของ SP-HAL และทรัพยากร Dependency ของไลบรารีเหล่านั้น ซึ่งรวมถึงไลบรารี VNDK-SP ลงในกระบวนการของเฟรมเวิร์ก ควรมีกลไกบางอย่างเพื่อป้องกันความขัดแย้งของสัญลักษณ์
dlopen()
และandroid_dlopen_ext()
อาจทำให้เกิดการอ้างอิงรันไทม์บางอย่างที่มองไม่เห็นในเวลาบิลด์ และอาจตรวจหาได้ยากโดยใช้การวิเคราะห์แบบคงที่
คุณสามารถแก้ไขความท้าทายทั้ง 2 อย่างนี้ได้ด้วยกลไกเนมสเปซของ Linker กลไกนี้ให้บริการโดยโปรแกรมลิงก์แบบไดนามิก ซึ่งจะแยกไลบรารีที่ใช้ร่วมกันในเนมสเปซของลิงเกอร์ที่แตกต่างกันได้ เพื่อให้ไลบรารีที่มีชื่อไลบรารีเดียวกันแต่มีสัญลักษณ์ต่างกันไม่ขัดแย้งกัน
ในทางกลับกัน กลไกเนมสเปซของลิงเกอร์มีความยืดหยุ่น เพื่อให้ลิงเกอร์เนมสเปซส่งออกไลบรารีที่ใช้ร่วมกันบางรายการและใช้โดย ลิงเกอร์เนมสเปซอื่นได้ คลังที่ใช้ร่วมกันซึ่งส่งออกเหล่านี้สามารถกลายเป็น อินเทอร์เฟซการเขียนโปรแกรมแอปพลิเคชันที่เปิดให้โปรแกรมอื่นๆ ใช้ได้ ขณะเดียวกันก็ ซ่อนรายละเอียดการใช้งานไว้ภายในเนมสเปซของลิงเกอร์
เช่น /system/lib[64]/libcutils.so
และ /system/lib[64]/vndk-sp-${VER}/libcutils.so
เป็นไลบรารีที่แชร์ 2 รายการ โดยไลบรารีทั้ง 2 นี้อาจมีสัญลักษณ์ที่แตกต่างกัน โดยจะโหลดลงในเนมสเปซของ Linker ที่แตกต่างกันเพื่อให้โมดูลเฟรมเวิร์กขึ้นอยู่กับ /system/lib[64]/libcutils.so
และไลบรารีที่ใช้ร่วมกันของ SP-HAL ขึ้นอยู่กับ /system/lib[64]/vndk-sp-${VER}/libcutils.so
ได้
ในทางกลับกัน /system/lib[64]/libc.so
เป็นตัวอย่างของ
ไลบรารีสาธารณะที่ส่งออกจากเนมสเปซของ Linker และนำเข้าไปยัง
เนมสเปซของ Linker หลายรายการ ระบบจะโหลดทรัพยากร Dependency ของ
/system/lib[64]/libc.so
เช่น libnetd_client.so
ลงในเนมสเปซที่ /system/lib[64]/libc.so
อยู่ เนมสเปซอื่นๆ จะไม่มีสิทธิ์เข้าถึงทรัพยากร Dependency เหล่านั้น กลไกนี้จะสรุปรายละเอียดการติดตั้งใช้งานในขณะที่แสดงอินเทอร์เฟซสาธารณะ
วิธีการทำงาน
โปรแกรมลิงก์แบบไดนามิกมีหน้าที่โหลดไลบรารีที่ใช้ร่วมกันซึ่งระบุไว้
ในรายการ DT_NEEDED
หรือไลบรารีที่ใช้ร่วมกันซึ่งระบุไว้โดย
อาร์กิวเมนต์ของ dlopen()
หรือ android_dlopen_ext()
ในทั้ง 2 กรณี ตัวลิงก์แบบไดนามิกจะค้นหาเนมสเปซของลิงก์เกอร์ที่ผู้เรียกอยู่ และพยายามโหลดการอ้างอิงลงในเนมสเปซของลิงก์เกอร์เดียวกัน หากตัวลิงก์แบบไดนามิกโหลดไลบรารีที่ใช้ร่วมกันลงในเนมสเปซของตัวลิงก์ที่ระบุไม่ได้
ก็จะขอไลบรารีที่ใช้ร่วมกันที่ส่งออกจากเนมสเปซของตัวลิงก์ที่ลิงก์
รูปแบบไฟล์การกำหนดค่า
รูปแบบไฟล์การกำหนดค่าจะอิงตามรูปแบบไฟล์ 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 หลายส่วน
- แต่ละส่วนจะมีเนมสเปซหลายรายการ (จุดยอดของกราฟ) และลิงก์สำรองหลายรายการ ระหว่างเนมสเปซ (ส่วนโค้งของกราฟ)
- แต่ละเนมสเปซมีการแยก การค้นหาเส้นทาง เส้นทางที่อนุญาต และการตั้งค่าระดับการมองเห็นของตัวเอง
ตารางด้านล่างจะอธิบายความหมายของพร็อพเพอร์ตี้แต่ละรายการโดยละเอียด
พร็อพเพอร์ตี้การแมปส่วนไดเรกทอรี
พร็อพเพอร์ตี้ | คำอธิบาย | ตัวอย่าง |
---|---|---|
|
เส้นทางไปยังไดเรกทอรีที่ แต่ละพร็อพเพอร์ตี้จะแมปไฟล์ที่เรียกใช้งานได้ภายใต้ไดเรกทอรีไปยังส่วนการกำหนดค่าเนมสเปซของ Linker
อาจมีพร็อพเพอร์ตี้ 2 รายการ (หรือมากกว่า) ที่มี |
ซึ่งหมายความว่าการกำหนดค่าที่ระบุไว้ในส่วน
การกำหนดค่าที่ระบุในส่วน |
พร็อพเพอร์ตี้ความสัมพันธ์
พร็อพเพอร์ตี้ | คำอธิบาย | ตัวอย่าง |
---|---|---|
additional. |
รายการเนมสเปซเพิ่มเติม (นอกเหนือจากเนมสเปซ |
ซึ่งระบุว่ามีการกำหนดค่าเนมสเปซ 3 รายการ ( |
namespace. |
รายการเนมสเปซสำรองที่คั่นด้วยคอมมา หากไม่พบไลบรารีที่ใช้ร่วมกันในเนมสเปซปัจจุบัน ตัวลิงก์แบบไดนามิก จะพยายามโหลดไลบรารีที่ใช้ร่วมกันจากเนมสเปซสำรอง เนมสเปซที่ระบุที่จุดเริ่มต้นของรายการจะมีลำดับความสำคัญสูงกว่า |
หากไลบรารีที่ใช้ร่วมกันหรือไฟล์ที่เรียกใช้งานได้ขอไลบรารีที่ใช้ร่วมกันซึ่ง
โหลดลงในเนมสเปซ จากนั้นหากโหลดไลบรารีที่ใช้ร่วมกันจากเนมสเปซ สุดท้ายนี้ หากพยายามดำเนินการทุกอย่างแล้วแต่ไม่สำเร็จ ตัวลิงก์แบบไดนามิกจะแสดงข้อผิดพลาด |
namespace. |
รายการไลบรารีที่ใช้ร่วมกันซึ่งคั่นด้วยเครื่องหมายโคลอนซึ่งสามารถค้นหาได้ใน
ใช้พร็อพเพอร์ตี้นี้กับ
|
ซึ่งหมายความว่าลิงก์สำรองจะยอมรับเฉพาะ |
namespace. |
ค่าบูลีนที่ระบุว่าค้นหาไลบรารีที่แชร์ทั้งหมดได้ในเนมสเปซ ใช้พร็อพเพอร์ตี้นี้กับ
|
ซึ่งหมายความว่าชื่อไลบรารีทั้งหมดสามารถเดินผ่านลิงก์สำรอง
จากเนมสเปซ |
พร็อพเพอร์ตี้ของเนมสเปซ
พร็อพเพอร์ตี้ | คำอธิบาย | ตัวอย่าง |
---|---|---|
namespace. |
ค่าบูลีนที่ระบุว่าตัวลิงก์แบบไดนามิกควรตรวจสอบตำแหน่งของไลบรารีที่ใช้ร่วมกันหรือไม่ หาก หาก |
ซึ่งหมายความว่าเฉพาะไลบรารีที่แชร์ใน
|
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 ที่แสดงการเปลี่ยนแปลงเหล่านี้ ดูรายละเอียดเพิ่มเติมเกี่ยวกับการสร้างการกำหนดค่า Linker
ได้ที่
${android-src}/system/linkerconfig
การแยกเนมสเปซของ Linker
การกำหนดค่ามี 3 ประเภท ระบบจะสร้างการกำหนดค่าที่เกี่ยวข้องในเวลาบูต โดยขึ้นอยู่กับค่าของ
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 จะแยกการอ้างอิงไลบรารีที่ใช้ร่วมกัน ระหว่างพาร์ติชันระบบและพาร์ติชันของผู้ให้บริการ เมื่อเทียบกับ การกำหนดค่าที่กล่าวถึงในส่วนย่อยก่อนหน้า ความแตกต่าง มีดังนี้
-
กระบวนการของเฟรมเวิร์ก
default
,vndk
,sphal
และrs
จะได้รับการสร้างขึ้น- เนมสเปซทั้งหมดจะแยกออกจากกัน
- ระบบจะโหลดไลบรารีที่ใช้ร่วมกันของระบบลงในเนมสเปซ
default
- ระบบจะโหลด SP-HAL ลงในเนมสเปซ
sphal
- ไลบรารีที่ใช้ร่วมกันของ VNDK-SP ที่โหลดลงในเนมสเปซ
vndk
-
กระบวนการของผู้ให้บริการ
- ระบบจะสร้างเนมสเปซ
default
,vndk
และsystem
default
เนมสเปซจะแยกกัน- ระบบจะโหลดไลบรารีที่ใช้ร่วมกันของผู้ให้บริการลงในเนมสเปซ
default
- ระบบจะโหลดไลบรารีที่ใช้ร่วมกัน VNDK และ VNDK-SP ลงในเนมสเปซ
vndk
- ระบบจะโหลด LL-NDK และการขึ้นต่อกันลงในเนมสเปซ
system
- ระบบจะสร้างเนมสเปซ
ความสัมพันธ์ระหว่างเนมสเปซของ Linker แสดงไว้ด้านล่าง

ในรูปภาพด้านบน 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 เป็นต้นมา ระบบจะกำหนดค่าลิงก์เกอร์แบบไดนามิกเพื่อแยกไลบรารีที่ใช้ร่วมกันของ 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 มีการเพิ่ม
vndk
เนมสเปซของ Linker ลงในกระบวนการของผู้ให้บริการ และแยกไลบรารีที่ใช้ร่วมกันของ VNDK ออกจากเนมสเปซของ Linker เริ่มต้น - แทนที่
PRODUCT_FULL_TREBLE
ด้วยPRODUCT_TREBLE_LINKER_NAMESPACES
ที่เฉพาะเจาะจงมากขึ้น - Android 9 เปลี่ยนชื่อไฟล์การกำหนดค่าลิงก์แบบไดนามิกต่อไปนี้
Android 8.x Android 9 คำอธิบาย ld.config.txt.in
ld.config.txt
สำหรับอุปกรณ์ที่มีการแยกเนมสเปซของ Linker รันไทม์ 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