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 的功能。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值