Không gian tên của trình liên kết

Trình liên kết động xử lý 2 thách thức trong thiết kế Treble VNDK:

  • Thư viện dùng chung SP-HAL và các phần phụ thuộc của thư viện đó, bao gồm cả VNDK-SP thư viện, được tải vào quy trình khung. Sẽ có một số để ngăn chặn xung đột biểu tượng.
  • dlopen()android_dlopen_ext() có thể giới thiệu một số phần phụ thuộc trong thời gian chạy không hiển thị tại thời điểm xây dựng và có thể khó phát hiện khi sử dụng phương pháp phân tích tĩnh.

Bạn có thể giải quyết hai thử thách này bằng không gian tên trình liên kết cơ chế. Cơ chế này do trình liên kết động cung cấp. Nó có thể tách riêng các thư viện dùng chung trong các không gian tên trình liên kết khác nhau để các thư viện có cùng tên thư viện nhưng có biểu tượng khác nhau sẽ không xung đột.

Mặt khác, cơ chế không gian tên của trình liên kết còn mang lại tính linh hoạt để một số thư viện dùng chung có thể được xuất bởi một không gian tên trình liên kết và được sử dụng một không gian tên trình liên kết khác. Những thư viện chia sẻ đã xuất này có thể trở thành giao diện lập trình ứng dụng được công khai với các chương trình khác trong khi ẩn thông tin triển khai trong không gian tên của trình liên kết.

Ví dụ: /system/lib[64]/libcutils.so/system/lib[64]/vndk-sp-${VER}/libcutils.so là hai đường liên kết dùng chung thư viện. Hai thư viện này có thể có các ký hiệu khác nhau. Đã tải xong vào nhiều không gian tên của trình liên kết để các mô-đun khung có thể phụ thuộc Thư viện dùng chung /system/lib[64]/libcutils.so và SP-HAL có thể phụ thuộc vào /system/lib[64]/vndk-sp-${VER}/libcutils.so.

Mặt khác, /system/lib[64]/libc.so là một ví dụ về một thư viện công khai được một không gian tên trình liên kết xuất ra và nhập vào nhiều không gian tên trình liên kết. Phần phụ thuộc của /system/lib[64]/libc.so, chẳng hạn như libnetd_client.so, được tải vào không gian tên trong đó /system/lib[64]/libc.so cư trú. Các không gian tên khác sẽ không có quyền truy cập vào các phần phụ thuộc đó. Chiến dịch này cơ chế đóng gói chi tiết triển khai trong khi cung cấp cho giao diện.

Cách hoạt động

Trình liên kết động chịu trách nhiệm tải các thư viện dùng chung được chỉ định trong DT_NEEDED mục nhập hoặc thư viện dùng chung được chỉ định bởi đối số của dlopen() hoặc android_dlopen_ext(). Trong cả hai trình liên kết động sẽ tìm không gian tên trình liên kết nơi phương thức gọi cư trú và cố gắng tải các phần phụ thuộc vào cùng một không gian tên trình liên kết. Nếu trình liên kết động không thể tải thư viện chia sẻ vào trình liên kết đã chỉ định không gian tên được xuất, phương thức này yêu cầu không gian tên trình liên kết được liên kết cho các mục đã chia sẻ được xuất thư viện.

Định dạng tệp cấu hình

Định dạng tệp cấu hình dựa trên định dạng tệp INI. Một giá trị điển hình tệp cấu hình sẽ có dạng như sau:

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}

Tệp cấu hình bao gồm:

  • Một số thuộc tính ánh xạ phần thư mục ngay từ đầu cho phần tử trình liên kết động để chọn phần hiệu quả.
  • Một số phần cấu hình của không gian tên trình liên kết:
    • Mỗi phần chứa một số không gian tên (đỉnh đồ thị) và một vài liên kết dự phòng giữa các không gian tên (vòng cung đồ thị).
    • Mỗi không gian tên có cách riêng biệt, đường dẫn tìm kiếm, đường dẫn được phép, và chế độ hiển thị.

Các bảng dưới đây mô tả chi tiết ý nghĩa của từng thuộc tính.

Thuộc tính liên kết mục thư mục

Thuộc tính Mô tả Ví dụ

dir.name

Đường dẫn đến thư mục mà phần [name] áp dụng cho.

Mỗi thuộc tính liên kết các tệp thực thi trong thư mục với một trình liên kết phần cấu hình không gian tên. Có thể có hai (hoặc nhiều) thuộc tính có cùng name nhưng trỏ đến khác .

dir.system = /system/bin
dir.system = /system/xbin
dir.vendor = /vendor/bin

Điều này cho biết rằng cấu hình được chỉ định trong Phần [system] áp dụng cho các tệp thực thi được tải từ /system/bin hoặc /system/xbin.

Cấu hình được chỉ định trong phần [vendor] sẽ áp dụng vào các tệp thực thi được tải từ /vendor/bin.

Thuộc tính quan hệ

Thuộc tính Mô tả Ví dụ
additional.namespaces

Danh sách các không gian tên bổ sung được phân tách bằng dấu phẩy (ngoài default) cho phần này.

additional.namespaces = sphal,vndk

Điều này cho biết có 3 không gian tên (default, sphalvndk) trong [system] .

namespace.name.links

Danh sách không gian tên dự phòng được phân tách bằng dấu phẩy.

Nếu không thể tìm thấy thư viện chia sẻ trong không gian tên hiện tại, tệp động trình liên kết cố gắng tải thư viện chia sẻ từ các không gian tên dự phòng. Chiến lược phát hành đĩa đơn không gian tên được chỉ định ở đầu danh sách có mức độ ưu tiên cao hơn.

namespace.sphal.links = default,vndk

Nếu thư viện dùng chung hoặc tệp thực thi yêu cầu một thư viện dùng chung không tải được vào không gian tên sphal, trình liên kết động sẽ cố tải thư viện chia sẻ từ default không gian tên.

Sau đó, nếu không thể tải thư viện chia sẻ từ Không gian tên default, trình liên kết động sẽ cố tải thư viện chia sẻ từ không gian tên vndk.

Cuối cùng, nếu tất cả các lần thử đều không thành công, trình liên kết động sẽ trả về lỗi.

namespace.name.link.other.shared_libs

Danh sách thư viện dùng chung được phân tách bằng dấu hai chấm có thể được tìm kiếm trong Không gian tên other khi không thể tìm thấy các thư viện đó trong Không gian tên name.

Không thể sử dụng thuộc tính này với namespace.name.link.other.allow_all_shared_libs.

namespace.sphal.link.default.shared_libs = libc.so:libm.so

Điều này cho biết rằng đường liên kết dự phòng chỉ chấp nhận libc.so hoặc libm.so làm tên thư viện được yêu cầu. Trình liên kết động bỏ qua liên kết dự phòng từ sphal đến Không gian tên default nếu tên thư viện được yêu cầu không phải là libc.so hoặc libm.so.

namespace.name.link.other.allow_all_shared_libs

Một giá trị boolean cho biết liệu tất cả thư viện dùng chung có thể đã tìm kiếm trong không gian tên other khi các thư viện đó không thể trong không gian tên name.

Không thể sử dụng thuộc tính này với namespace.name.link.other.shared_libs.

namespace.vndk.link.sphal.allow_all_shared_libs = true

Điều này cho biết rằng tất cả tên thư viện đều có thể đi qua liên kết dự phòng từ không gian tên vndk sang sphal.

Thuộc tính không gian tên

Thuộc tính Mô tả Ví dụ
namespace.name.isolated

Một giá trị boolean cho biết trình liên kết động có cần kiểm tra hay không nơi chứa thư viện chia sẻ.

Nếu isolatedtrue thì chỉ thư viện dùng chung thuộc một trong các thư mục search.paths (không bao gồm các thư mục con) hoặc thuộc một trong permitted.paths thư mục (bao gồm cả thư mục con) có thể là đã tải xong.

Nếu isolatedfalse (mặc định), thì biến thể động trình liên kết không kiểm tra đường dẫn của thư viện dùng chung.

namespace.sphal.isolated = true

Điều này cho biết rằng chỉ các thư viện dùng chung trong search.paths hoặc dưới permitted.paths có thể được tải vào không gian tên sphal.

namespace.name.search.paths

Danh sách các thư mục được phân tách bằng dấu hai chấm để tìm kiếm những thư mục được chia sẻ thư viện.

Các thư mục được chỉ định trong search.paths sẽ được thêm vào trước vào tên thư viện được yêu cầu nếu hàm gọi đến dlopen() hoặc Các mục nhập DT_NEEDED không chỉ định đường dẫn đầy đủ. Thư mục được chỉ định ở đầu danh sách có mức độ ưu tiên cao hơn.

Khi isolatedtrue, các thư viện dùng chung nằm trong một trong số các thư mục search.paths (ngoại trừ thư mục con) có thể được tải bất kể permitted.paths thuộc tính này.

Ví dụ: nếu search.paths/system/${LIB}permitted.paths trống, Có thể tải /system/${LIB}/libc.so nhưng Không thể tải /system/${LIB}/vndk/libutils.so.

namespace.default.search.paths = /system/${LIB}

Điều này cho biết rằng trình liên kết động sẽ tìm kiếm /system/${LIB} đối với các thư viện dùng chung.

namespace.name.asan.search.paths

Danh sách các thư mục được phân tách bằng dấu hai chấm để tìm kiếm thư viện dùng chung khi AddressSanitizer (ASan) đã được bật.

namespace.name.search.paths là bị bỏ qua khi ASan được bật bật.

namespace.default.asan.search.paths = /data/asan/system/${LIB}:/system/${LIB}

Điều này cho biết rằng khi ASan được bật trình liên kết động sẽ tìm kiếm /data/asan/system/${LIB} trước tiên và sau đó tìm kiếm /system/${LIB}.

namespace.name.permitted.paths

Danh sách các thư mục được phân tách bằng dấu hai chấm (bao gồm cả các thư mục con) trong đó trình liên kết động có thể tải thư viện dùng chung (ngoài search.paths) khi isolatedtrue.

Thư viện dùng chung nằm trong thư mục con của Bạn cũng có thể tải permitted.paths. Ví dụ: nếu permitted.paths mới là /system/${LIB}, cả /system/${LIB}/libc.so và Có thể tải /system/${LIB}/vndk/libutils.so.

Nếu isolatedfalse, permitted.paths sẽ bị bỏ qua và một cảnh báo sẽ được phát ra.

namespace.default.permitted.paths = /system/${LIB}/hw

Điều này cho biết rằng các thư viện dùng chung trong Có thể tải /system/${LIB}/hw vào Không gian tên default.

Ví dụ: nếu không có permitted.paths, Không tải được libaudiohal.so /system/${LIB}/hw/audio.a2dp.default.so vào Không gian tên default.

namespace.name.asan.permitted.paths

Danh sách các thư mục được phân tách bằng dấu hai chấm mà trình liên kết động có thể tải thư viện dùng chung khi bật ASan.

namespace.name.permitted.paths là bị bỏ qua khi bật ASan.

namespace.default.asan.permitted.paths = /data/asan/system/${LIB}/hw:/system/${LIB}/hw

Thông báo này cho biết khi ASan được bật thư viện dùng chung thuộc /data/asan/system/${LIB}/hw hoặc /system/${LIB}/hw có thể được tải vào Không gian tên default.

namespace.name.visible

Một giá trị boolean cho biết liệu chương trình (ngoài libc) có thể lấy tên người dùng không gian tên của trình liên kết bằng android_get_exported_namespace() rồi mở một thư viện chia sẻ trong không gian tên của trình liên kết bằng cách chuyển tên người dùng đến android_dlopen_ext().

Nếu visibletrue, android_get_exported_namespace() luôn trả về tên người dùng nếu không gian tên đó đã tồn tại.

Nếu visiblefalse (mặc định), android_get_exported_namespace() luôn trả lại hàng NULL bất kể có vùng chứa tên hay không. Thư viện chia sẻ chỉ có thể được tải vào vùng chứa tên này nếu (1) có người khác yêu cầu các tài sản này không gian tên trình liên kết có một đường liên kết dự phòng đến không gian tên này, hoặc (2) chúng do các thư viện dùng chung hoặc tệp thực thi khác trong không gian tên này yêu cầu.

namespace.sphal.visible = true

Điều này cho biết rằng android_get_exported_namespace("sphal") có thể trả về tên người dùng không gian tên trình liên kết hợp lệ.

Tạo không gian tên của trình liên kết

Trên Android 11, cấu hình trình liên kết được tạo trong thời gian chạy trong /linkerconfig thay vì sử dụng tệp văn bản thuần tuý ở ${android-src}/system/core/rootdir/etc. Cấu hình này được tạo khi khởi động dựa trên môi trường thời gian chạy, bao gồm các mục sau:

  • Nếu thiết bị hỗ trợ VNDK
  • Phiên bản VNDK mục tiêu của phân vùng nhà cung cấp
  • Phiên bản VNDK của phân vùng sản phẩm
  • Các mô-đun APEX đã cài đặt

Cấu hình trình liên kết được tạo bằng cách phân giải các phần phụ thuộc giữa các không gian tên của trình liên kết. Cho ví dụ: nếu có bất kỳ nội dung cập nhật nào trên các mô-đun APEX bao gồm thông tin cập nhật phần phụ thuộc, trình liên kết cấu hình được tạo phản ánh những thay đổi này. Thông tin chi tiết khác để tạo cấu hình trình liên kết có thể được tìm thấy trong ${android-src}/system/linkerconfig.

Tách biệt không gian tên của trình liên kết

Có 3 loại cấu hình. Tuỳ thuộc vào giá trị của PRODUCT_TREBLE_LINKER_NAMESPACESBOARD_VNDK_VERSION trong BoardConfig.mk, cấu hình tương ứng được tạo tại thời điểm khởi động.

PRODUCT_TREBLE_
LINKER_NAMESPACES
BOARD_VNDK_
VERSION
Cấu hình đã chọn Yêu cầu về VTS
true current VNDK Bắt buộc đối với các thiết bị chạy Android 9 trở lên
Trống VNDK Lite Bắt buộc đối với các thiết bị chạy Android 8.x
false Trống Legacy Đối với các thiết bị không hỗ trợ chuẩn Treble

Cấu hình VNDK Lite tách biệt các thư viện dùng chung SP-HAL và VNDK-SP. Trong Android 8.0, hàm này bạn phải là tệp cấu hình cho trình liên kết động khi PRODUCT_TREBLE_LINKER_NAMESPACEStrue.

Cấu hình VNDK cũng tách biệt các thư viện dùng chung SP-HAL và VNDK-SP. Ngoài ra, cấu hình này cung cấp tính năng tách biệt trình liên kết động hoàn toàn. Quy trình này đảm bảo rằng các mô-đun trong phân vùng hệ thống sẽ không phụ thuộc vào trong phân vùng nhà cung cấp và ngược lại.

Trong Android 8.1 trở lên, cấu hình VNDK là cấu hình mặc định Bạn nên bật hoàn toàn tính năng tách biệt trình liên kết động bằng cách đặt BOARD_VNDK_VERSION thành current.

Cấu hình VNDK

Cấu hình VNDK tách biệt các phần phụ thuộc của thư viện dùng chung giữa phân vùng hệ thống và phân vùng nhà cung cấp. So sánh với cấu hình được đề cập trong tiểu mục trước, sự khác biệt được trình bày như sau:

  • Quy trình khung

    • default, vndk Không gian tên sphalrs đã được tạo.
    • Tất cả các không gian tên đều bị tách riêng.
    • Thư viện chia sẻ của hệ thống sẽ được tải vào không gian tên default.
    • SP-HAL được tải vào không gian tên sphal.
    • Các thư viện chia sẻ VNDK-SP được tải vào không gian tên vndk.
  • Quy trình của nhà cung cấp

    • Đã tạo các không gian tên default, vndksystem.
    • Không gian tên default bị tách riêng.
    • Thư viện chia sẻ của nhà cung cấp được tải vào không gian tên default.
    • Thư viện chia sẻ VNDK và VNDK-SP được tải vào không gian tên vndk.
    • LL-NDK và các phần phụ thuộc của nó được tải vào không gian tên system.

Mối quan hệ giữa các không gian tên của trình liên kết được minh hoạ bên dưới.

Biểu đồ không gian tên của trình liên kết được mô tả trong cấu hình VNDK

Hình 1. Tách biệt không gian tên của trình liên kết (cấu hình VNDK).

Trong hình ảnh trên, LL-NDKVNDK-SP đại diện cho những nội dung sau thư viện dùng chung:

  • 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

Bạn có thể xem thêm thông tin chi tiết trong /linkerconfig/ld.config.txt trên thiết bị.

Cấu hình VNDK Lite

Kể từ Android 8.0, trình liên kết động được định cấu hình để tách biệt SP-HAL và Thư viện dùng chung VNDK-SP sao cho các biểu tượng của chúng không xung đột với các thư viện khác thư viện dùng chung khung. Mối quan hệ giữa các không gian tên của trình liên kết là như bên dưới.

Biểu đồ không gian tên của trình liên kết được mô tả trong cấu hình VNDK Lite
Hình 2. Tách biệt không gian tên của trình liên kết (cấu hình VNDK Lite)

LL-NDKVNDK-SP là công cụ dành cho các thư viện dùng chung sau:

  • LL-NDK
    • libEGL.so
    • libGLESv1_CM.so
    • libGLESv2.so
    • libc.so
    • libdl.so
    • liblog.so
    • libm.so
    • libnativewindow.so
    • libstdc++.so (không có trong cấu hình)
    • libsync.so
    • libvndksupport.so
    • libz.so (đã chuyển sang VNDK-SP trong cấu hình)
  • 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

Bảng dưới đây liệt kê cấu hình không gian tên cho khung các quy trình, được trích từ phần [system] trong cấu hình VNDK Lite.

Không gian tên Thuộc tính Giá trị
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 (cho 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 (đối với 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 (đối với nhân RS được biên dịch)
isolated true
visible true
links default,vndk
link.default.shared_libs LL-NDK

libmediandk.so libft2.so
link.vndk.shared_libs VNDK-SP

Bảng dưới đây trình bày cấu hình không gian tên cho các quy trình của nhà cung cấp, đoạn mã này được trích từ phần [vendor] trong cấu hình VNDK Lite.

Không gian tên Thuộc tính Giá trị
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} (không dùng nữa)
/product/${LIB} (không dùng nữa)
isolated false

Bạn có thể xem thêm thông tin chi tiết trong /linkerconfig/ld.config.txt trên thiết bị này.

Nhật ký tài liệu

Các thay đổi đối với Android 11

  • Trong Android 11, các tệp ld.config.*.txt tĩnh sẽ là bị xoá khỏi cơ sở mã và LinkerConfig sẽ tạo chúng trong thời gian chạy.

Các thay đổi liên quan đến Android 9

  • Trong Android 9, không gian tên trình liên kết vndk được thêm vào nhà cung cấp các quy trình và thư viện chia sẻ VNDK được tách biệt với trình liên kết mặc định không gian tên.
  • Thay thế PRODUCT_FULL_TREBLE bằng nội dung cụ thể hơn PRODUCT_TREBLE_LINKER_NAMESPACES.
  • Android 9 đổi tên của cấu hình trình liên kết động sau đây tệp.
    Android 8.x Android 9 Mô tả
    ld.config.txt.in ld.config.txt Đối với các thiết bị tách biệt không gian tên của trình liên kết trong thời gian chạy
    ld.config.txt ld.config.vndk_lite.txt Đối với các thiết bị được tách biệt không gian tên của trình liên kết VNDK-SP
    ld.config.legacy.txt ld.config.legacy.txt Đối với các thiết bị cũ chạy Android 7.x trở xuống
  • Xoá android.hardware.graphics.allocator@2.0.so.
  • Thêm phân vùng productodm.