Linker แบบไดนามิกแก้ปัญหา 2 อย่างในการออกแบบ Treble VNDK ดังนี้
- ไลบรารีที่ใช้ร่วมกัน SP-HAL และทรัพยากร Dependency ต่างๆ รวมถึง VNDK-SP จะถูกโหลดเข้าสู่กระบวนการของเฟรมเวิร์ก ควรมีบางอย่าง เพื่อป้องกันไม่ให้สัญลักษณ์ขัดแย้งกัน
dlopen()
และandroid_dlopen_ext()
แนะนำได้ ทรัพยากร Dependency ของรันไทม์บางรายการที่ไม่แสดงขณะสร้างบิลด์ ตรวจจับได้ยากเมื่อใช้การวิเคราะห์แบบคงที่
ปัญหา 2 ข้อนี้แก้ไขได้โดยเนมสเปซ Linker Google Analytics กลไกนี้ให้บริการโดย Linker แบบไดนามิก ทั้งนี้ สามารถแยกไลบรารีที่แชร์ในเนมสเปซของ Linker ที่แตกต่างกันได้ ห้องสมุดที่มีชื่อห้องสมุดเดียวกันแต่มีสัญลักษณ์ต่างกันจะไม่มีความขัดแย้งกัน
ในทางกลับกัน กลไกเนมสเปซของ Linker ให้ความยืดหยุ่น เพื่อให้ไลบรารีที่ใช้ร่วมกันบางรายการส่งออกโดยเนมสเปซ Linker และใช้โดย เนมสเปซ Linker อื่น ไลบรารีที่ใช้ร่วมกันที่ส่งออกเหล่านี้อาจกลายเป็น Application Programming Interface ที่เผยแพร่ต่อสาธารณะในโปรแกรมอื่นๆ โดยซ่อนรายละเอียดการใช้งานภายในเนมสเปซ Linker
เช่น /system/lib[64]/libcutils.so
และ
/system/lib[64]/vndk-sp-${VER}/libcutils.so
แชร์ 2 รายการ
ห้องสมุด ไลบรารีทั้งสองนี้อาจมีสัญลักษณ์ที่แตกต่างกันได้ โหลดแล้ว
ลงในเนมสเปซ Linker ที่แตกต่างกันเพื่อให้โมดูลเฟรมเวิร์กทำงานได้
ไลบรารีที่ใช้ร่วมกัน /system/lib[64]/libcutils.so
และ SP-HAL สามารถ
ขึ้นอยู่กับ /system/lib[64]/vndk-sp-${VER}/libcutils.so
ในทางกลับกัน /system/lib[64]/libc.so
เป็นตัวอย่างของ
ไลบรารีสาธารณะที่ส่งออกโดยเนมสเปซ Linker และนำเข้าสู่
Namespace ของ Linker จำนวนมาก ทรัพยากร Dependency ของ
/system/lib[64]/libc.so
เช่น libnetd_client.so
จะโหลดลงในเนมสเปซที่มี /system/lib[64]/libc.so
อยู่ เนมสเปซอื่นๆ จะไม่มีสิทธิ์เข้าถึงทรัพยากร Dependency เหล่านั้น ช่วงเวลานี้
จะสรุปรายละเอียดการนำไปใช้
ควบคู่ไปกับการให้บริการสู่สาธารณะ
อินเทอร์เฟซ
วิธีการทำงาน
Linker แบบไดนามิกมีหน้าที่โหลดไลบรารีที่ใช้ร่วมกันที่ระบุ
ใน DT_NEEDED
รายการหรือไลบรารีที่ใช้ร่วมกันที่ระบุโดย
อาร์กิวเมนต์ของ dlopen()
หรือ android_dlopen_ext()
ในทั้ง 2 รูปแบบ
ตัวลิงก์แบบไดนามิกจะค้นหาเนมสเปซ Linker ที่เครื่องมือเรียก
อยู่และพยายามโหลดทรัพยากร Dependency ลงในเนมสเปซ 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 แบบไดนามิกเพื่อเลือกส่วนที่มีประสิทธิภาพ
-
ส่วนการกำหนดค่าเนมสเปซของ Linker หลายรายการมีดังนี้
- แต่ละส่วนประกอบด้วยเนมสเปซหลายรายการ (กราฟ Vertexes) และหลายๆ จุด ลิงก์สำรองระหว่างเนมสเปซ (กราฟอาร์ก)
- เนมสเปซแต่ละรายการมี การแยก เส้นทางการค้นหา เส้นทางที่ได้รับอนุญาต และการตั้งค่าระดับการเข้าถึง
ตารางด้านล่างอธิบายความหมายของที่พักแต่ละแห่งอย่างละเอียด
พร็อพเพอร์ตี้การแมปส่วนไดเรกทอรี
พร็อพเพอร์ตี้ | คำอธิบาย | ตัวอย่าง |
---|---|---|
|
เส้นทางไปยังไดเรกทอรีที่ส่วน พร็อพเพอร์ตี้แต่ละรายการจะแมปไฟล์ปฏิบัติการภายใต้ไดเรกทอรีกับ Linker
ส่วนการกำหนดค่าเนมสเปซ อาจมีพร็อพเพอร์ตี้ 2 รายการ (หรือมากกว่านั้น)
ที่มี |
ซึ่งหมายความว่าการกำหนดค่าที่ระบุใน
ส่วน ใช้การกำหนดค่าที่ระบุในส่วน |
พร็อพเพอร์ตี้ความสัมพันธ์
พร็อพเพอร์ตี้ | คำอธิบาย | ตัวอย่าง |
---|---|---|
additional. |
รายการเนมสเปซเพิ่มเติมที่คั่นด้วยคอมมา (นอกเหนือจาก
|
ซึ่งหมายความว่ามีเนมสเปซ 3 รายการ ( |
namespace. |
รายการเนมสเปซสำรองที่คั่นด้วยคอมมา หากไม่พบไลบรารีที่ใช้ร่วมกันในเนมสเปซปัจจุบัน Linker พยายามโหลดไลบรารีที่ใช้ร่วมกันจากเนมสเปซสำรอง Namespace ที่ระบุที่ตอนต้นของรายการมีลำดับความสำคัญสูงกว่า |
หากไลบรารีที่ใช้ร่วมกันหรือไฟล์ปฏิบัติการขอไลบรารีที่ใช้ร่วมกันที่
โหลดลงในเนมสเปซ แล้วถ้าโหลดไลบรารีที่ใช้ร่วมกันจาก
เนมสเปซ และสุดท้าย หากพยายามทั้งหมดไม่สำเร็จ Linker แบบไดนามิกจะแสดงข้อผิดพลาด |
namespace. |
รายการไลบรารีที่ใช้ร่วมกันที่คั่นด้วยโคลอน ซึ่งสามารถค้นหาได้ใน
เนมสเปซ พร็อพเพอร์ตี้นี้ใช้ไม่ได้กับ
|
ซึ่งเป็นการระบุว่าลิงก์สำรองยอมรับเฉพาะ |
namespace. |
ค่าบูลีนที่ระบุว่าไลบรารีที่แชร์ทั้งหมดสามารถ
ค้นหาในเนมสเปซ พร็อพเพอร์ตี้นี้ใช้ไม่ได้กับ
|
ซึ่งบ่งบอกว่าชื่อไลบรารีทั้งหมดสามารถนำทางไปยังลิงก์สำรองได้
จาก |
พร็อพเพอร์ตี้เนมสเปซ
พร็อพเพอร์ตี้ | คำอธิบาย | ตัวอย่าง |
---|---|---|
namespace. |
ค่าบูลีนที่ระบุว่าตัวลิงก์แบบไดนามิกควรตรวจสอบหรือไม่ ที่เก็บไลบรารีที่ใช้ร่วมกัน หาก หาก |
ซึ่งหมายความว่าเฉพาะไลบรารีที่ใช้ร่วมกันใน
|
namespace. |
รายการไดเรกทอรีที่คั่นด้วยโคลอนสำหรับค้นหารายการที่แชร์ ห้องสมุด มีการเพิ่มไดเรกทอรีที่ระบุใน เมื่อ ตัวอย่างเช่น หาก |
ซึ่งเป็นการระบุว่าการค้นหา Linker แบบไดนามิก
|
namespace. |
รายการไดเรกทอรีที่คั่นด้วยโคลอนสำหรับค้นหาไลบรารีที่ใช้ร่วมกันเมื่อ เปิดใช้ AddressSanitizer (ASan) อยู่
|
สิ่งนี้หมายความว่าเมื่อ
ASan เปิดใช้งาน
Linker แบบไดนามิกค้นหา |
namespace. |
รายการไดเรกทอรีที่คั่นด้วยโคลอน (รวมถึงไดเรกทอรีย่อย) โดยที่
Linker แบบไดนามิกสามารถโหลดไลบรารีที่ใช้ร่วมกัน (นอกเหนือจาก
ไลบรารีที่ใช้ร่วมกันซึ่งอยู่ภายใต้ไดเรกทอรีย่อยของ
นอกจากนี้ยังโหลด หาก |
ซึ่งเป็นการระบุว่าไลบรารีที่ใช้ร่วมกันภายใต้
เช่น หากไม่มี |
namespace. |
รายการไดเรกทอรีที่คั่นด้วยโคลอนซึ่งโหลด Linker แบบไดนามิกได้ ไลบรารีที่ใช้ร่วมกันเมื่อเปิดใช้ ASan
|
ซึ่งเป็นการระบุว่าเมื่อเปิดใช้ ASan
ไลบรารีที่แชร์ภายใต้ |
namespace. |
ค่าบูลีนที่ระบุว่าโปรแกรม (นอกเหนือจาก
หาก หาก |
ซึ่งหมายความว่า |
การสร้างเนมสเปซ Linker
ใน Android 11 การกำหนดค่า Linker สร้างขึ้นขณะรันไทม์ภายใต้
/linkerconfig
แทนการใช้ไฟล์ข้อความธรรมดาใน
${android-src}/system/core/rootdir/etc
ระบบจะสร้างการกำหนดค่าเมื่อเปิดเครื่อง
เวลาตามสภาพแวดล้อมรันไทม์ ซึ่งรวมถึงรายการต่อไปนี้
- หากอุปกรณ์รองรับ VNDK
- เวอร์ชัน VNDK เป้าหมายของพาร์ติชันผู้ให้บริการ
- เวอร์ชัน VNDK ของพาร์ติชันผลิตภัณฑ์
- โมดูล APEX ที่ติดตั้ง
การกำหนดค่า Linker สร้างขึ้นโดยการแก้ไขทรัพยากร Dependency ระหว่างเนมสเปซ Linker สำหรับ
ตัวอย่างเช่น ถ้ามีการอัปเดตในโมดูล APEX ที่มีการอัปเดตทรัพยากร Dependency, 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
ต้องเป็นไฟล์การกำหนดค่าสำหรับ Linker แบบไดนามิกเมื่อ
PRODUCT_TREBLE_LINKER_NAMESPACES
คือtrue
การกำหนดค่า VNDK จะแยกไลบรารีที่ใช้ร่วมกัน SP-HAL และ VNDK-SP ด้วย นอกจากนี้ การกำหนดค่านี้จะให้การแยก Linker แบบไดนามิกอย่างเต็มรูปแบบ เพื่อให้มั่นใจว่าโมดูลในพาร์ติชันระบบจะไม่อิงตาม ในพาร์ติชันผู้ให้บริการ หรือในพาร์ติชันของผู้ให้บริการ
ใน Android 8.1 ขึ้นไป ระบบจะใช้การกำหนดค่า VNDK เป็นค่าเริ่มต้น
และเราขอแนะนำอย่างยิ่งให้เปิดใช้การแยก Linker แบบไดนามิกเต็มรูปแบบด้วยการตั้งค่า
BOARD_VNDK_VERSION
ไปยัง current
การกำหนดค่า VNDK
การกำหนดค่า VNDK จะแยกทรัพยากร Dependency ของไลบรารีที่ใช้ร่วมกัน ระหว่างพาร์ติชันระบบและพาร์ติชันผู้ให้บริการ เปรียบเทียบกับ การกำหนดค่าที่กล่าวถึงในส่วนย่อยก่อนหน้านี้ ความแตกต่าง มีรายละเอียดดังต่อไปนี้
-
กระบวนการในเฟรมเวิร์ก
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 การแยกเนมสเปซ 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
สำหรับ 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 ระบบจะเพิ่มเนมสเปซ Linker
vndk
ไปยังผู้ให้บริการ กระบวนการและไลบรารีที่ใช้ร่วมกันของ VNDK จะแยกออกจากตัวลิงก์เริ่มต้น Namespace - แทนที่
PRODUCT_FULL_TREBLE
ด้วยคำที่เจาะจงมากขึ้นPRODUCT_TREBLE_LINKER_NAMESPACES
- Android 9 เปลี่ยนชื่อการกำหนดค่า Linker แบบไดนามิกต่อไปนี้
Android 8.x Android 9 คำอธิบาย ld.config.txt.in
ld.config.txt
สําหรับอุปกรณ์ที่มีการแยกเนมสเปซ Linker แบบรันไทม์ 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
แล้ว