Android 的一些启动方式

Android 的一些启动方式

翻译自 Android Booting Shenanigans by topjohnwu

术语

  • rootdir: 根目录(/),所有的文件、文件夹、分区、文件系统都被存储并挂载在根目录中,在 Android 中,文件系统可能是 rootfssystem 分区。

  • initramfs: Android 启动镜像中的一部分,Linux 内核把它作为 rootfs 使用

  • recoveryboot 分区: 这两个分区其实十分相似,都是包含 ramdisk 和 Linux 内核的启动镜像(外加其它的一些东西),唯一的区别是启动 boot 分区时将会启动 Android,而 recovery 将会启动一个最小化的 Linux 环境,用来修复或升级设备

  • SAR: System-as-root,指将 system 分区作为根目录而不是 rootfs

  • A/B, A-Only: 对于支持无缝系统更新,而且拥有两个相同的 systemvendorboot,我们称之为 A/B 设备,反之,没有 A/B 设备这些特性的,我们称之为 A-Only 设备

  • 2SI: 双阶段启动,解释放在后面

这里有几个参数可以更精确地定义设备的 Android 版本:

  • LV: 发行版本,指设备发行时的 Android 版本。即设备首次上市时预装的Android版本

  • RV: 运行版本,指设备现在运行的 Android 版本

我们会使用 Android API 级别 来表示 LV 和 RV,API 级别和Android 版本之间的关系可以从这个表格中看到。例如,Pixel XL 发行时搭载 Android 7.1,现在运行 Android 10。这段话则可以用这段参数表示 LV = 25, RV = 29

启动方法

Android 的启动可以大致分为三种不同的方法,我们提供了一个方法,以确定您的设备最有可能使用的启动方法,例外情况将单独列出

方法启动时的根目录最终的根目录
Arootfsrootfs
Bsystemsystem
Crootfssystem
  • 方法 A - Legacy ramdisk: 这是以前所有 Android 设备的启动方式,内核使用 initramfs 作为根目录,并执行 /init 来启动

    • 不属于方法 B 和 C 标准的设备
  • 方法 B - Legacy SAR: 这种启动方法最先出现在 Pixel 1,内核直接挂载 system 分区作为根目录,然后执行 /init 启动

    • 设备 LV = 28
    • Google: Pixel 1、2 和升级到 Android 9 的 Pixel 3(a)
    • 一加: 6 - 7
    • 也有可能出现在部分 LV < 29 的 Android GO 设备中?
  • 方法 C - 2SI ramdisk SAR: 这种启动方法最先出现在 Pixel 3 Android 10 的开发者预览版当中,内核会先将 initramfs 作为根目录,然后在 rootfs 中执行 /init,这个 init 负责挂载 system 分区为新的根目录,最终执行 /system/bin/init 来启动

    • 设备 LV > 29
    • 设备 LV < 28, RV > 29 不包括已经使用方法 B 的设备
    • Google: Pixel 3(a) 且 RV >= 29

一些讨论

从 Google 官方的文档来看,Google 对 SAR 的定义只考虑了内核如何启动设备(上表中的 Initial rootdir),也就是说,从 Google 的角度来看,只有使用方法 B 的设备才是 Google 官方认为的 SAR 设备。

但对于 Magisk 来说,真正的区别在于设备在完全启动时最终使用的根目录是什么(上表中的 Final rootdir),也就是说,就 Magisk 而言,方法 B 和方法 C 都是 SAR 的一种形式,只是实现方式不同。本文档后面提到的每一个 SAR 例子都会参考 Magisk 的定义,除非另有特别说明。

方法 C 的标准有点复杂,简单点的话就是,要么你的设备足够新,预载 Android 10+,要么你就是在原本使用方法 A 的设备上运行第三方 Android 10+ 的 ROM。

  • 任何使用方法 A 的设备在运行 Android 10+ 时,都必须使用方法 C
  • 使用方法 B 的设备将继续使用方法 B 启动,除了 Pixel 3(a),Google 对其进行了改动以适应方法 C

SAR 是 Project Treble 中非常重要的一部分,因为 rootdir 应该与平台绑定,且谷歌强制所有 OEM 厂商遵守每年更新的要求。这也是为什么方法 B 和 C 带有 LV >= API级别 标准的原因。

一些历史

当 Google 发布初代 Pixel 时,他就已经支持了 A/B(无缝) 系统更新。出于存储空间的考虑,与 A-only 相比,有几个不同之处,最大的变化是的是删除了 recoverycache 分区,recovery ramdisk 被合并到 boot 中。

让我们回到 Google 第一次设计 A/B 的时候,如果使用 SAR(当时只有方法 B 存在),内核不需要 initramfs 来启动 Android(因为会将 system 挂载为根目录)。这意味着我们可以把 recovery 删除,把 recovery ramdisk(包含了一个最小化到 Linux 环境)放到 boot 里,然后让内核根据 Bootloader 的信息来决定将哪个挂载为根目录 (system 或 recovery ramdisk)

随着时间的推移,Google 推出了动态分区,这对于 SAR 来说不是一个好消息,因为 Linux 内核不能直接识别这种新分区格式,从而无法直接将 system 挂载为根目录。他们想到了方法 C,先将 initramfs 作为根目录,然后让 userspace 处理剩下的启动步骤,包括决定要启动到 Android 或 Recovery,Google 官方称之为 USES_RECOVERY_AS_BOOT

一些使用 A/B 和 2SI 的新设备还带有 recovery_a/_b 分区,这是 Google 官方支持的标准。这些设备将只使用 boot ramdisk 启动到 Android,因为 recovery 存储在一个单独的分区。

总结

有了以上的信息,现在我们可以把所有的 Android 设备分为这几种不同的类型。

类型启动方法分区类型是否使用 2SIboot中的 Ramdisk
AA-Only不使用boot ramdisk
BA/B可选recovery ramdisk
BA-Only可选N/A
CAny使用混合 ramdisk
  • 类型一: legacy ramdisk 启动
  • 类型二: 较老的 A/B 设备,Pixel 1 是第一款此类型设备,是第一款使用了 A/B 和 SAR 设备。
  • 类型三: 2018年末-2019年末的设备大多都是 A-Only,就 Magisk 而言,是有史以来最糟的一种设备
  • 类型四: 所以使用方法 C 的设备都属于类型四,使用 A/b 分区的类型四设备的 ramdisk 可以根据 Bootloader 的信息启动到 Android 或 Recovery,A-Only 的类型四设备的 ramdisk 只能启动到 Android

关于类型三设备的更多信息:Magisk 安装在 boot 的 ramdisk 中。对于其它类型的设备,因为它们的 boot 分区包含 ramdisk,所以可以很容易地通过 Magisk 管理器或第三方 Recovery 来安装 Magisk。但类型三设备,只能将 Magisk 安装到 recovery 分区中。正常启动时,Magisk 无法工作。除非从 recovery 分区启动,Magisk 才能正常工作。

一些类型三设备的 Bootloader 仍然支持 initramfs 被手动添加到 boot 镜像中的内核中(例如一些小米设备),但是许多设备都不支持(例如三星 S10,Note 10)。这完全取决于厂商如何定义其 Bootloader 的功能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值