这篇文章主要为大家介绍了Android VNDK使用及原理深入探究,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
为何要使用 VNDK?
VNDK的全称是Vendor Native Development Kit,是Android 8.0引入的一种新技术。它表现一系列库的合集,用于让供应商开发自己的HALs。VNDK 包含在 system.img 中,并在运行时与供应商代码动态关联。
官方文档的解释给我的感觉其目的就是收敛Android的碎片化。不仅仅VNDK,Android 8.0引入许多的技术都是为了将System与Vendor分割开来。这样可以保持Android核心系统的纯净性,而将碎片化扔给供应商维护。渐渐的芯片供应商和设备厂商可以无需关心Android系统的实现,仅仅使用VNDK就可以完成产品开发。
VNDK相关概念
供应商模块
供应商模块是特定于供应商的可执行文件或共享库,这些模块将安装到供应商分区中。
在 Android.bp 文件中,供应商模块必须将vendor或proprietary属性设置为 true。
在 Android.mk 文件中,供应商模块必须将 LOCAL_VENDOR_MODULE 或 LOCAL_PROPRIETARY_MODULE 设置为 true。
Framework共享库
在理想的Android 8.0及更高版本环境中,Framework进程不加载供应商共享库,而供应商进程仅加载供应商共享库(和一部分Framework共享库)。Framework进程与供应商进程之间的通信由HIDL和hardware binder控制。
供应商进程需要使用Framework共享库可能随系统的更新而发生变化。为了保证供应商模块在多个Android版本上皆可正常工作,根据Framework共享库的特性不同,将其三个子类别:
LL-NDK库:已知稳定的Framework共享库,它们的开发者致力于保持其 API/ABI 稳定性。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 库 (VNDK):可以安全复制两次的Framework共享库。Framework模块和供应商模块可以与其各自的库副本相关联。Framework共享库只有满足以下条件才能成为合格的 VNDK 库:
不向Framework发送或从Framework接收 IPC。
与 ART 虚拟机无关。
不读写文件格式不稳定的文件/分区。
没有需要法律审查的特殊软件许可。
其代码所有者不反对供应商使用该库。
框架专用库 (FWK-ONLY) :不属于上述类别的Framework共享库。此类库具有以下特点:
被视为Framework内部实现细节。
不得由供应商模块访问。
具有不稳定的 ABI/API,无 API/ABI 兼容性保证。
不会被复制。
LL-NDK
LL-NDK 共享库是具有稳定 ABI 的共享库。框架模块和供应商模块均具有相同的最新实现。对于每个 LL-NDK 共享库,Android.bp 都包含一个 llndk_library 模块定义:
llndk_library {
name: "libvndksupport",
symbol_file: "libvndksupport.map.txt",
}
该模块定义指定了模块名称和符号文件,后者描述了对供应商模块可见的符号。例如:
LIBVNDKSUPPORT {
global:
android_load_sphal_library; # vndk
android_unload_sphal_library; # vndk
local:
*;
};
Same-Process HAL (SP-HAL)
Same-Process HAL (SP-HAL) 是预定义的的一组HAL,作为供应商共享库进行实现,并被加载到Framework进程中。SP-HAL 必须仅依赖于 LL-NDK 和 VNDK-SP。VNDK-SP 是一部分预定义的符合条件的 VNDK 库。VNDK-SP 库会被仔细审查,以确保将 VNDK-SP 库双重加载到Framework进程中不会导致问题。SP-HAL 和 VNDK-SP 均由 Google 定义,并通过链接器命名空间进行隔离。
以下库是经过批准的 SP-HAL:
libGLESv1_CM_${driver}.so
libGLESv2_${driver}.so
libGLESv3_${driver}.so
libEGL_${driver}.so
vulkan.${driver}.so
android.hardware.renderscript@1.0-impl.so
android.hardware.graphics.mapper@2.0-impl.so
以下库是 SP-HAL 可以访问的 VNDK-SP 库:
android.hardware.graphics.common@1.0.so
android.hardware.graphics.mapper@2.0.so
android.hardware.renderscript@1.0.so (Renderscript)
libRS_internal.so (Renderscript)
libbase.so
libc++.so
libcutils.so
libhardware.so
libhidlbase.so
libhidltransport.so
libhwbinder.so
libion.so
libutils.so
libz.so
以下 VNDK-SP 依赖项 (VNDK-SP-Private) 对 SP-HAL 来说是不可见的:
libRSCpuRef.so (Renderscript)
libRSDriver.so (Renderscript)
libbacktrace.so
libblas.so (Renderscript)
libbcinfo.so (Renderscript)
liblzma.so
libunwind.so
以下是具有 RS 例外的框架专用库 (FWK-ONLY-RS):
libft2.so (Renderscript)
libmediandk.so (Renderscript)
VNDK 库简介
VNDK 定义了可与供应商代码相关联的库集:VNDK-core、VNDK-SP 和 LL-NDK,并阻止供应商使用不在 VNDK 集内的库。
VNDK-core 库安装在 /system/lib[64]/vndk-${VER} 中,仅适用于 API 级别为 ${VER} 的供应商进程。${VER} 可以通过/vendor/default.prop中的系统属性ro.vndk.version获取。系统进程不得使用这些库,而必须使用安装在 /system/lib[64] 中的库。由于每个进程都具有严格的命名空间限制,因此不会造成重复加载 VNDK-core 库。要在 VNDK-core 中添加库,请将以下内容添加到 Android.bp 中:
vendor_available: true,
vndk: {
enabled: true,
},
VNDK-SP 库安装在 /system/lib[64]/vndk-sp-${VER} 中,可以被供应商进程和系统进程(通过安装在供应商分区中的 SP-HAL 库)使用。VNDK-SP 库可以重复加载。要在 VNDK-SP 中添加库,请将以下内容添加到 Android.bp 中:
vendor_available: true,
vndk: {
enabled: true,
support_system_process: true,
},
LL-NDK 库安装在 /system/lib[64] 中。供应商模块可以使用 LL-NDK stub访问 LL-NDK 库的预选符号。LL-NDK 库必须支持向后兼容,且具有 ABI 稳定性,以便旧版供应商模块使用新版 LL-NDK 库。由于 LL-NDK 具有 ABI 稳定特性,VNDK 快照无需包含旧版供应商映像的 LL-NDK 库。
目录
VNDK库可以大致划分为以下目录:
/system/lib[64] 包含所有Framework共享库,具体包括 LL-NDK、VNDK 和Framework专用库(包括 LL-NDK-Private 和一些与 VNDK-SP 中的库同名的库)。
/system/lib[64]/vndk-sp 包含适用于 Same-Process HAL 的 VNDK-SP 库。
/vendor/lib[64] 包含供应商扩展的 VNDK 库(DXUA 库或 DXUX VNDK 库)、Same-Process HAL 实现,以及其他供应商共享库。
/vendor/lib[64]/vndk-sp 可能包含供应商扩展的 VNDK-SP 库。
供应商模块从 /system/lib[64] 中加载 VNDK 库。
VNDK 电子表格
Google 会提供一个符合条件的 VNDK 电子表格(例如 eligible-list.csv),该电子表格会标记可由供应商模块使用的框架共享库:
下表描述了适用于供应商共享库的标记:
标记之间的关系:
VNDK 快照
VNDK 快照就是一组预编译的库文件和配置文件的集合。因为VNDK的实质就是要规范供应商的开发,如果保证VNDK接口稳定的标准化,供应商就无需修改VNDK库。系统只要提供所有VNDK版本的二进制文件,就可以满足供应商的开发。这些需求的文件就是VNDK快照需要提供的内容。
VNDK 快照包含以下文件:
VNDK-core 和 VNDK-SP 共享库的供应商变体。
无需 LL-NDK 共享库,因为这类库是向后兼容的。
对于 64 位目标,TARGET_ARCH 和 TARGET_2ND_ARCH 库都将被编译并包含在内。
VNDK-core、VNDK-SP、LL-NDK 和 VNDK-private 库的列表,文件为 [vndkcore|vndksp|llndk|vndkprivate].libraries.txt。
链接器配置文件为 ld.config.txt。
许可文件。
module_paths.txt。记录所有 VNDK 库的模块路径;检查 GPL 项目是否已在指定 Android 源代码树中发布源代码时,需要用到这种文件。
以下示例展示了 arm64 (TARGET_ARCH=arm64) VNDK 快照 ZIP 文件 (android-vndk-arm64.zip) 的目录结构。
供应商镜像会依赖于特定版本的VNDK,所以系统镜像中应该提供供应商需求的VNDK版本的镜像。即使系统镜像与供应商镜像使用不同版本的Android进行编译,但是只要保证系统镜像能够提供正确的VNDK就保证正常运行。下图展示了Android P系统镜像使用Android O供应商镜像的场景。
启用 VNDK
编译选项
在 BoardConfig.mk添加BOARD_VNDK_VERSION=current可以在编译过程开启VNDK。也可以在编译模块时传递该编译选项,例如: m -j BOARD_VNDK_VERSION=current MY-LIB)。
当启用 BOARD_VNDK_VERSION=current 后,编译系统会检查库的依赖性和头文件的合法性。
确保vendor对象仅依赖于VNDK库集:VNDK-core、VNDK-SP 和 LL-NDK。确保core组件不依赖与vendor组件。
移除全局头文件的依赖项,以便编译器可以明确是否使用-D__ANDROID_VNDK__来编译头文件。就是说全局头文件无法再使用传递方式包含在头文件内。
启用 BOARD_VNDK_VERSION后,系统会移除多个默认的全局头文件搜索路径。模块使用这些路径下的头文件时,需要明确指定与 header_libs、static_libs 和/或 shared_libs 的依赖关系。这些路径中包括:
frameworks/av/include
frameworks/native/include
frameworks/native/opengl/include
hardware/libhardware/include
hardware/libhardware_legacy/include
hardware/ril/include
libnativehelper/include
libnativehelper/include_deprecated
system/core/include
system/media/audio/include
供应商变体库
在 Android.bp 文件中,cc_library、cc_library_static、cc_library_shared 和 cc_library_headers 模块定义支持三个与 VNDK 相关的属性:vendor_available、vndk.enabled 和 vndk.support_system_process。
如果 一个库标记为vendor_available 或 vndk.enabled 为 true,则可能被编译两次,生成两种变体:核心变体和供应商变体。
核心变体被视为Framework模块,将安装到 /system/lib[64] 中。
而供应商变体应被视为供应商模块。系统根据模块依赖性来决定是否编译变体,并进行依赖性检查。供应商变体安装路径会根据 Android.bp中的属性来决定。
下表总结了编译系统如何处理供应商变体,
注意:供应商可以为其模块设置 vendor_available,但不得设置 vndk.enabled 和 vndk.support_system_process,因为供应商模块无法在通用系统映像 (GSI) 中找到它们。
条件编译
默认情况下,Android 编译系统会为供应商变体和 VNDK 扩展定义 ANDROID_VNDK。您可以使用 C 预处理器防护程序保护代码:
void all() { }
#if !defined(__ANDROID_VNDK__)
void framework_only() { }
#endif
#if defined(__ANDROID_VNDK__)
void vndk_only() { }
#endif
除了 ANDROID_VNDK,还可以在 Android.bp 中指定不同的 cflags 或 cppflags。在 target.vendor 中指定的 cflags 或 cppflags 是专门针对供应商变体的。
例如,以下 Android.bp 定义了 libexample 和 libexample_ext。它为libexample的供应商变体定义了"LIBEXAMPLE_ENABLE_VNDK=1",为libexample的扩展库定义了 "LIBEXAMPLE_ENABLE_VNDK=1" 和"LIBEXAMPLE_ENABLE_VNDK_EXT=1"。
cc_library {
name: "libexample",
srcs: ["src/example.c"],
vendor_available: true,
vndk: {
enabled: true,
},
target: {
vendor: {
cflags: ["-DLIBEXAMPLE_ENABLE_VNDK=1"],
},
},
}
cc_library {
name: "libexample_ext",
srcs: ["src/example.c"],
vendor: true,
vndk: {
enabled: true,
extends: "libexample",
},
cflags: [
"-DLIBEXAMPLE_ENABLE_VNDK=1",
"-DLIBEXAMPLE_ENABLE_VNDK_EXT=1",
],
}
VNDK 扩展
Android还提供了VNDK扩展的方法,就是使用自己修改的VNDK共享库来替换原始的VNDK共享库。因为供应商很可能根据自己的需求来更改AOSP库的源码,可能是为了提高性能,或者添加新钩子、新 API 或新功能。VNDK 扩展库会安装到 /vendor/lib[64]/vndk[-sp] 中,并在系统运行时会替换原始的 VNDK 共享库。
在 Android 9 及更高版本中,Android.bp 本身支持 VNDK 扩展。要编译 VNDK 扩展,请定义另一个具有 vendor:true 和 extends 属性的模块:
cc_library {
name: "libvndk",
vendor_available: true,
vndk: {
enabled: true,
},
}
cc_library {
name: "libvndk_ext",
vendor: true,
vndk: {
enabled: true,
extends: "libvndk",
},
}
具有 vendor:true、vndk.enabled:true 和 extends 属性的模块可定义 VNDK 扩展:
extends 属性必须指定基础 VNDK 共享库名称(或 VNDK-SP 共享库名称)。
VNDK 扩展(或 VNDK-SP 扩展)以扩展时所基于的基础模块名称命名。例如,libvndk_ext 的输出二进制文件是 libvndk.so,而非 libvndk_ext.so。
VNDK 扩展将安装到 /vendor/lib[64]/vndk 中。
VNDK-SP 扩展将安装到 /vendor/lib[64]/vndk-sp 中。
基础共享库必须同时具有 vndk.enabled:true 和 vendor_available:true。
VNDK-SP 扩展必须从 VNDK-SP 共享库进行扩展,就是说在定义时必须包含相同的vndk.support_system_process 。VNDK 扩展(或 VNDK-SP 扩展)也可以依赖于其他供应商共享库:
cc_library {
name: "libvndk_sp",
vendor_available: true,
vndk: {
enabled: true,
support_system_process: true,
},
}
cc_library {
name: "libvndk_sp_ext",
vendor: true,
vndk: {
enabled: true,
extends: "libvndk_sp",
support_system_process: true,
shared_libs: [
"libvendor",
],
}
cc_library {
name: "libvendor",
vendor: true,
}
如果供应商模块依赖于由 VNDK 扩展定义的其他 API,则该模块必须在其 shared_libs 属性中指定 VNDK 扩展的名称:
// A vendor shared library example
cc_library {
name: "libvendor",
vendor: true,
shared_libs: [
"libvndk_ext",
],
}
// A vendor executable example
cc_binary {
name: "vendor-example",
vendor: true,
shared_libs: [
"libvndk_ext",
],
}
如果供应商模块依赖于 VNDK 扩展,则这些 VNDK 扩展将自动安装到 /vendor/lib[64]/vndk[-sp] 中。如果某个模块不再依赖于 VNDK 扩展,请向 CleanSpec.mk 添加一个清理步骤,以移除共享库。例如:
$(call add-clean-step, rm -rf $(TARGET_OUT_VENDOR)/lib/libvndk.so)
规则和Sepolicy
VNDK 规则
完整的 VNDK 规则列表如下。
框架进程不得从供应商分区中加载非 SP-HAL 共享库(此规则从 Android 8.1 开始严格地强制实施)。
供应商进程不得从系统分区中加载非 LL-NDK 库、非 VNDK-SP 库和非 VNDK 库(Android O 中并未严格地强制实施此规则,但未来版本中会这么做)。
注意:要想从未来版本(比 Android 8.0 更高的版本)仅针对框架的 OTA 中受益,就不得在搭载 Android 8.0 出厂的设备中违反此规则。
已安装的 VNDK 库必须是由 Google 定义的合格 VNDK 库的子集。
SP-HAL 和 SP-HAL-Dep 的外部依赖项必须仅限于 LL-NDK 库或由 Google 定义的 VNDK-SP 库。
SP-HAL 共享库的依赖项必须仅限于 LL-NDK 库、由 Google 定义的 VNDK-SP 库、其他 SP-HAL 库和/或可标记为 SP-HAL-Dep 库的其他供应商共享库。
只有当供应商共享库不是 AOSP 库,且其依赖项仅限于 LL-NDK 库、由 Google 定义的 VNDK-SP 库、SP-HAL 库和/或其他 SP-HAL-Dep 库时,才可标记为 SP-HAL-Dep 库。
VNDK-SP 必须保持独立。在 Android 8.0 中,系统以一种特殊方式处理 libRS_internal.so,但在未来版本中,其处理方式会被重新考虑。
不得通过非 HIDL 接口(包括但不限于 Binder、套接字、共享内存、文件等)进行框架-供应商通信。
系统分区必须足够大,以便容纳所有符合条件的 VNDK 库的两个副本,以及不符合条件的框架共享库的一个副本。
sepolicy
本部分中介绍的框架进程对应于 sepolicy 中的 coredomain,而供应商进程对应于 non-coredomain。例如,/dev/binder 只能在 coredomain 中被访问,而 /dev/vndbinder 只能在非 coredomain 中被访问。
类似政策会限制对系统分区和供应商分区上的共享库的访问。下表列出了访问不同类别的共享库时所需的权限:
LL-NDK-Private 和 VNDK-SP-Private 必须从这两个域中都可访问,因为非 coredomain 会间接访问这些库。同样,SP-HAL-Dep 必须可从 coredomain 访问,因为 SP-HAL 依赖该域。
same_process_hal_file 标签
供应商分区中包含下面几个库。确保这些库既可以从 coredomain 访问,又可以从非 coredomain 访问。
VNDK-SP-Ext,位于 /vendor/lib[64]/vndk-sp
SP-HAL,位于 /vendor/lib[64] 或 /vendor/lib[64]/hw
SP-HAL-Dep,位于 /vendor/lib[64] 或 /vendor/lib[64]/hw
将这些文件明确标记为 same_process_hal_file。因为在默认情况下,从 coredomain 无法访问 vendor 分区中的任何内容。请向供应商特定的 file_contexts 文件中添加与以下命令行类似的命令行:
/vendor/lib(64)?/hw/libMySpHal\.so u:object_r:same_process_hal_file:s0
/vendor/lib(64)?/vndk-sp/libBase\.so u:object_r:same_process_hal_file:s0
/vendor/lib(64)?/libBaseInternal\.so u:object_r:same_process_hal_file:s0
参考文档:
Android Source: VNDK
以上就是Android VNDK使用及原理深入探究的详细内容,更多关于Android VNDK使用原理的资料请关注vb.net教程C#教程python教程SQL教程access 2010教程xin3721自学网