Android系统之VINTF(3)Matching Rules

由 adtxl 发布

两对兼容性矩阵和清单旨在 OTA 更新时进行协调,以验证框架和供应商实现是否可以相互协同工作。
This verification is done at build time, at OTA update package generation time, at boot time, and in VTS compatibility tests.
下面几部分将详细介绍各种组件使用的匹配规则。

1. Framework compatibility matrix version matches

如需使设备清单与框架兼容性矩阵相匹配,manifest.target-level 指定的 Shipping FCM 版本必须与 compatibility-matrix.level 指定的 FCM 版本完全相同。否则,这二者将不匹配。

如果使用 libvintf 请求框架兼容性矩阵,则此匹配始终都会成功,因为 libvintf 会打开设备清单,检索 Shipping FCM 版本,并返回该 Shipping FCM 版本的框架兼容性矩阵(以及更高 FCM 版本的兼容性矩阵中的一些可选 HAL)。

2. HAL 匹配

HAL 匹配规则可以识别清单文件中被视为受相应兼容性矩阵的所有者支持的 hal 元素的版本。

  • 多个 <hal> 元素具有 AND 关系。
  • 同一个 <hal> 中的多个 <version> 元素具有 OR 关系。如果指定了两个或两个以上版本,则只需要实现其中一个版本(请参见下面的 DRM 示例)。
  • 同一个 <hal> 中的多个 <instance><regex-instance> 元素具有 AND 关系(请参见下面的 DRM 示例)。

示例:相机模块的成功 HAL 匹配
对于 2.5 版的 HAL,匹配规则如下:

Matrix Matching Manifest
2.5 2.5-2.∞. In the compatibility matrix, 2.5 is the shorthand for 2.5-5.
2.5-7 2.5-2.∞. Indicates the following:
2.5 is the minimum required version, meaning a manifest providing HAL 2.0-2.4 isn't compatible.
2.7 is the maximum version that could be requested, meaning the owner of the compatibility matrix (framework or device) won't request versions beyond 2.7. The owner of the matching manifest can still serve version 2.10 (as an example) when 2.7 is requested. The compatibility-matrix owner knows only that the requested service is compatible with API version 2.7.
-7 is informational only and doesn't affect the OTA update process.
Thus, a device with a HAL at version 2.10 in its manifest file remains compatible with a framework that states 2.5-7 in its compatibility matrix.

示例:DRM 模块的成功 HAL 匹配
框架兼容性矩阵指明了 DRM HAL 的以下版本信息:

<hal>
    <name>android.hardware.drm
    <version>1.0</version>
    <version>3.1-2</version>
    <interface>
        <name>IDrmFactory</name>
        <instance>default</instance>
        <instance>specific</instance>
    </interface>
</hal>
<hal>
    <name>android.hardware.drm
    <version>2.0</version>
    <interface>
        <name>ICryptoFactory</name>
        <instance>default</instance>
        <regex-instance>[a-z]+/[0-9]+</regex-instance>
    </interface>
</hal>

供应商必须实现以下实例之一:

android.hardware.drm@1.x::IDrmFactory/default          // where x >= 0
android.hardware.drm@1.x::IDrmFactory/specific         // where x >= 0

android.hardware.drm@3.y::IDrmFactory/default          // where y >= 1
android.hardware.drm@3.y::IDrmFactory/specific         // where y >= 1

并且还必须实现以下所有实例(instances):

android.hardware.drm@2.z::ICryptoFactory/default       // where z >= 0
android.hardware.drm@2.z::ICryptoFactory/${INSTANCE}
            // where z >= 0 and ${INSTANCE} matches [a-z]+/[0-9]+
            // e.g. legacy/0

3. AIDL HALs

All Android versions later than Android 11 (excluding Android 11) supports versions for AIDL HALs in VINTF. The match rules for AIDL HALs are similar to those of HIDL and native HALs, except that there're no major versions, and there is exactly one version per HAL instance (1 if version is unspecified).

  • Multiple <hal> elements are evaluated with a single AND relationship.
  • Multiple <instance> and <regex-instance> elements within the same <hal> are evaluated with a single AND relationship. (See the vibrator example below.)

Example: Successful HAL match for a module
For a HAL at version 5, the match rule is as follows:

Matrix Matching Manifest
5 5-∞. In the compatibility matrix, 5 is the shorthand for 5-5.
5-7 5-∞. Indicates the following:
5 is the minimum required version, meaning a manifest providing HAL 1-4 isn't compatible.
7 is the maximum version that could be requested, meaning the owner of the compatibility matrix (framework or device) won't request versions beyond 7. The owner of the matching manifest can still serve version 10 (as an example) when 7 is requested. The compatibility-matrix owner knows only that the requested service is compatible with API version 7.
-7 is informational only and doesn't affect the OTA update process.
Thus, a device with a HAL at version 10 in its manifest file remains compatible with a framework that states 5-7 in its compatibility matrix.

Example: Successful HAL match for multiple modules
The framework compatibility matrix states the following version information for vibrator and camera HALs:

<hal>
    <name>android.hardware.vibrator
    <version>1-2</version>
    <interface>
        <name>IVibrator</name>
        <instance>default</instance>
        <instance>specific</instance>
    </interface>
</hal>
<hal>
    <name>android.hardware.camera
    <version>5</version>
    <interface>
        <name>ICamera</name>
        <instance>default</instance>
        <regex-instance>[a-z]+/[0-9]+</regex-instance>
    </interface>
</hal>

A vendor must implement all of these instances:

android.hardware.vibrator.IVibrator/default     // version >= 1
android.hardware.vibrator.IVibrator/specific    // version >= 1
android.hardware.camera.ICamera/default         // version >= 5
android.hardware.camera.ICamera/${INSTANCE}
            // with version >= 5, where ${INSTANCE} matches [a-z]+/[0-9]+
            // e.g. legacy/0

4. 内核匹配

The <kernel> section of the framework compatibility matrix describes the framework's requirements of the Linux kernel on the device. This information is meant to be matched against the information about the kernel that gets reported by the device's VINTF object.

4.1 Match kernel branches

Each kernel branch suffix (for example, 5.4-r) is mapped to a unique kernel FCM version (for example, 5). The mapping is the same as the mapping between release letters (for example, R) and FCM versions (for example, 5).

VTS tests enforce that the device explicitly specifies the kernel FCM version in the device manifest, /vendor/etc/vintf/manifest.xml, if one of the following is true:

  • The kernel FCM version is different from the target FCM version. For example, the aforementioned device has a target FCM version 4, and its kernel FCM version is 5 (kernel branch suffix r).
  • The kernel FCM version is greater than or equal to 5 (kernel branch suffix r).

Note: If the kernel FCM version equals the target FCM version and they are greater than or equal to 5, the source file of the device manifest specified by DEVICE_MANIFEST_FILE doesn't have to specify the kernel FCM version. assemble_vintf automatically infers the kernel FCM version from the target FCM version if the target FCM version is greater than or equal to 5.

VTS tests enforce that, if the kernel FCM version is specified, the kernel FCM version is greater than or equal to the target FCM version in the device manifest.

Example: Determine the kernel branch
If the device has target FCM version 4 (released in Android 10), but runs kernel from the 4.19-r branch, the device manifest should specify the following:

<manifest version="2.0" type="device" target-level="4">
   <kernel target-level="5" />
</manifest>

The VINTF object checks kernel compatibility against requirements on 4.19-r kernel branch, which is specified in FCM version 5. These requirements are built from kernel/configs/r/android-4.19 in the Android source tree.

4.2 Match kernel versions

A matrix can include multiple <kernel> sections, each with a different version attribute using the format:

${ver}.${major_rev}.${kernel_minor_rev}

The VINTF object considers only the <kernel> section from the FCM with matching FCM version with the same ${ver} and ${major_rev} as the device kernel (i.e., version="${ver}.${major_rev}.${matrix_minor_rev}"); other sections are ignored. In addition, the minor revision from the kernel must be a value from the compatibility matrix (${kernel_minor_rev} >= ${matrix_minor_rev};). If no <kernel> section meets these requirements, it's a non-match.

Example: Select requirements for matching
Consider the following hypothetical case where FCMs in /system/etc/vintf declare the following requirements (header and footer tags are omitted):

<!-- compatibility_matrix.3.xml -->
<kernel version="4.4.107" level="3"/>
<!-- See kernel/configs/p/android-4.4/ for 4.4-p requirements -->
<kernel version="4.9.84" level="3"/>
<!-- See kernel/configs/p/android-4.9/ for 4.9-p requirements -->
<kernel version="4.14.42" level="3"/>
<!-- See kernel/configs/p/android-4.14/ for 4.14-p requirements -->

<!-- compatibility_matrix.4.xml -->
<kernel version="4.9.165" level="4"/>
<!-- See kernel/configs/q/android-4.9/ for 4.9-q requirements -->
<kernel version="4.14.105" level="4"/>
<!-- See kernel/configs/q/android-4.14/ for 4.14-q requirements -->
<kernel version="4.19.42" level="4"/>
<!-- See kernel/configs/q/android-4.19/ for 4.19-q requirements -->

<!-- compatibility_matrix.5.xml -->
<kernel version="4.14.180" level="5"/>
<!-- See kernel/configs/r/android-4.14/ for 4.14-r requirements -->
<kernel version="4.19.123" level="5"/>
<!-- See kernel/configs/r/android-4.19/ for 4.19-r requirements -->
<kernel version="5.4.41" level="5"/>
<!-- See kernel/configs/r/android-5.4/ for 5.4-r requirements -->

The target FCM version, the kernel FCM version, and the kernel version together select the kernel requirements from the FCMs:

Target Kernel FCM Version Kernel version Match with
3 (P) unspecified 4.4.106 No match (minor version mismatch)
3 (P) unspecified 4.4.107 4.4-p
3 (P) unspecified 4.19.42 4.19-q (see note below)
3 (P) unspecified 5.4.41 5.4-r (see note below)
3 (P) 3 (P) 4.4.107 4.4-p
3 (P) 3 (P) 4.19.42 No match (no 4.19-p kernel branch)
3 (P) 4 (Q) 4.19.42 4.19-q
4 (Q) unspecified 4.4.107 No match (no 4.4-q kernel branch)
4 (Q) unspecified 4.9.165 4.9-q
4 (Q) unspecified 5.4.41 5.4-r (see note below)
4 (Q) 4 (Q) 4.9.165 4.9-q
4 (Q) 4 (Q) 5.4.41 No match (no 5.4-q kernel branch)
4 (Q) 5 (R) 4.14.105 4.14-r
4 (Q) 5 (R) 5.4.41 5.4-r
5 (R) unspecified any VTS fails (Must specify the kernel FCM version for the target FCM version 5)
5 (R) 4 (Q) any VTS fails (kernel FCM version < target FCM version)
5 (R) 5 (R) 4.14.180 4.14-r

Note: For devices with a target FCM version lower than 5 (R) and an unspecified kernel FCM version, the VINTF object selects the kernel branch with the lowest suffix that is greater than the target FCM version with the matching kernel version. In the above example, a device with a target FCM version of 3 (P) use the 4.19-q kernel branch because 4.19-q has the lowest suffix among all 4.19-* kernel branches, [4.19-q, 4.19-r, 4.19-s]. This requirement selection behavior is disallowed for devices with a target FCM version of 5 (R) or higher, because the kernel FCM version must be specified.

4.3 Match kernel configurations

If the <kernel> section does match, the process continues by attempting to match config elements against /proc/config.gz. For each config element in the compatibility matrix, it looks up /proc/config.gz to see if the config is present. When a config item is set to n in the compatibility matrix for the matching <kernel> section, it must be absent from /proc/config.gz. Finally, a config item not in the compatibility matrix may or may not be present in /proc/config.gz.

Example: Match kernel configurations

  • <value type="string">bar</value> matches "bar". Quotes are omitted in the compatibility matrix but present in /proc/config.gz.
  • <value type="int">4096</value> matches 4096 or 0x1000 or 0X1000.
  • <value type="int">0x1000</value> matches 4096 or 0x1000 or 0X1000.
  • <value type="int">0X1000</value> matches 4096 or 0x1000 or 0X1000.
  • <value type="tristate">y</value> matches y.
  • <value type="tristate">m</value> matches m.
  • <value type="tristate">n</value> means the config item must NOT exist in /proc/config.gz.
  • <value type="range">1-0x3</value> matches 1, 2, or 3, or hexadecimal equivalent.

Example: Successful kernel match
A framework compatibility matrix with FCM version 1 has the following kernel information:

<kernel version="4.14.42">
   <config>
      <key>CONFIG_TRI</key>
      <value type="tristate">y</value>
   </config>
   <config>
      <key>CONFIG_NOEXIST</key>
      <value type="tristate">n</value>
   </config>
   <config>
      <key>CONFIG_DEC</key>
      <value type="int">4096</value>
   </config>
   <config>
      <key>CONFIG_HEX</key>
      <value type="int">0XDEAD</value>
   </config>
   <config>
      <key>CONFIG_STR</key>
      <value type="string">str</value>
   </config>
   <config>
      <key>CONFIG_EMPTY</key>
      <value type="string"></value>
   </config>
</kernel>

The kernel branch is matched first. The kernel branch is specified in the device manifest in manifest.kernel.target-level, which defaults to manifest.level if the former is not specified. If the kernel branch in the device manifest:

  • is 1, proceeds to the next step and checks kernel version.
  • is 2, no match to matrix. VINTF objects reads kernel requirements from matrix at FCM version 2 instead.

Then, the kernel version is matched. If a device in uname() reports:

  • 4.9.84 (no match to matrix unless there's a separate kernel section with <kernel version="4.9.x">, where x <= 84)
  • 4.14.41 (no match to matrix, smaller than version)
  • 4.14.42 (match to matrix)
  • 4.14.43 (match to matrix)
  • 4.1.22 (no match to matrix unless there's a separate kernel section with <kernel version="4.1.x"> where x <= 22)

After the appropriate <kernel> section is selected, for each <config> item with value other than n, we expect the corresponding entry to be present in /proc/config.gz; for each <config> item with value n, we expect the corresponding entry to not be present in /proc/config.gz. We expect the content of <value> to exactly match the text after the equal sign (including quotes), up to the newline character or #, with leading and trailing whitespace truncated.

The following kernel configuration is an example of a successful match:

# comments don't matter
CONFIG_TRI=y
# CONFIG_NOEXIST shouldn't exist
CONFIG_DEC = 4096 # trailing comments and whitespaces are fine
CONFIG_HEX=57005  # 0XDEAD == 57005
CONFIG_STR="str"
CONFIG_EMPTY=""   # empty string must have quotes
CONFIG_EXTRA="extra config items are fine too"

The following kernel configuration is an example of an unsuccessful match:

CONFIG_TRI="y"   # mismatch: quotes
CONFIG_NOEXIST=y # mismatch: CONFIG_NOEXIST exists
CONFIG_HEX=0x0   # mismatch; value doesn't match
CONFIG_DEC=""    # mismatch; type mismatch (expect int)
CONFIG_EMPTY=1   # mismatch; expects ""
# mismatch: CONFIG_STR is missing

5. SE 策略匹配

SE 策略需要以下匹配:

  • <sepolicy-version> 定义了每个主要版本的次要版本的封闭范围。设备报告的 sepolicy 版本必须属于这些范围之一才能与框架兼容。匹配规则类似于 HAL 版本;如果 sepolicy 版本高于或等于范围内的最低版本,则匹配。最高版本仅供参考。
  • <kernel-sepolicy-version>(即 policydb 版本)必须低于设备报告的 security_policyvers()

示例:成功的 SE 策略匹配
框架兼容性矩阵指明了以下 sepolicy 信息:

<sepolicy>
    <kernel-sepolicy-version>30</kernel-sepolicy-version>
    <sepolicy-version>25.0</sepolicy-version>
    <sepolicy-version>26.0-3</sepolicy-version>
</sepolicy>

在设备上:

  • security_policyvers() 返回的值必须大于或等于 30。否则,不匹配。例如:

    • 如果设备返回 29,则不匹配。
    • 如果设备返回 31,则匹配。
  • SE 策略版本必须为 25.0-∞ 和 26.0-∞ 其中之一。否则,不匹配(“26.0”后面的“-3”仅供参考)。

6. AVB 版本匹配

AVB 版本包含 MAJOR 版本和 MINOR 版本,格式为 MAJOR.MINOR(例如 1.0 和 2.1)。有关详细信息,请参阅版本管理和兼容性。AVB 版本具有以下系统属性:

  • ro.boot.vbmeta.avb_version 是引导加载程序中的 libavb 版本
  • ro.boot.avb_version 是 Android 操作系统中的 libavb 版本 (init/fs_mgr)

仅当已使用对应的 libavb 验证 AVB 元数据(并且返回 OK)时,才会显示该系统属性。如果验证失败(或根本没有执行验证),则不会显示该系统属性。

兼容性匹配将比较以下内容:

  • sysprop ro.boot.vbmeta.avb_version 与框架兼容性矩阵中的 avb.vbmeta-version;
    • ro.boot.vbmeta.avb_version.MAJOR == avb.vbmeta-version.MAJOR
    • ro.boot.vbmeta.avb_version.MINOR >= avb.vbmeta-version.MINOR
  • sysprop ro.boot.avb_version 与框架兼容性矩阵中的 avb.vbmeta-version。
    • ro.boot.avb_version.MAJOR == avb.vbmeta-version.MAJOR
    • ro.boot.avb_version.MINOR >= avb.vbmeta-version.MINOR
      引导加载程序或 Android 操作系统可能包含 libavb 库的两个副本,每个副本具有不同的 MAJOR 版本,用于升级设备和启动设备。在这种情况下,可以共享同一个未签名的系统映像,但最终的签名系统映像则不同(具有不同的 avb.vbmeta-version):

下图为AVB 版本匹配(/system 为 P,其他所有分区均为 O)。
image.png

AVB 版本匹配(所有分区均为 P):
image96e9784274cb3d91.png

示例:成功的 AVB 版本匹配

框架兼容性矩阵指明了以下 AVB 信息:

<avb>
    <vbmeta-version>2.1</vbmeta-version>
</avb>

在设备上:

ro.boot.avb_version              == 1.0 &&
ro.boot.vbmeta.avb_version       == 2.1  mismatch
ro.boot.avb_version              == 2.1 &&
ro.boot.vbmeta.avb_version       == 3.0  mismatch
ro.boot.avb_version              == 2.1 &&
ro.boot.vbmeta.avb_version       == 2.3  match
ro.boot.avb_version              == 2.3 &&
ro.boot.vbmeta.avb_version       == 2.1  match

6.1 在 OTA 期间匹配 AVB 版本

对于搭载 Android 9 或更低版本的设备,在 OTA 期间,系统会将框架兼容性矩阵中的 AVB 版本要求与设备上的当前 AVB 版本进行匹配。如果 AVB 版本在 OTA 期间进行主要版本升级(例如,从 0.0 升级到 1.0),则 OTA 中的检查不会反映 OTA 之后的兼容性。

为了缓解这个问题,原始设备制造商 (OEM) 可以在 OTA 软件包 (compatibility.zip) 中放置一个假 AVB 版本来通过检查。为此,请执行以下操作:

  1. 择优挑选以下 CL 并将其添加到 Android 9 源代码树中:
    • CL 732261
    • CL 732262
  2. 为设备定义 BOARD_OTA_FRAMEWORK_VBMETA_VERSION_OVERRIDE。其值应该等于 OTA 之前的 AVB 版本,即设备启动时的 AVB 版本。
  3. 重新构建 OTA 软件包。

这些更改会自动将 BOARD_OTA_FRAMEWORK_VBMETA_VERSION_OVERRIDE 作为 compatibility-matrix.avb.vbmeta-version 放置在以下文件中:

  • 设备上的 /system/compatibility_matrix.xml(未在 Android 9 中使用)
  • OTA 软件包中 compatibility.zip 内的 system_matrix.xml

这些更改不会影响其他框架兼容性矩阵,包括 /system/etc/vintf/compatibility_matrix.xml。在 OTA 之后,/system/etc/vintf/compatibility_matrix.xml 中的新值将用于进行兼容性检查。

7. VNDK 版本匹配

设备兼容性矩阵在 compatibility-matrix.vendor-ndk.version 中声明所需的 VNDK 版本。如果设备兼容性矩阵没有 <vendor-ndk> 标记,则系统不会实施任何要求,因此始终将其视为匹配项。

如果设备兼容性矩阵具有 <vendor-ndk> 标记,则系统会从框架在框架清单中提供的 VNDK 供应商快照集中查找具有匹配 <version><vendor-ndk> 条目。如果不存在此类条目,则没有匹配项。

如果确实存在此类条目,则设备兼容性矩阵中枚举的库集必须是框架清单中声明的一组库的子集;否则,系统不会将此类条目视为匹配项。

- 一种特殊情况是,如果设备兼容性矩阵中未枚举任何库,则系统会始终将该条目视为匹配项,因为空集是任何集的子集。

示例:成功的 VNDK 版本匹配

如果设备兼容性矩阵在 VNDK 上声明了以下要求:

<!-- Example Device Compatibility Matrix -->
<vendor-ndk>
    <version>27</version>
    <library>libjpeg.so</library>
    <library>libbase.so</library>
</vendor-ndk>
在框架清单中,系统仅会考虑具有版本 27 的条目。


<!-- Framework Manifest Example A -->
<vendor-ndk>
    <version>27</version>
    <library>libjpeg.so</library>
    <library>libbase.so</library>
    <library>libfoo.so</library>
</vendor-ndk>

示例 A 是匹配项,因为 VNDK 版本 27 在框架清单中,并且 {libjpeg.so, libbase.so, libfoo.so} ⊇ {libjpeg.so, libbase.so}。

<!-- Framework Manifest Example B -->
<vendor-ndk>
    <version>26</version>
    <library>libjpeg.so</library>
    <library>libbase.so</library>
</vendor-ndk>
<vendor-ndk>
    <version>27</version>
    <library>libbase.so</library>
</vendor-ndk>

示例 B 不是匹配项。即使 VNDK 版本 27 在框架清单中,该快照中的框架也不支持 libjpeg.so。VNDK 版本 26 将被忽略。

8. 系统 SDK 版本匹配

设备兼容性矩阵在 compatibility-matrix.system-sdk.version 中声明一组所需的系统 SDK 版本。只有当该集合是所提供的系统 SDK 版本(在框架清单的 manifest.system-sdk.version 中声明)的子集时,才存在匹配项。

一种特殊情况是,如果设备兼容性矩阵中未枚举任何系统 SDK 版本,则系统会始终将该条目视为匹配项,因为空集是任何集的子集。
示例:成功的系统 SDK 版本匹配
如果设备兼容性矩阵在系统 SDK 上声明了以下要求:

<!-- Example Device Compatibility Matrix -->
<system-sdk>
    <version>26</version>
    <version>27</version>
</system-sdk>

然后,框架必须提供系统 SDK 版本 26 和 27 才能匹配。

<!-- Framework Manifest Example A -->
<system-sdk>
    <version>26</version>
    <version>27</version>
</system-sdk>

示例 A 是匹配项。

<!-- Framework Manifest Example B -->
<system-sdk>
    <version>26</version>
    <version>27</version>
    <version>28</version>
</system-sdk>

示例 B 是匹配项。

<!-- Framework Manifest Example C -->
<system-sdk>
    <version>26</version>
</system-sdk>

示例 C 不是匹配项,因为未提供系统 SDK 版本 27。


暂无评论

发表评论