在 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
布局信息。
图 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 参数不变。
这些是带有验证的增量实施的步骤:
- 进行引导加载程序和构建更改,然后执行以下操作:
- 使用
BOARD_BOOTCONFIG
变量添加新的 bootconfig 参数。 - 保持内核 cmdline 参数原样,以便设备可以继续正确启动。这使得调试和验证更加容易。
- 使用
- 通过检查
/proc/bootconfig
的内容来验证您的工作。验证您是否在设备启动后看到了新添加的参数。 - 使用
BOARD_BOOTCONFIG
变量和引导加载程序将androidboot.*
参数从内核 cmdline 移动到 bootconfig。 - 验证每个参数是否存在于
/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 。