在 Android 12 中實現 Bootconfig

在 Android 12 中,bootconfig 功能取代了 Android 11 及更低版本中使用的androidboot.*內核命令行選項。 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值設置,因此您無需使用這些屬性對代碼進行更改。

構建更改

首先,將您的引導頭版本升級到版本 4:

- BOARD_BOOT_HEADER_VERSION := 3

+ BOARD_BOOT_HEADER_VERSION := 4

添加bootconfig內核命令行參數。這使得內核尋找 bootconfig 部分:

BOARD_KERNEL_CMDLINE += bootconfig

bootconfig 參數是從BOARD_BOOTCONFIG變量中的參數創建的,很像內核 cmdline 是從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 參數時,保持內核 cmdline 參數不變。

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

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

OTA升級降級註意事項

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

Android 12 是第一個支持 bootconfig 的版本。如果降級到之前的任何版本,必須使用內核命令行參數而不是 bootconfig。

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

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

故障排除

執行驗證步驟時,如果在/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