在 Android 12 中實作 bootconfig

在 Android 12 中,bootconfig 功能會取代 Android 11 以下版本使用的 androidboot.* 核心 cmdline 選項。Bootconfig 功能是一種機制,可將設定詳細資料從建構和系統啟動載入程式傳遞至 Android 12。

這項功能可將 Android 使用者空間的設定參數與核心區隔開來。將長串 androidboot.* 核心參數移至 bootconfig 檔案,可在核心 cmdline 上建立空間,並讓該空間可供日後擴充使用。

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

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

針對搭載 12-5.10.xx 核心版本的裝置,實作 bootconfig 功能。如果您要升級裝置,則不需要實作這項功能。

範例和來源

在您查看本節的範例和原始碼時,請注意,bootconfig 程式碼的格式與 Android 11 以下版本中使用的核心 cmdline 格式僅略有不同。不過,以下差異對於使用方式來說相當重要:

  • 參數必須以換行符號逸出順序 \n 分隔,而非以空格分隔。

系統啟動載入程式範例

如需啟動載入程式範例,請參閱 Cuttlefish U-boot 參考啟動載入程式實作。以下列出參考資料中的兩個提交。第一個升級會將引導程式標頭版本支援升級至最新版本。在本範例中,第一個版本更新 (或升級) 會將版本支援升級至下一個版本,也就是 v4。第二項作業是新增 bootconfig 處理功能,並示範如何在執行階段新增參數:

建構範例

如需顯示 mkbootimg 變更,以使用廠商啟動標頭 v4 建構 vendor_boot.img 的建構範例,請參閱 mkbootimg changes for bootconfig。請參閱 Cuttlefish 變更,以便執行下列操作:

實作

合作夥伴必須為系統啟動載入程式新增支援,並將建構時間 androidboot.* 參數從核心 cmdline 移至 bootconfig 檔案。實作這項變更的最佳方式是逐步進行;如要瞭解如何遵循逐步程序,請參閱「逐步實作和驗證」一節。

如果您變更了搜尋 /proc/cmdline 檔案的 androidboot.* 參數,請改為將其指向 /proc/bootconfig 檔案。ro.boot.* 屬性會以新的 bootconfig 值設定,因此您不需要變更使用這些屬性的程式碼。

版本變更

首先,將 Boot 標頭版本更新為第 4 版:

- BOARD_BOOT_HEADER_VERSION := 3

+ BOARD_BOOT_HEADER_VERSION := 4

新增 bootconfig 核心 cmdline 參數。這會讓核心尋找 bootconfig 區段:

BOARD_KERNEL_CMDLINE += bootconfig

bootconfig 參數是根據 BOARD_BOOTCONFIG 變數中的參數建立,就像是 kernel cmdline 是根據 BOARD\_KERNEL\_CMDLINE 建立一樣。

任何 androidboot.* 參數都可以原封不動地移動,如下所示:

- BOARD_KERNEL_CMDLINE += androidboot..selinux=enforcing

+ BOARD_BOOTCONFIG += androidboot..selinux=enforcing

系統啟動載入程式變更

引導程式會在跳轉至核心之前設定 initramfs核心啟動設定會搜尋 bootconfig 區段,並尋找位於 initramfs, 最末端的預期拖車。

引導程式會從供應商的啟動映像檔標頭取得 vendor_boot.img 版面配置資訊。

Bootconfig 記憶體配置配置的圖表

圖 1. Android 12 開機設定記憶體配置

引導程式會在記憶體中建立 bootconfig 區段。bootconfig 區段包含下列記憶體配置:

  • 參數
  • 4 B 大小 parameters size
  • 4 B 尺寸:parameters checksum
  • 12 B 開機魔法字串 (#BOOTCONFIG\n)

參數來自兩個來源:建構時已知的參數,以及建構時未知的參數。必須新增不明參數。

在建構期間已知的參數會封裝至 bootconfig 區段中 vendor_boot 映像檔的結尾。區段大小會以位元組的形式儲存在廠商啟動標頭欄位 vendor_bootconfig_size 中。

在建構期間未知的參數,只有在啟動載入程式執行階段時才會知曉。必須在套用 bootconfig 拖車之前,將這些參數加到 bootconfig 參數部分的結尾。

如果您需要在套用 bootconfig 拖車後新增任何參數,請覆寫拖車並重新套用。

逐步導入及驗證

請按照本節所述的程序,逐步實作 bootconfig 功能。新增 bootconfig 參數時,請勿變更核心 cmdline 參數。

以下是漸進式導入步驟,並附上驗證步驟:

  1. 變更 Bootloader 和 Build,然後執行下列操作:
    1. 使用 BOARD_BOOTCONFIG 變數新增 bootconfig 參數。
    2. 請維持核心 cmdline 參數的原始狀態,以便裝置繼續正確啟動。這可大幅簡化偵錯和驗證作業。
  2. 檢查 /proc/bootconfig 的內容,驗證作業。確認裝置啟動後,您會看到新加入的參數。
  3. 使用 BOARD_BOOTCONFIG 變數和啟動載入程式,移動 從核心 cmdline 到 bootconfig 的 androidboot.* 參數。
  4. 確認每個參數都存在於 /proc/bootconfig 中,且不存在/proc/cmdline。如果您可以驗證這一點,表示導入成功。

OTA 升級和降級注意事項

在不同 Android 版本或不同核心版本之間管理 OTA 升級和降級時,請特別小心。

Android 12 是第一個支援 bootconfig 的版本。如果降級至該版本之前的任何版本,則必須使用核心 cmdline 參數,而非 bootconfig。

核心 12-5.4 以上版本支援 Bootconfig。如果降級至該版本之前的任何版本(包括 11-5.4),則必須使用核心 cmdline 參數。

從 Android 11 以下版本升級至 Android 12 以上版本時,可以繼續使用核心 cmdline 參數。升級核心版本也是如此。

疑難排解

執行「驗證」步驟時,如果在 /proc/bootconfig 中找不到預期的參數,請檢查 logcat 中的核心記錄。如果核心支援 bootconfig,系統一律會顯示 bootconfig 的記錄項目。

記錄輸出內容範例

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

如果您看到系統傳回的錯誤記錄,表示載入 bootconfig 時發生問題。如要查看不同類型的錯誤,請查看 init/main.c