blob: 45c8adc278994ea15f43091de80be8b54af589f4 [file] [log] [blame]
<html devsite><head>
<title>VNDK 快照设计</title>
<meta name="project_path" value="/_project.yaml"/>
<meta name="book_path" value="/_book.yaml"/>
</head>
<body>
<!--
Copyright 2018 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<p>
系统映像可以使用 VNDK 快照为供应商映像提供正确的 VNDK 库,即使系统映像和供应商映像是基于不同版本的 Android 编译的也是如此。创建 VNDK 快照需要以快照形式捕获 VNDK 库,并使用版本号标记它们。供应商映像可以与特定的 VNDK 版本相关联,由此版本为供应商映像中的模块提供所需 ABI。不过,在同一 VNDK 版本内,VNDK 库必须具有<a href="/devices/architecture/hidl/hashing#abi-stability">稳定的 ABI</a>
</p>
<p>
VNDK 快照设计包括用于执行以下两项操作的方法:从当前系统映像<a href="/devices/architecture/vndk/snapshot-generate.html">生成预编译的 VNDK 快照</a><a href="/devices/architecture/vndk/snapshot-generate.html#install-vndk-snapshot">将这些预编译的库安装</a>到更高 Android 版本的系统分区。
</p>
<h2 id="about-vndk-libs">VNDK 库简介</h2>
<p>
Android 8.0 中引入的 <a href="/devices/architecture/index.html#hidl">HIDL-HAL</a> 支持单独升级系统分区和供应商分区。VNDK 定义了可与供应商代码相关联的库集(VNDK-core、VNDK-SP 和 LL-NDK),并阻止供应商使用不在 VNDK 集内的库。因此,如果将系统映像上合适的 VNDK 集提供给供应商映像,则可以编译并运行供应商映像。
</p>
<aside class="note"><strong>注意</strong>:有关这些库的详细信息,请参阅 <a href="/devices/architecture/vndk/index.html#concepts">VNDK 概念</a>
</aside>
<h3 id="vndk-core">VNDK-core</h3>
<p>
VNDK-core 库集安装在 <code>/system/lib[64]/vndk-${VER}</code> 中,<strong></strong>适用于 API 级别为 <code>${VER}</code> 的供应商进程。系统进程不得使用这些库,而必须使用安装在 <code>/system/lib[64]</code> 中的库。由于每个进程都具有严格的命名空间限制,因此不会造成重复加载 VNDK-core 库。
</p>
<p>要在 VNDK-core 中添加库,请将以下内容添加到 <code>Android.bp</code> 中:
</p>
<pre class="prettyprint">
vendor_available: true,
vndk: {
enabled: true,
},
</pre>
<aside class="note"><strong>注意</strong>:如果系统进程从 <code>system/lib</code> 加载库 <code>foo.so</code>,并从 <code>system/lib/vndk</code> 加载另一个 <code>foo.so</code>,这种情况就属于重复加载 <code>foo.so</code>。通常,在一个进程中两次加载同一个库是不安全的。
</aside>
<h3 id="vndk-sp">VNDK-SP</h3>
<p>
VNDK-SP 库安装在 <code>/system/lib[64]/vndk-sp-${VER}</code> 中,适用于供应商进程和系统进程(通过安装在供应商分区中的 SP-HAL 库)。VNDK-SP 库可以重复加载。
</p>
<p>
要在 VNDK-SP 中添加库,请将以下内容添加到 <code>Android.bp</code> 中:
</p>
<pre class="prettyprint">
vendor_available: true,
vndk: {
enabled: true,
support_system_process: true,
},
</pre>
<h3 id="ll-ndk">LL-NDK</h3>
<p>
LL-NDK 库安装在 <code>/system/lib[64]</code> 中。供应商模块可以使用 LL-NDK 存根库访问 LL-NDK 库的预选符号。LL-NDK 库必须支持向后兼容且具有 ABI 稳定性,以便旧版供应商模块使用新版 LL-NDK 库。由于 LL-NDK 具有 ABI 稳定特性,VNDK 快照无需包含旧版供应商映像的 LL-NDK 库。
</p>
<h2 id="about-vndk-snapshots">VNDK 快照简介</h2>
<p>
Android 8.1 包含<a href="/devices/architecture/vndk/build-system">根据源代码编译的 VNDK 库</a>。不过,对于更高版本的 Android,必须以快照形式捕获每个 VNDK 版本,并作为预编译版本提供,以便关联到较旧版本的供应商映像。
</p>
<p>
从 Android 9 开始,新版 Android 将在 Android 源代码中包含较低版本 Android 的 VNDK-core 和 VNDK-SP 目录的至少一个快照。编译时,所需快照将安装到 <code>/system/lib[64]/vndk-${VER}</code><code>/system/lib[64]/vndk-sp-${VER}</code>(供应商分区可以使用的目录),其中 <code>${VER}</code> 是表示 VNDK 快照版本名称的字符串变量。
</p>
<p>
由于每个 VNDK 版本的 VNDK 快照库可能各不相同,因此 VNDK 快照还包含按以下格式安装的链接器命名空间配置:<code>etc/ld.config.${VER}.txt</code><code>/etc/llndk.libraries.${VER}.txt</code><code>/etc/vndksp.libraries.${VER}.txt</code>
</p>
<h3 id="example-upgrade-system-vendor">示例:升级系统映像和供应商映像</h3>
<p>
无需快照;无需针对 VNDK 快照进行其他配置即可编译。
</p>
<h3 id="example-upgrade-system-only">示例:仅升级系统映像</h3>
<p>
必须在系统映像中包含供应商映像的 VNDK 快照和链接器命名空间配置文件。系统会自动配置链接器命名空间配置文件,以在 <code>/system/lib[64]/vndk-${VER}</code><code>/system/lib[64]/vndk-sp-${VER}</code> 中搜索 VNDK 库。
</p>
<img src="/devices/architecture/images/vndk_snapshot_system_only.png"/>
<figcaption><strong>图 1.</strong> 仅升级系统映像</figcaption>
<h3 id="example-upgrade-system-minor-vendor">示例:升级系统映像,少量更改供应商映像</h3>
<p>
根据 VNDK 快照编译供应商映像尚不受支持,因此您必须使用原始源代码单独编译供应商映像,然后按上一示例中所述升级系统映像。
</p>
<h2 id="vndk-snapshot-arch">VNDK 快照架构</h2>
<p>
要使 Android 9 系统映像与 Android 8.1 供应商映像兼容,必须为 Android 9 系统映像提供与 Android 8.1 供应商映像匹配的 VNDK 快照,如下所示:</p>
<img src="/devices/architecture/images/vndk_snapshot_arch.png"/>
<figcaption><strong>图 2.</strong> VNDK 快照架构</figcaption>
<p>VNDK 快照设计包括以下方法:</p>
<ul>
<li><strong>为 VNDK-core 和 VNDK-SP 库生成快照</strong>。Android 9 包含一个脚本,您可以使用它来制作当前 VNDK 版本的快照。此脚本将 <code>/system/lib[64]/vndk-28</code><code>/system/lib[64]/vndk-sp-28</code> 中的所有库组合在一起,这些库是采用当前源代码以 VNDK 快照形式编译的,其中 <code>28</code> 是 Android 9 的 VNDK 版本。快照还包含链接器命名空间配置文件 <code>/etc/ld.config.28.txt</code><code>/etc/llndk.libraries.28.txt</code><code>/etc/vndksp.libraries.28.txt</code>。生成的快照将用于较新的 Android 版本(高于 Android 9 的版本)。
</li>
<li><strong>从快照安装预编译的 VNDK-core 和 VNDK-SP 库</strong>。在 Android 9 中,VNDK 快照具有一组预编译的 VNDK-core 库和一组 VNDK-SP 库,以及链接器命名空间配置文件。如果您提供了要安装的 VNDK 快照版本列表,系统映像会在编译时将 VNDK 快照库安装到 <code>/system/lib[64]/vndk-${VER}</code><code>/system/lib[64]/vndk-sp-${VER}</code> 目录,并将这些 VNDK 快照的链接器命名空间配置文件安装到 <code>/etc</code> 目录。</li>
</ul>
<h3 id="vndk-versioning">VNDK 版本控制</h3>
<p>
每个 Android 版本都只有一个 VNDK 快照,并且 SDK 版本用作 VNDK 版本(这意味着 VNDK 版本必须采用整数,例如 Android 8.1 的 VNDK 版本为 27)。Android 版本发布时,VNDK 版本已确定。供应商分区使用的 VNDK 版本自动存储在 <code>ro.vndk.version</code> 属性中,可在运行时读取。然后,此版本用于识别一些库的供应商 VNDK 版本及命名空间配置的 VNDK 快照版本。
</p>
<h3 id="build-vndk-libs">编译 VNDK 库</h3>
<p>
<code>make vndk</code> 命令可用于编译具有 <code>vndk:
{ enabled: true, … }</code> 的库,包括依赖项和命名空间配置文件。如果设置了 <code>BOARD_VNDK_VERSION := current</code>,则可使用 <code>make</code> 命令编译这些库。
</p><p>
</p><p>
由于这种编译方法不会从快照安装 VNDK 库,安装的 VNDK 库不具有 ABI 稳定性。不过,Android 版本发布时,当前 VNDK 版本的 ABI 已确定。此时,任何 ABI 损坏都属于编译错误,因此 Android 版本的补丁程序不得更改 VNDK 库的 ABI。
</p>
</body></html>