Android 共享系統映像

本頁介紹了 Android 裝置 OEM 可以用來跨產品線擁有自己的共享系統映像 (SSI) 的幾種機制。它還提出了一種將 OEM 擁有的 SSI 基於 AOSP 構建的通用系統映像 (GSI) 的程式。

背景

Project Treble中,整體 Android 被分為兩部分:特定於硬體的部分(供應商實作)和通用作業系統部分(Android 作業系統框架)。每個軟體都安裝在單獨的分區中:供應商分區用於特定於硬體的軟體,系統分區用於通用作業系統軟體。稱為供應商介面 ( VINTF ) 的版本化介面是在兩個分區之間定義和強制執行的。透過使用此分區系統,您可以修改系統分區而不修改供應商分區,反之亦然。

動機

AOSP 中發布的框架程式碼符合 Treble 架構,並保持了與舊供應商實現的向後相容性。例如,從 Android 10 AOSP 來源建置的通用系統映像可以在運行 Android 8 或更高版本的任何相容 Treble 的裝置上運行。消費性裝置上搭載的 Android 版本由 SoC 供應商和 OEM 進行修改。 (請參閱Android 版本的生命週期。)對框架所做的這些更改和擴展並不是為了保持向後相容性,這意味著作業系統升級的複雜性和成本更高。特定於裝置的變更和修改增加了升級 Android 作業系統版本的成本和複雜性。

在 Android 11 之前,沒有明確的架構可以讓合作夥伴建構 Android 作業系統框架的模組化擴充。本文檔介紹了 SoC 供應商和 OEM 可以採取的建立 SSI 的步驟。這意味著從 Android 作業系統框架來源建立的映像可以在多個裝置上重複使用,保持與供應商實現的向後相容性,並顯著降低 Android 作業系統升級的複雜性和成本。有關建立 SSI 所需的具體步驟,請參閱基於 GSI 的 SSI 的建議步驟部分,並注意您不必使用所有四個步驟。您選擇哪些步驟(例如,僅步驟 1)取決於您的實作。

SSI概述

透過 SSI,特定於產品的軟體元件和 OEM 擴充被放置在新的/product分區中。 /product分區中的元件使用定義良好、穩定的介面與/system分區中的元件互動。 OEM 可以選擇建立一個 SSI,也可以選擇擁有少量 SSI 以在多個裝置 SKU 中使用。當新版本的 Android 作業系統發佈時,OE​​M只需投資一次即可將其 SSI 更新到最新的 Android 版本。他們可以重複使用 SSI 來更新多個設備,而無需更新/product分區。

請注意,OEM 和 SoC 供應商建置的 SSI 包含 OEM 所需的所有自訂功能和修改。本頁提供的機制和最佳實務旨在供 OEM 用來實現以下關鍵目標:

  • 跨多個裝置 SKU 重複使用 SSI。
  • 透過模組化擴充更新Android系統,讓作業系統升級更加容易。

將特定於產品的組件分離到產品分區中的核心思想類似於將特定於 SoC 的組件分離到供應商分區中的 Treble 思想。產品介面(類似於VINTF )允許 SSI 和產品分區之間進行通訊。請注意,對於 SSI,術語「元件」描述了安裝到映像的所有資源、二進位檔案、文字、庫等,這些資源本質上成為分區。

圍繞 SSI 進行分區

圖 1 顯示了 SSI 周圍的分區、跨分區的版本化介面以及介面上的策略。本節詳細解釋每個分區和介面。

Partitions and interfaces around SSI block diagram

圖 1. SSI 周圍的分區和介面

鏡像和分區

本節中的資訊區分術語「映像」「分區」

  • 影像是一個可以獨立更新的概念性軟體。
  • 分區是可以獨立更新的實體儲存位置。

圖 1 中的各部分定義如下:

  • SSI: SSI是 OEM 通用的映像,可以跨多個裝置存在。它沒有任何特定於硬體或特定於產品的組件。根據定義,給定 SSI 中的所有內容都在使用該 SSI 的所有裝置之間共用。 SSI 由單一/system映像或/system/system_ext分區組成,如圖 1 所示。

    • /system分區包含基於 AOSP 的元件,而/system_ext在實作時包含 OEM 和 SoC 供應商擴充以及與 AOSP 元件緊密耦合的元件。例如,為 OEM 自己的應用程式提供自訂 API 的 OEM Java 框架庫更適合放在/system_ext中,而不是放在/system分區中。 /system/system_ext分區的內容都是根據 OEM 修改的 Android 來源建構的。

    • /system_ext分區是可選的,但將其用於與基於 AOSP 的組件緊密耦合的任何自訂功能和擴展是有益的。這種差異可以幫助您確定需要進行的更改,以便在一段時間內將此類元件從/system_ext分區移至/product分區。

  • 產品:特定於產品或裝置的元件的集合,代表 OEM 對 Android 作業系統的客製化和擴充。將 SoC 特定組件放在/vendor分區。 SoC 供應商也可以將/product分區用於適當的組件,例如獨立於 SoC 的組件。例如,如果 SoC 供應商向其 OEM 客戶提供獨立於 SoC 的組件(可以選擇隨產品一起提供),則 SoC 供應商可以將該組件放置在產品映像中。組件的位置不是由其所有權決定的,而是由其用途決定的。

  • 供應商:SoC 特定組件的集合。

  • ODM: SoC 未提供的特定於板的組件的集合。通常,SoC 供應商擁有供應商映像,而設備製造商擁有 ODM 映像。當沒有單獨的/odm分割區時,SoC 供應商和 ODM 映像都會合併到/vendor分割區中。

影像之間的介面

SSI 周圍存在兩個用於供應商和產品映像的主要介面:

  • 供應商介面 (VINTF) :VINTF 是駐留在供應商和 ODM 映像中的元件的介面。產品和系統映像中的元件只能透過此介面與供應商和 ODM 映像進行互動。例如,供應商映像不能依賴系統映像的私有部分,反之亦然。這最初是在 Project Treble 中定義的,它將映像分為系統分區和供應商分區。此介面使用以下機制進行說明:

    • HIDL (直通 HAL 僅適用於systemsystem_ext模組)
    • 穩定的AIDL
    • 配置
      • 系統屬性API
      • 設定檔架構 API
    • 越南國家發展局
    • Android SDK API
    • Java SDK 函式庫
  • 產品介面:產品介面是SSI 和產品影像之間的介面。定義穩定的介面可以將 SSI 中的產品元件與系統元件解耦。產品介面需要與VINTF相同的穩定介面。但是,對於使用 Android 11(及更高版本)啟動的設備,僅強制使用 VNDK 和 Android SDK API。

在 Android 11 中啟用 SSI

本部分介紹如何使用 Android 11 中的新功能來支援 SSI。

/system_ext 分區

/system_ext分區是在 Android 11 中作為可選分區引入的。 (這是與/system分區中 AOSP 定義的組件緊密耦合的非 AOSP 組件所在的位置。) /system_ext分區被假定為/system分區的 OEM 特定擴展,沒有跨系統定義的介面。兩個分區。 /system_ext分區中的元件可以對/system分區進行私有 API 呼叫,而/system分區中的元件可以對/system_ext分區進行私有 API 呼叫。

由於這兩個分區緊密耦合,因此當新的 Android 版本發佈時,兩個分區都會一起升級。為先前版本的 Android 建立的/system_ext分區不需要與下一個 Android 版本中的/system分區相容。

若要將模組安裝到/system_ext分區,請將system_ext_specific: true加入Android.bp檔案。對於沒有/system_ext分區的設備,請將此類模組安裝到/system分區中的./system_ext子目錄。

歷史

以下是有關/system_ext分區的一些歷史記錄。設計目標是將所有 OEM 特定元件(無論它們是否通用)放置在/product分區中。然而,一次性移動它們是不可行的,特別是當某些組件與/system分區緊密耦合時。若要將緊密耦合的元件移至/product分區,必須擴充產品介面。這往往需要對組件本身進行廣泛的重構,這會消耗大量的時間和精力。 /system_ext分區最初是作為臨時託管那些尚未準備好移至/product分區的組件的位置。 SSI 的目標是最終消除/system_ext分區。

但是, /system_ext分區對於使/system分區盡可能靠近 AOSP 非常有用。對於 SSI,大部分升級工作都花在/system/system_ext分區中的元件上。當系統映像是盡可能從與 AOSP 相似的來源建置時,您可以將升級工作重點放在system_ext映像上。

將元件從/system/system_ext分區解綁到/product分區

Android 9 引進了與/system分區結合的/product分區/product分區中的模組不受任何限制地使用系統資源,反之亦然。為了讓 SSI 在 Android 10 中成為可能,產品元件被分成/system_ext/product分區。 /system_ext分區不必遵守 Android 9 中/product分區對使用系統組件的限制。從 Android 10 開始, /product分區必須從/system分區解綁,並且必須使用來自/system 10 的穩定介面。/system和/system_ext分區。

/system_ext分區的主要目的是擴展系統功能,而不是安裝捆綁的產品模組,如/system_ext partition部分所述。為此,請解綁特定於產品的模組並將它們移至/product分區。分拆特定於產品的模組使得/system_ext對於設備來說是通用的。 (有關更多詳細信息,請參閱使 /system_ext 分區公用。)

若要從系統元件中取消捆綁/product分區, /product分區必須與已與 Project Treble 取消捆綁的/vendor分區具有相同的強制策略。

從 Android 11 開始, /product分區的本機和 Java 介面將如下所述強制實施。有關更多信息,請參閱強制執行產品分區接口

  • 本機介面/product分區中的本機模組必須與其他分區分開。產品模組唯一允許的依賴項是/system分區中的一些 VNDK 庫(包括 LLNDK)。產品應用依賴的JNI函式庫必須是NDK函式庫。
  • Java 介面/product分區中的 Java(應用程式)模組不能使用隱藏的 API,因為它們不穩定。這些模組只能使用/system分區中的公用 API 和系統 API,以及/system/system_ext分區中的 Java SDK 函式庫。您可以為自訂 API 定義Java SDK 函式庫

基於 GSI 的 SSI 的建議步驟

Suggested partitions for GSI-based SSI

圖 2.基於 GSI 的 SSI 的建議分區

通用系統映像 (GSI) 是直接從 AOSP 建置的系統映像。它用於Treble 合規性測試(例如,CTS-on-GSI),並作為參考平台,應用程式開發人員在沒有運行所需Android 版本的真實設備時可以使用該平台來測試其應用程式的兼容性。

OEM 也可以使用 GSI 來製作他們的 SSI。如映像和分區所述,SSI 由 AOSP 定義的元件的系統映像和 OEM 定義的元件的system_ext映像組成。當使用GSI作為system鏡像時,OEM可以專注於system_ext鏡像進行升級。

本部分為希望在使用 AOSP 或近 AOSP 系統映像時將其自訂模組化至/system_ext/product分區的 OEM 提供指南。如果 OEM 從 AOSP 來源建立系統映像,那麼他們可以用 AOSP 提供的 GSI 替換他們建立的系統映像。然而,OEM 不需要一次完成最後一步(使用 GSI)。

步驟1.繼承OEM的系統映像(OEM GSI)的generic_system.mk

透過繼承generic_system.mk (在Android 11中命名為mainline_system.mk ,在AOSP中重新命名為generic_system.mk ),系統映像(OEM GSI)包含了AOSP GSI擁有的所有檔案。 OEM 可以修改這些文件,以便 OEM GSI 除了 AOSP GSI 文件之外還可以包含 OEM 專有文件。但是,OEM 不允許修改generic_system.mk檔案本身。

Inheriting `generic_system.mk` for OEM system image

圖 3.繼承 OEM 系統映像的generic_system.mk

步驟 2. 使 OEM GSI 與 AOSP GSI 具有相同的文件列表

OEM GSI 在此階段不能有其他文件。 OEM 的專有檔案必須移出到system_extproduct分區。

Moving added files out of the OEM GSI

圖 4.將新增的檔案移出 OEM GSI

步驟 3. 定義允許清單以限制 OEM GSI 中的修改文件

若要檢查已修改的文件,OEM 可以使用compare_images工具,並將AOSP GSI 與OEM GSI 進行比較。從 AOSP 午餐目標generic_system_*取得 AOSP GSI。

透過使用allowlist參數定期執行compare_images工具,您可以監控白名單以外的差異。這樣就無需對 OEM GSI 進行額外修改。

Define an allowlist to reduce the list of modified files in OEM GSI

圖 5.定義允許列表以減少 OEM GSI 中的修改文件列表

步驟 4. 使 OEM GSI 具有與 AOSP GSI 相同的二進位文件

清理白名單允許 OEM 使用 AOSP GSI 作為自己產品的系統映像。要清理允許列表,OEM 可以放棄 OEM GSI 中的更改,或將其更改上游到 AOSP,以便 AOSP GSI 包含其更改。

Make OEM GSI have the same binaries as AOSP GSI

圖 6.使 OEM GSI 具有與 AOSP GSI 相同的二進位文件

為 OEM 定義 SSI

在建置時保護 /system 分區

為了避免/system分區中任何特定於產品的變更並定義 OEM GSI,OEM 可以使用名為require-artifacts-in-path的 makefile 巨集來防止在呼叫該巨集後聲明任何系統模組。請參閱建立 makefile 並啟用工件路徑檢查範例

OEM 可以定義一個列表,以允許將特定於產品的模組暫時安裝在/system分區中。但是,該清單必須為空,以使 OEM GSI 對於所有 OEM 產品都是通用的。此流程用於定義 OEM GSI,並且可以獨立於AOSP GSI 的步驟

強制執行產品介面

為了確保/product分區是解綁定的,OEM 可以透過設定PRODUCT_PRODUCT_VNDK_VERSION:= current (對於本機模組)和PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE:= true對於 Java 模組)來確保其設備強制執行產品介面。如果設備的PRODUCT_SHIPPING_API_LEVEL大於或等於30 ,則會自動設定這些變數。有關詳細信息,請參閱強制執行產品分區介面

使/system_ext分區公用

/system_ext分區可能因設備而異,因為它可以具有特定於設備的系統捆綁模組。由於 SSI 由/system/system_ext分區組成,因此/system_ext分區的差異阻礙了 OEM 定義 SSI。 OEM 可以擁有自己的 SSI,並且可以透過消除任何差異並使/system_ext分區公用來在多個裝置之間共用該 SSI。

本節提供了使/system_ext分區公用的建議。

暴露系統分割區中隱藏的API

許多產品特定應用程式無法安裝在產品分割區中,因為它們使用隱藏的 API,而這些 API 在產品分割區中是被禁止的。若要將裝置特定的應用程式移至產品分割區,請刪除隱藏 API 的使用。

從應用程式中刪除隱藏 API 的首選方法是找到替代的公共或系統 API 來取代它們。如果沒有 API 來取代隱藏的 API,OEM 可以向 AOSP 做出貢獻,為其設備定義新的系統 API。

或者,OEM 可以透過在/system_ext分區中建立自己的Java SDK 庫來定義自訂 API。它可以使用系統分割區中的隱藏API,並且可以向​​產品或供應商分割區中的應用程式提供API。 OEM 必須凍結產品導向的 API以實現向後相容性。

包含所有 APK 的超集並跳過每個設備的一些軟體包安裝

與系統捆綁在一起的某些軟體包在不同設備上並不常見。解綁這些 APK 模組以將其移至產品或供應商分區可能很困難。作為臨時解決方案,OEM 可以讓 SSI 包含所有模組,然後使用 SKU 屬性 ( ro.boot.hardware.sku ) 過濾掉不需要的模組。若要使用篩選器,OEM 會覆寫框架資源config_disableApkUnlessMatchedSku_skus_listconfig_disableApksUnlessMatchedSku_apk_list

為了更精確的設置,聲明一個廣播接收器來停用不必要的包。廣播接收器在收到ACTION_BOOT_COMPLETED訊息時呼叫setApplicationEnabledSetting來停用該套件。

定義 RRO 而不是使用靜態資源覆蓋

靜態資源覆蓋操作覆蓋的包。但是,它可能會妨礙定義 SSI,因此請確保 RRO 的屬性已開啟並正確設定。透過如下設定屬性,OEM 可以將所有自動產生的覆蓋作為 RRO。

PRODUCT_ENFORCE_RRO_TARGETS := *
PRODUCT_ENFORCE_RRO_EXCLUDED_OVERLAYS := # leave it empty

如果需要詳細配置,請手動定義 RRO,而不是依賴自動產生的 RRO。有關詳細信息,請參閱運行時資源覆蓋 (RRO) 。 OEM 也可以使用android:requiredSystemPropertyNameandroid:requiredSystemPropertyValue屬性定義依賴系統屬性的條件 RRO。

常見問題 (FAQ)

我可以定義多個 SSI 嗎?

這取決於設備(或設備組)的共通性和特性。 OEM 可以嘗試使system_ext分區公用,如使 system_ext 分區公用中所述。如果設備組有很多差異,那麼最好定義多個 SSI。

我可以修改 OEM GSI 的generic_system.mk ( mainline_system.mk ) 嗎?

不會。但 OEM 可以為繼承generic_system.mk檔案的 OEM GSI 定義一個新的 makefile,並改用新的 makefile。有關範例,請參閱強制執行產品分區介面

我可以從generic_system.mk中刪除與我的實作衝突的模組嗎?

不會。GSI 具有最少的可啟動和可測試模組集。如果您認為某個模組不是必需的,請提交錯誤以更新 AOSP 中的generic_system.mk檔案。