ตัวลิงก์แบบไดนามิกช่วยแก้ปัญหา 2 ข้อในการออกแบบ Treble VNDK ดังนี้
- ระบบโหลดไลบรารีที่ใช้ร่วมกัน SP-HAL และทรัพยากร Dependency ของไลบรารีดังกล่าว ซึ่งรวมถึงไลบรารี VNDK-SP ไว้ในกระบวนการของเฟรมเวิร์ก ควรมีกลไกบางอย่างเพื่อป้องกันไม่ให้สัญลักษณ์ทับซ้อนกัน
dlopen()
และandroid_dlopen_ext()
อาจทำให้เกิดข้อกําหนดในรันไทม์บางอย่างที่มองไม่เห็นขณะสร้าง และตรวจจับได้ยากโดยใช้การวิเคราะห์แบบคงที่
ปัญหาทั้ง 2 ข้อนี้แก้ไขได้ด้วยกลไกเนมสเปซของ linker กลไกนี้มาจากตัวลิงก์แบบไดนามิก ซึ่งสามารถแยกไลบรารีที่แชร์ในเนมสเปซของ linker ที่แตกต่างกันได้ เพื่อไม่ให้ไลบรารีที่มีชื่อเดียวกันแต่มีสัญลักษณ์ต่างกันเกิดข้อขัดแย้ง
ในทางกลับกัน กลไกเนมสเปซของ linker ให้ความยืดหยุ่นเพื่อให้เนมสเปซของ linker หนึ่งส่งออกไลบรารีที่ใช้ร่วมกันบางรายการและเนมสเปซของ linker อื่นนำไปใช้ได้ ไลบรารีที่ใช้ร่วมกันที่ส่งออกเหล่านี้อาจกลายเป็น Application Programming Interface ที่เปิดเผยต่อสาธารณะในโปรแกรมอื่นๆ ในขณะที่ซ่อนรายละเอียดการใช้งานภายในเนมสเปซ 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 กรณี ตัวลิงก์แบบไดนามิกจะค้นหาเนมสเปซ Linker ที่มีผู้โทรอยู่และพยายามโหลดทรัพยากร Dependency ลงในเนมสเปซ 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 หลายรายการมีดังนี้
- แต่ละส่วนจะมีเนมสเปซหลายรายการ (กราฟ Vertexe) และลิงก์สำรองหลายรายการระหว่างเนมสเปซ (กราฟอาร์ก)
- เนมสเปซแต่ละรายการจะมีการตั้งค่าการแยก เส้นทางการค้นหา เส้นทางที่อนุญาต และการตั้งค่าระดับการเข้าถึงเป็นของตนเอง
ตารางด้านล่างอธิบายความหมายของที่พักแต่ละแห่งอย่างละเอียด
พร็อพเพอร์ตี้การแมปส่วนไดเรกทอรี
พร็อพเพอร์ตี้ | คำอธิบาย | ตัวอย่าง |
---|---|---|
|
เส้นทางไปยังไดเรกทอรีที่ใช้กับส่วน พร็อพเพอร์ตี้แต่ละรายการจะแมปไฟล์ปฏิบัติการภายใต้ไดเรกทอรีไปยังส่วนการกําหนดค่าเนมสเปซของโปรแกรมลิงก์ อาจมีพร็อพเพอร์ตี้ 2 (หรือมากกว่า) รายการที่มี |
ซึ่งหมายความว่าการกำหนดค่าที่ระบุในส่วน การกําหนดค่าที่ระบุในส่วน |
พร็อพเพอร์ตี้ความสัมพันธ์
พร็อพเพอร์ตี้ | คำอธิบาย | ตัวอย่าง |
---|---|---|
additional. |
รายการเนมสเปซเพิ่มเติมที่คั่นด้วยคอมมา (นอกเหนือจากเนมสเปซ |
ซึ่งหมายความว่ามีเนมสเปซ 3 รายการ ( |
namespace. |
รายการเนมสเปซสำรองที่คั่นด้วยคอมมา หากไม่พบไลบรารีที่ใช้ร่วมกันในเนมสเปซปัจจุบัน โปรแกรมลิงก์แบบไดนามิกจะพยายามโหลดไลบรารีที่ใช้ร่วมกันจากเนมสเปซสำรอง เนมสเปซที่ระบุไว้ที่ด้านบนของรายการจะมีลำดับความสำคัญสูงกว่า |
หากไลบรารีที่ใช้ร่วมกันหรือไฟล์ปฏิบัติการขอไลบรารีที่ใช้ร่วมกันซึ่งโหลดลงในเนมสเปซ จากนั้น หากโหลดไลบรารีที่ใช้ร่วมกันจากเนมสเปซ สุดท้าย หากการพยายามทั้งหมดไม่สำเร็จ ตัวเชื่อมโยงแบบไดนามิกจะแสดงข้อผิดพลาด |
namespace. |
รายการไลบรารีที่ใช้ร่วมกันที่คั่นด้วยโคลอนซึ่งค้นหาได้ในเนมสเปซ พร็อพเพอร์ตี้นี้ใช้กับ |
ซึ่งหมายความว่าลิงก์สำรองยอมรับเฉพาะ |
namespace. |
ค่าบูลีนซึ่งระบุว่าสามารถค้นหาไลบรารีที่ใช้ร่วมกันทั้งหมดในเนมสเปซ พร็อพเพอร์ตี้นี้ใช้กับ |
ซึ่งหมายความว่าชื่อไลบรารีทั้งหมดจะไปยังเนมสเปซ |
พร็อพเพอร์ตี้เนมสเปซ
พร็อพเพอร์ตี้ | คำอธิบาย | ตัวอย่าง |
---|---|---|
namespace. |
ค่าบูลีนที่ระบุว่าตัวลิงก์แบบไดนามิกควรตรวจสอบตำแหน่งของไลบรารีที่ใช้ร่วมกันหรือไม่ หาก หาก |
ซึ่งหมายความว่ามีเพียงไลบรารีที่แชร์ใน |
namespace. |
รายการไดเรกทอรีที่คั่นด้วยโคลอนเพื่อค้นหาคลังที่ใช้ร่วมกัน ระบบจะใส่ไดเรกทอรีที่ระบุใน เมื่อ ตัวอย่างเช่น หาก |
ซึ่งหมายความว่า Linker แบบไดนามิกจะค้นหาไลบรารีที่แชร์ใน |
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 สร้างขึ้นโดยการแก้ไขทรัพยากร Dependency ระหว่างเนมสเปซ Linker ตัวอย่างเช่น หากมีการอัปเดตในโมดูล APEX ที่มีอัปเดตทรัพยากร จะมีการสร้างขึ้นเพื่อแสดงการเปลี่ยนแปลงเหล่านี้ ดูรายละเอียดเพิ่มเติมในการสร้างการกำหนดค่า 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 ด้วย นอกจากนี้ การกำหนดค่านี้ยังให้การแยก Linker แบบไดนามิกเต็มรูปแบบด้วย ซึ่งช่วยให้มั่นใจว่าโมดูลในพาร์ติชันระบบจะไม่ใช้ไลบรารีที่แชร์ในพาร์ติชันของผู้ให้บริการ และในทางกลับกัน
ใน Android 8.1 ขึ้นไป การกำหนดค่า VNDK จะเป็นการกำหนดค่าเริ่มต้น และเราขอแนะนำอย่างยิ่งให้เปิดใช้การแยก Linker แบบไดนามิกอย่างเต็มรูปแบบโดยตั้งค่า BOARD_VNDK_VERSION
เป็น current
การกำหนดค่า VNDK
เพื่อใช้ประโยชน์จาก GPU อย่างเต็มที่การกำหนดค่า VNDK จะแยกการพึ่งพาไลบรารีที่ใช้ร่วมกันระหว่างพาร์ติชันระบบกับพาร์ติชันของผู้ให้บริการ ความแตกต่างจะแสดงข้อแตกต่างดังต่อไปนี้เมื่อเทียบกับการกำหนดค่าที่กล่าวถึงในส่วนย่อยก่อนหน้านี้
-
กระบวนการของเฟรมเวิร์ก
- ระบบจะสร้างเนมสเปซ
default
,vndk
,sphal
และrs
- เนมสเปซทั้งหมดจะแยกออกจากกัน
- ระบบจะโหลดไลบรารีที่ใช้ร่วมกันของระบบลงในเนมสเปซ
default
- ระบบจะโหลด SP-HAL ลงในเนมสเปซ
sphal
- ไลบรารีที่ใช้ร่วมกันของ VNDK-SP ที่โหลดลงในเนมสเปซ
vndk
- ระบบจะสร้างเนมสเปซ
-
กระบวนการของผู้ให้บริการ
- ระบบจะสร้างเนมสเปซ
default
,vndk
และsystem
- เนมสเปซ
default
แยกอยู่ - ระบบจะโหลดไลบรารีที่ใช้ร่วมกันของผู้ให้บริการลงในเนมสเปซ
default
- ระบบจะโหลดไลบรารีที่ใช้ร่วมกันของ VNDK และ VNDK-SP ลงในเนมสเปซ
vndk
- ระบบจะโหลด LL-NDK และทรัพยากร Dependency ลงในเนมสเปซ
system
- ระบบจะสร้างเนมสเปซ
ความสัมพันธ์ระหว่างเนมสเปซของ linker แสดงอยู่ด้านล่าง
รูปที่ 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 ระบบจะกำหนดค่าตัวลิงก์แบบไดนามิกให้แยกไลบรารีที่ใช้ร่วมกันของ 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
ลงในกระบวนการของผู้ให้บริการ และแยกไลบรารีที่ใช้ร่วมกันของ VNDK ออกจากเนมสเปซของโปรแกรมเชื่อมโยงเริ่มต้น - แทนที่
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
สําหรับอุปกรณ์ที่มีการแยกเนมสเปซของโปรแกรมลิงก์ VNDK-SP ld.config.legacy.txt
ld.config.legacy.txt
สำหรับอุปกรณ์รุ่นเดิมที่ใช้ Android 7.x หรือต่ำกว่า - นำ
android.hardware.graphics.allocator@2.0.so
ออก - เพิ่มพาร์ติชัน
product
และodm
แล้ว