在 Android 12 實現 Bootconfig

在 Android 12 中,bootconfig 功能取代了 Android 11 及更低版本中使用的androidboot.*核心命令列選項。 bootconfig 功能是一種將設定詳細資訊從建置和開機載入程式傳遞到 Android 12 的機制。

此功能提供了一種將 Android 使用者空間的配置參數與核心的配置參數分開的方法。將冗長的androidboot.*核心參數移至 bootconfig 檔案會在核心命令列上建立空間,並使其可用於將來輕鬆擴展。

核心和 Android 用戶空間都必須支援bootconfig

  • 第一款支援此功能的版本:Android 12
  • 第一個支援此功能的內核版本:12-5.4.xx 內核

為使用 12-5.10.xx 核心版本啟動的裝置實作 bootconfig 功能。如果您要升級設備,則無需實施它。

範例和來源

當您查看本節中的範例和原始程式碼時,請注意bootconfig程式碼的格式與 Android 11 及更低版本中使用的核心命令列的格式僅略有不同。但是,以下差異對於您的使用很重要:

  • 參數必須由換行符轉義序列\n分隔,而不是空格。

引導程式範例

有關引導程式範例,請參閱 Cuttlefish U-boot 參考引導程式實作。下面列出了參考中的兩個提交。第一個將啟動標頭版本支援升級到最新版本。在範例中,第一個提交將版本支援更新(或升級)到下一個版本 v4。第二個有兩件事;它添加了 bootconfig 處理,並演示了在運行時添加參數:

建構範例

有關顯示mkbootimg變更以使用供應商引導標頭 v4 建置vendor_boot.img建置範例,請參閱mkbootimg changes for bootconfig 。請參閱 Cuttlefish 變更以執行以下操作:

執行

合作夥伴必須添加對其引導程式的支持,並將其建置時androidboot.*參數從核心命令列移至 bootconfig 檔案。實施這項變革的最佳方式是逐步實施;有關遵循增量過程的信息,請參閱增量實施和驗證部分。

如果您進行了在 /proc/cmdline 檔案中搜尋androidboot.*參數的更改,請將它們指向 /proc/bootconfig 檔案。 ro.boot.*屬性是使用新的bootconfig值設定的,因此您無需使用這些屬性對程式碼進行更改。

建構變更

首先,將啟動標頭版本升級至版本 4:

- BOARD_BOOT_HEADER_VERSION := 3

+ BOARD_BOOT_HEADER_VERSION := 4

新增bootconfig核心命令列參數。這使得核心查找 bootconfig 部分:

BOARD_KERNEL_CMDLINE += bootconfig

bootconfig 參數是根據BOARD_BOOTCONFIG變數中的參數建立的,就像核心命令列是從BOARD\_KERNEL\_CMDLINE建立的一樣。

任何androidboot.*參數都可以原樣移動,類似於以下內容:

- BOARD_KERNEL_CMDLINE += androidboot..selinux=enforcing

+ BOARD_BOOTCONFIG += androidboot..selinux=enforcing

引導程式的變化

引導程式在跳到核心之前設定initramfs核心引導配置搜尋 bootconfig 部分,並尋找它位於initramfs,以及預期的預告片。

引導程式從供應商引導映像標頭取得vendor_boot.img佈局資訊。

Diagram of bootconfig memory allocation layout

圖 1. Android 12 bootconfig 記憶體分配

引導程式在記憶體中建立 bootconfig 部分。 bootconfig 部分包含以下內容的記憶體分配:

  • 參數
  • 4 B尺寸parameters size
  • 4 B大小parameters checksum
  • 12 B bootconfig 魔術字串 ( #BOOTCONFIG\n )

參數有兩個來源:建構時已知的參數和建置時未知的參數。必須新增未知參數。

建置時已知的參數被打包到 bootconfig 部分中的vendor_boot映像的末尾。該部分的大小(以位元組為單位)儲存在供應商引導標頭欄位vendor_bootconfig_size中。

在建置時未知的參數僅在引導程式運行時才知道。在應用 bootconfig 預告片之前,必須將它們新增至 bootconfig 參數部分的末尾。

如果您需要在套用 bootconfig 預告片後新增任何參數,請覆寫預告片並重新套用它。

增量實施和驗證

依照本節給出的流程逐步實作 bootconfig 功能。在新增 bootconfig 參數時,保持核心命令列參數不變。

這些是增量實施和驗證的步驟:

  1. 進行引導程式和建置更改,然後執行以下操作:
    1. 使用BOARD_BOOTCONFIG變數新增新的 bootconfig 參數。
    2. 保持內核命令列參數不變,以便設備可以繼續正確啟動。這使得調試和驗證變得更加容易。
  2. 透過檢查/proc/bootconfig的內容來驗證您的工作。驗證您在裝置啟動後是否看到新新增的參數。
  3. 使用BOARD_BOOTCONFIG變數和引導程式將androidboot.*參數從核心命令列移至bootconfig。
  4. 驗證每個參數是否存在於/proc/bootconfig中且不/proc/cmdline中。如果您可以驗證這一點,那麼您的實施就成功了。

OTA升級降級注意事項

當您管理不同版本的 Android 或不同核心版本之間的 OTA 升級和降級時,應特別小心。

Android 12 是第一個支援 bootconfig 的版本。如果降級到先前的任何版本,則必須使用核心命令列參數而不是 bootconfig。

核心版本 12-5.4 及更高版本支援 bootconfig。如果降級到之前的任何版本(包括11-5.4),則必須使用核心命令列參數。

從 Android 11 及更早版本升級到 Android 12 及更高版本可以繼續使用核心命令列參數。升級核心版本也是如此。

故障排除

執行驗證步驟時,如果在/proc/bootconfig中沒有看到預期的參數,請檢查logcat中的核心日誌。如果核心支援的話,bootconfig 總是會有一個日誌條目。

日誌輸出範例

$ adb logcat | grep bootconfig
02-24 17:00:07.610     0     0 I Load bootconfig: 128 bytes 9 nodes

如果您看到傳回錯誤日誌,則表示載入 bootconfig 時出現問題。若要查看不同的錯誤類型,請查看init/main.c