Boot Image Header Version 介绍

从Android 9开始,boot映象的header包含一个字段用于标识header版本号。引导加载程序必须检查header版本号字段,并相应地解析header。通过对boot映象header进行版本编号,可在将来对header进行修改,保持向后兼容性。

旧版本中的unused字段在Android 9之后会转换为header_version字段,Android 9之间版本的boot映象的header版本会被视为0。所有新发布的Android 9设备必须使用v1版本的boot header。所有新发布的Android 10设备必须使用v2版本的boot header。

Android 9在创建boot映象的mkbootimg工具添加了header_versionrecovery_dtbo参数用于设置boot映象header版本和recovery dtbo映象的路径。可在BoardConfig.mk中使用BOARD_MKBOOTIMG_ARGS配置这些参数,如:

1
BOARD_MKBOOTIMG_ARGS := --ramdisk_offset $(BOARD_RAMDISK_OFFSET) --tags_offset $(BOARD_KERNEL_TAGS_OFFSET) --header_version $(BOARD_BOOTIMG_HEADER_VERSION)

Android 9及之前版本,dtb.img不是在自己的分区里,就是被打包到image.gz中以创建kernel+dtb映象(即用于mkbootimg工具创建boot映象)。从Android 10开始,对boot映象格式进行了调整,默认会包含dtb映象,并在bootloader添加了新的kernel cmdline参数androidboot.dtb_idx来指示所选DT的索引用于进行VTS验证,以检查设备中的boot映象header版本是不是v2。对于Non-A/B设备,会将dtb作为recovery映象的一部分,可以避免某些因OTA升级中断而带来的问题。例如,在OTA升级时,若dtb分区已升级,但因为某些原因未完全升级完成(如断电),设备会重启进入recovery模式以重新进行OTA升级,但此时就会出现recovery映象不匹配的情况(因为dtb已经升级了)。

dtb映象必须使用以下格式之一:

(1)DT Blob依次串联:bootloader使用每个fdt头文件中totalsize字段来读取和解析相应的blob。

(2)DTB/DTBO分区结构:bootloader会检查dt_table_entry结构体(含id,rev和custom字段)来选择正确的DT Blob,该结构体可存放条目的硬件识别信息。

Android 10在创建boot映象的mkbootimg工具中添加了dtbdtb_offset参数用于设置dtb映象的路径和dtb实际加载的物理地址。必须在BoardConfig.mk中将BOARD_INCLUDE_DTB_IN_BOOTIMG设定为true,并用BOARD_PREBUILT_DTBIMAGE_DIR来指定dtb映象的路径,另外需要将dtb_offset参数配置到BOARD_MKBOOTIMG_ARGS中,如:

1
BOARD_MKBOOTIMG_ARGS := --ramdisk_offset $(BOARD_RAMDISK_OFFSET) --dtb_offset $(BOARD_DTB_OFFSET) --tags_offset $(BOARD_KERNEL_TAGS_OFFSET) --header_version $(BOARD_BOOTIMG_HEADER_VERSION)

下表是boot映象的各字段说明:

字段 类型 说明
magic[BOOT_MAGIC_SIZE] unit8 boot的magic大小
kernel_size unit32 kernel大小
kernel_addr unit32 加载kernel的起始物理地址
ramdisk_size unit32 ramdisk大小
ramdisk_addr unit32 加载ramdisk的起始物理地址
second_size unit32 第二阶段bootloader的大小
second_addr unit32 加载第二阶段bootloader的起始物理地址
tags_addr unit32 加载kernel tags的起始物理地址
page_size unit32 flash页大小
unused unit32 (Andoid 9移除)
header_version unit32 boot的header版本(Android 9新增)
os_version unit32 android系统版本
name[BOOT_NAME_SIZE] unit8 boot的名字大小
cmdline[BOOT_ARGS_SIZE] unit8 cmdline参数的大小
id[8] unit32 时间戳等内容
extra_cmdline[BOOT_EXTRA_ARGS_SIZE] unit8 额外的cmdline参数的大小
recovery_dtbo_size unit32 recovery dtbo大小(Android 9新增,适用于Non-A/B)
recovery_dtbo_offset unit64 加载recovery dtbo的起始物理地址(Android 9新增,适用于Non-A/B)
header_size unit32 boot映象header大小(Android 9新增)
dtb_size unit32 dtb映象大小(Android 10新增)
dtb_offset unit64 加载dtb映象的起始物理地址(Android 10新增)

要允许添加dtb.img,需要按下表方式调整boot映象格式:

boot映象格式 页数
boot header (1 page) 1
kernel (l pages) l = (kernel_size + page_size - 1) / page_size
ramdisk (m pages) m = (ramdisk_size + page_size - 1) / page_size
second stage bootloader (n pages) n = (second_size + page_size - 1) / page_size
recovery dtbo (o pages) o = (recovery_dtbo_size + page_size - 1) / page_size
dtb (p pages) p = (dtb_size + page_size - 1) / page_size

下面以十六进制hexdump工具中boot.img为例呈现各字段内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
00000000: 414E 4452 4F49 4421 4818 8A00 0080 0040    ANDROID!H......@
00000010: A3FD 6800 0000 B051 0000 0000 0000 F040 #}h...0Q......p@
00000020: 0000 8847 0008 0000 0200 0000 3A01 0014 ...G........:...
00000030: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000040: 626F 6F74 6F70 743D 3634 5333 2C33 3253 bootopt=64S3,32S
00000050: 312C 3332 5331 2062 7569 6C64 7661 7269 1,32S1.buildvari
00000060: 616E 743D 7573 6572 6465 6275 6700 0000 ant=userdebug...
......
00000240: 6A38 E7A4 5FA6 99AA 90E8 445E D76A D195 j8g$_&.*.hD^WjQ.
00000250: 3509 CAA5 0000 0000 0000 0000 0000 0000 5.J%............
......
00000660: 4CA7 0000 0028 F300 0000 0000 7C06 0000 L'...(s.....|...
00000670: 3097 0100 0000 8847 0000 0000 0000 0000 0......G........

boot_magic: ANDROID!
kernel_size: 008A 1848 (9050184)
kernel load address: 4000 8000
ramdisk size: 0068 FDA3 (6880675)
ramdisk load address: 51B0 0000
second bootloader size: 0000 0000 (0)
second bootloader load address: 40F0 0000
kernel tags load address: 4788 0000
page size: 0000 0800 (2048)
boot image header version: 0000 0002 (2)
os version and patch level: 1400 013A (335544634)
product name:
command line args: bootopt=64S3,32S1,32S1 buildvariant=userdebug
additional command line args:
recovery dtbo size: 0000 A74C (42828)
recovery dtbo offset: 00F3 2800
boot header size: 0000 067C (1660)
dtb size: 0001 9730 (104240)
dtb address: 4788 0000