這個動態連結程式克服了 Treble VNDK 設計的兩個挑戰:
- SP-HAL 共用程式庫及其依附元件,包括 VNDK-SP 會載入架構程序應該會 避免符號衝突。
dlopen()
和android_dlopen_ext()
可能會帶來 一些在建構期間看不到的執行階段依附元件, 靜態分析難以偵測
連結器命名空間可以解決這兩項挑戰 以注意力機制為基礎這項機制是由動態連結器提供。這項服務 可以將共用程式庫隔離在不同的連接器命名空間中, 如果程式庫的程式庫名稱相同,但符號不同,則不會發生衝突。
另一方面,連結器命名空間機制可提供 讓部分共用程式庫可由連接器命名空間匯出,並用於 另一個連接器命名空間這些匯出的共用資料庫 可以在其他程式公開的應用程式設計介面 在連接器命名空間中隱藏實作詳細資料。
例如 /system/lib[64]/libcutils.so
和
有兩個共用項目/system/lib[64]/vndk-sp-${VER}/libcutils.so
程式庫這兩種程式庫可以有不同的符號。載入完成
轉換為不同的連結器命名空間,這樣架構模組就能
/system/lib[64]/libcutils.so
和 SP-HAL 共用資料庫
依附於 /system/lib[64]/vndk-sp-${VER}/libcutils.so
。
另一方面,/system/lib[64]/libc.so
是
是由連結器命名空間匯出的公開程式庫
許多連接器命名空間Kubernetes 的依附元件
/system/lib[64]/libc.so
,例如 libnetd_client.so
會載入至命名空間 /system/lib[64]/libc.so
的命名空間
存放。其他命名空間將無法存取這些依附元件。這個
機制會封裝實作詳細資料,並將
存取 API
運作方式
動態連結器負責載入指定的共用資料庫
在 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 已啟用
動態連結器會先搜尋 |
namespace. |
以冒號分隔的目錄 (包括子目錄) 清單,其中
除了伺服器以外,動態連結器還可以載入共用程式庫
位於以下子目錄的共用程式庫
系統也可以載入 如果 |
這表示
例如,如果沒有 |
namespace. |
動態連接器可載入的目錄清單 (以冒號分隔) ASan 啟用時的共用程式庫。
|
這表示當 ASan 啟用時
|
namespace. |
布林值,以指出程式是否
如果 如果 |
這表示 |
建立連接器命名空間
在 Android 11 中,系統會在執行階段建立連結器設定,位置如下:
/linkerconfig
,而非在
${android-src}/system/core/rootdir/etc
。系統會在啟動時產生設定
回應時間值,其中包含下列項目:
- 如果裝置支援 VNDK
- 供應商分區的目標 VNDK 版本
- 產品劃分的 VNDK 版本
- 已安裝的 APEX 模組
連結器設定是透過解析連結器命名空間之間的依附元件而建立。適用對象
例如,如果 APEX 模組有任何更新,而更新包含依附元件更新,則連接器
系統就會產生反映這些變更建立連接器設定的詳細資料
位於
${android-src}/system/linkerconfig
。
連接器命名空間隔離
共有三種設定類型。根據
「PRODUCT_TREBLE_LINKER_NAMESPACES
」和
BoardConfig.mk
中的 BOARD_VNDK_VERSION
,
相應的設定會在開機時產生
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
命名空間。
- 已建立
連結器命名空間之間的關係說明如下。
圖 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 共用程式庫,使其符號不會與其他程式庫發生衝突 架構共用程式庫連結器命名空間之間的關係為 如下所示。
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
個分區。