Bootloader 之二三事

一、bootloader概述

bootloader是用来启动kernel的供应商专用映像。它会监听设备状态,并负责初始化TEE、绑定它的信任根。
bootloader可能会直接将一个新的映像烧入相应的分区中,也可能会使用recovery开始重新烧录过程(类似OTA操作过程)。
另外,bootloader会在启动kernel之前先验证bootrecovery分区的完整性,并显示相应的警告。

bootloader启动流程如下:
(1)首先加载bootloader。
(2)bootloader初始化内存。
(3)如果是A/B分区,则确定要启动的当前槽位。
(4)确定是否应改为启动recovery模式。
(5)bootloader加载映像,其中包含内核和ramdisk。
(6)bootloader开始将内核作为可自行执行的压缩二进制文件加载到内存中。
(7)内核将自身解压缩并开始执行到内存中。
(8)旧设备从ramdisk加载init,而新设备从system分区加载它。
(9)init从system分区中启动并开始装载其他所有分区,如/vendor,然后开始执行代码以启动设备。

二、boot reason

bootloader会使用专用的硬件/内存资源来确认设备重启的原因,然后将androidboot.bootreason=<reason>添加到启动设备的kernel cmdline中。在init启动时会将其转入bootloader_boot_reason_prop属性值ro.boot.bootreason中。

自Android 9.0开始规范boot reason格式(system/core/bootstat/bootstat.cpp),以便系统运行时重写其内容。

1
<reason>,<subreason>,<detail>...

<1>reason:记录设备重启/关机优先级最高的原因,此为必选部分。
可包含内核原因(watchdog,kernel_panic)、强原因(recovery,bootloader)、弱原因(coldhardwarmshutdownreboot

<2>subreason:记录设备重启/关闭的简要,此为可选部分。

<3>detail:记录哪个或者哪些subsystem造成的重启/关机,此为可选部分。

三、system as root

AB分区中,system分区会作为rootfs加载;而NonAB分区中,boot分区的ramdisk会先被加载到内存中,再作为rootfs装载,而system分区在system中装载。

鉴于ramdisk中包含旧的init,可能会造成无法解析system分区上的rc文件,所以需要将其同system.img合并,以便替换system.img后能正常挂载启动(Android P)。即将BOARD_BUILD_SYSTEM_ROOT_IMAGE设为true。

verity-boot 1.0: kernel需在system分区上解析android metadata,然后转换为dm-verity参数以设置dm-verity。

verity-boot 2.0: bootloader需整合external/avb/libavb,然后用它解析system的hash description,再将解析结果转换为dm-verity参数,最后通过kernel cmdline将参数传给kernel。(system的hash description可能位于vbmeta或system上)

四、unlock bootloader

解锁方式:
(1)Settings->About Phone->Developer option->OEM unlocking,打开该选项,即将unlock_ability设置为’1’。
(2)执行adb reboot bootloader进入fastboot模式。
(3)执行fastboot flashing unlock,根据界面提示完成解锁操作后,重启及恢复出厂后保持解锁状态。
备注:可通过fastboot flashing lock指令重新锁定设备。

ro.oem_unlock_supported若为’0’则表示不支持解锁,若为’1’则表面支持解锁。开机时bootloader通过将cmdline变量androidboot.flash.locked设为’1’(缩定)或’0’(已解锁)来显示锁定状态。

对于开启dm-verity的设备,可以用ro.boot.verifiedbootstate来设置ro.boot.flash.locked的值(orange状态即值为’0’,表明已解锁)。