ตัวลิงก์แบบไดนามิกจะจัดการกับความท้าทาย 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 แสดงไว้ด้านล่าง
รูปที่ 1 การแยกเนมสเปซของ Linker (การกำหนดค่า 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 เป็นต้นมา ระบบจะกำหนดค่าลิงก์เกอร์แบบไดนามิกเพื่อแยกไลบรารีที่ใช้ร่วมกันของ SP-HAL และ VNDK-SP เพื่อไม่ให้สัญลักษณ์ของไลบรารีเหล่านั้นขัดแย้งกับไลบรารีที่ใช้ร่วมกันของเฟรมเวิร์กอื่นๆ ความสัมพันธ์ระหว่างเนมสเปซของ Linker แสดงอยู่ด้านล่าง
LL-NDK และ VNDK-SP หมายถึงไลบรารีที่ใช้ร่วมกันต่อไปนี้
-
LL-NDK
libEGL.solibGLESv1_CM.solibGLESv2.solibc.solibdl.soliblog.solibm.solibnativewindow.solibstdc++.so(ไม่ได้อยู่ในการกำหนดค่า)libsync.solibvndksupport.solibz.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
ตารางด้านล่างแสดงการกำหนดค่าเนมสเปซสำหรับกระบวนการของเฟรมเวิร์ก ซึ่งเป็นข้อความที่คัดลอกจากส่วน [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.solibft2.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.inld.config.txtสำหรับอุปกรณ์ที่มีการแยกเนมสเปซของ Linker รันไทม์ 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