Android 分区详解:修订间差异

来自Uotan Wiki · 刷机百科
无编辑摘要
(修改表格内容)
 
(未显示2个用户的4个中间版本)
第1行: 第1行:
Android 设备包含若干个分区,这些分区在Android启动和运行过程中发挥不同的作用。
'''Android 设备包含若干个分区,这些分区在Android启动和运行过程中发挥不同的作用。'''
 
部分 A/B 设备为了支持无缝更新,把 boot、system、vendor 和 radio 配置了两个槽位(如:<code>system_a</code>,<code>system_b</code>)。


== 常见分区详解​ ==
== 常见分区详解​ ==
第20行: 第18行:
=== '''<code>system_ext</code> 分区''': ===
=== '''<code>system_ext</code> 分区''': ===
'''由谷歌在 Android 11添加的一个新分区,可以使用 <code>system</code> 资源'''
'''由谷歌在 Android 11添加的一个新分区,可以使用 <code>system</code> 资源'''
=== '''<code>product</code> 分区''': ===
'''许多 OEM 会自定义 AOSP 系统映像,以实现自己的功能并满足运营商的要求。不过,如果进行这类自定义,则无法针对多个软件 SKU 使用单个系统映像。映像必须各不相同,才能支持不同的语言区域、运营商等自定义。如果使用单独的 <code>product</code> 分区来包含自定义项,则可以针对多个软件 SKU 使用单个系统映像(<code>system</code> 分区会托管可在众多软件 SKU 之间共享的通用代码)。<code>vendor</code> 分区会继续托管 SoC 专属 BSP 代码,这类代码可以基于指定 SoC 在多台设备之间共享。'''
'''使用单独的分区存在一些弊端,例如,难以管理磁盘空间(应该预留一定的空间满足未来增长的空间需求),以及难以在各分区之间维护稳定的应用二进制接口 (ABI)。'''


=== '''<code>recovery</code> 分区''': ===
=== '''<code>recovery</code> 分区''': ===
第49行: 第52行:
=== '''<code>vendor_dlkm</code> 分区''': ===
=== '''<code>vendor_dlkm</code> 分区''': ===
'''此分区专门用于存储供应商内核模块。将供应商内核模块存储在 <code>vendor_dlkm</code> 分区(而不是 <code>vendor</code> 分区)中后,无需更新 <code>vendor</code> 分区即可更新内核模块。'''
'''此分区专门用于存储供应商内核模块。将供应商内核模块存储在 <code>vendor_dlkm</code> 分区(而不是 <code>vendor</code> 分区)中后,无需更新 <code>vendor</code> 分区即可更新内核模块。'''
=== '''<code>vendor_boot</code> 分区''': ===
'''Android 11 引入了通用内核映像 (GKI) 的概念。为了能够使用 GKI 轻松启动任意设备,Android 11 设备使用启动映像头文件版本 3,所有供应商专用信息都已从 <code>boot</code> 分区分离出来并转移到新的 <code>vendor_boot</code> 分区中,也就是在Android11中该分区由一个头文件、供应商 ramdisk 和设备树 blob (DTB) 组成。'''
'''而相对的,在安卓12中使用的是版本4,此时该分区由一个头文件、供应商 ramdisk 区段(包含串联起来的所有供应商 ramdisk 片段)、设备树 blob (DTB) 和供应商 ramdisk 表组成。'''


=== '''<code>radio</code> 分区''': ===
=== '''<code>radio</code> 分区''': ===
第59行: 第67行:
'''此分区会存储受保护的虚拟机固件 (pvmfw),即在受保护的虚拟机中运行的第一个代码。如需了解详情,请参阅受保护的虚拟机固件。'''
'''此分区会存储受保护的虚拟机固件 (pvmfw),即在受保护的虚拟机中运行的第一个代码。如需了解详情,请参阅受保护的虚拟机固件。'''


== 动态分区 ==
== System-as-root ==
搭载 Android 11 及更高版本的设备可以支持动态分区,此类分区属于 Android 的用户空间分区系统,支持在无线下载 (OTA) 更新期间创建和销毁分区以及调整分区大小。使用此分区系统,您可以在无线下载 (OTA) 更新期间创建、销毁分区或者调整分区大小。借助动态分区,供应商无需担心各个分区(例如 <code>system</code>、<code>vendor</code> 和 <code>product</code>)的大小。取而代之的是,设备会分配一个 <code>super</code> 分区,其中的子分区可动态调整大小。各个分区映像不再需要为将来的 OTA 预留空间。相反,<code>super</code> 中剩余的可用空间还可用于所有动态分区。
 
== 关于 system-as-root ==
在 Android 9 中,非 A/B 设备应采用 system-as-root,以便通过系统专用 OTA 进行更新。
在 Android 9 中,非 A/B 设备应采用 system-as-root,以便通过系统专用 OTA 进行更新。


第82行: 第87行:
'''首先让我们来看一下传统分区与VAB分区的结构'''
'''首先让我们来看一下传统分区与VAB分区的结构'''
[[文件:安卓分区结构对比2.png|缩略图|1029x1029像素|居中]]
[[文件:安卓分区结构对比2.png|缩略图|1029x1029像素|居中]]
A-only 即仅有一套分区表的系统分区模式,而后面安卓引入了A-only 动态分区。动态分区的内容可以见下方。


'''也就是说,在AB分区的设备中,system_a和system_b等ab分区是真实存在的,他们会占用空间,而在VAB中(以下以默认槽位A为例),system_a和system_b并非同时存在,因此不会占据大量空间。无缝更新最大的优点在于:几乎无感,安全。'''
'''也就是说,在AB分区的设备中,system_a和system_b等ab分区是真实存在的,他们会占用空间,而在VAB中(以下以默认槽位A为例),system_a和system_b并非同时存在,因此不会占据大量空间。无缝更新最大的优点在于:几乎无感,安全。'''
第93行: 第100行:
'''空间占用对比:'''
'''空间占用对比:'''


<!-- 图源自Android Open Source Project -->[[文件:谷歌提供的图片.png|缩略图|897x897px|居中]]
<!-- 源自Android Open Source Project 并进行重绘以及翻译 -->[[文件:分区2.png|居中|缩略图|837x837像素]]
 
 
* 以PixelOS为例
 
== 动态分区 ==
动态分区是 Android 的用户空间分区系统。使用此分区系统,您可以在无线下载 (OTA) 更新期间创建、销毁分区或者调整分区大小。借助动态分区,供应商无需担心各个分区(例如 <code>system</code>、<code>vendor</code> 和 <code>product</code>)的大小。取而代之的是,设备会分配一个 <code>super</code> 分区,其中的子分区可动态调整大小。各个分区映像不再需要为将来的 OTA 预留空间。相反,<code>super</code> 中剩余的可用空间还可用于所有动态分区。
 
通俗的来讲,就是将常见的 <code>system</code>,<code>system_ext</code>,<code>product</code>等分区包括在<code>super</code>分区里面,而动态分区并不意味着super分区就是
 
可以随意调节的,事实上可以动态调节的是super里面的分区,在总体大小保持固定的情况下,我们可以根据各个分区所需要使用的大小来动态分配。





2024年8月19日 (一) 20:48的最新版本

Android 设备包含若干个分区,这些分区在Android启动和运行过程中发挥不同的作用。

常见分区详解​

boot 分区

此分区包含一个内核映像,使用 mkbootimg 创建。您可以使用虚拟分区直接刷写任意映像,而无需刷写新的 boot 分区。 此分区还包含在 Android 13 之前发布的设备中的通用 ramdisk。

  • kernel:kernel 虚拟分区通过将新内核映像写入旧内核映像来覆盖内核(zImagezImage-dtbImage.gz-dtb)。如果提供的开发内核不兼容,则可能需要使用关联的内核模块更新 vendorsystemdtb 分区(如果存在)。
  • ramdisk:ramdisk 虚拟分区通过将新 ramdisk 映像写入旧 ramdisk 映像来覆盖 ramdisk。

init_boot 分区

此分区包含发布时搭载 Android 13 及更高版本的设备的通用 ramdisk。

system 分区

此分区包含 Android 框架。

system_ext 分区

由谷歌在 Android 11添加的一个新分区,可以使用 system 资源

product 分区

许多 OEM 会自定义 AOSP 系统映像,以实现自己的功能并满足运营商的要求。不过,如果进行这类自定义,则无法针对多个软件 SKU 使用单个系统映像。映像必须各不相同,才能支持不同的语言区域、运营商等自定义。如果使用单独的 product 分区来包含自定义项,则可以针对多个软件 SKU 使用单个系统映像(system 分区会托管可在众多软件 SKU 之间共享的通用代码)。vendor 分区会继续托管 SoC 专属 BSP 代码,这类代码可以基于指定 SoC 在多台设备之间共享。

使用单独的分区存在一些弊端,例如,难以管理磁盘空间(应该预留一定的空间满足未来增长的空间需求),以及难以在各分区之间维护稳定的应用二进制接口 (ABI)。

recovery 分区

此分区会存储在 OTA 过程中启动的恢复映像。支持无缝更新的设备可以将恢复映像存储为 bootinit_boot 映像中包含的 ramdisk(而不是单独的映像)。

注意:某些厂商的VAB分区结构设备不包含recovery分区,他们会将recovery分区与boot分区合并,因此当你需要刷入第三方Recovery时需要使用命令:fastboot boot boot.img(具体名称自定)

cache 分区

此分区会存储临时数据,如果设备使用无缝更新,则此分区是可选的。cache 分区并非必须可从引导加载程序写入,但必须可清空。此分区大小取决于设备类型和 userdata 上的可用空间。通常,50 MB 至 100 MB 就足够了。

misc 分区

此分区供 recovery 分区使用,大小为 4 KB 或更大。

userdata 分区

此分区包含用户安装的应用和数据,包括自定义数据。

metadata 分区

此分区用于在设备使用元数据加密时存储元数据加密密钥。大小为 16 MB 或更大。此分区未经加密,且系统不会对其数据拍摄快照。数据会在设备恢复出厂设置时被清空。此分区的使用受到严格限制。

odm 分区

此分区包含原始设计制造商 (ODM) 对系统芯片 (SoC) 供应商板级支持包 (BSP) 的自定义设置。利用此类自定义设置,ODM 可以替换或自定义 SoC 组件,并在硬件抽象层 (HAL) 上为板级组件、守护程序和 ODM 特定的功能实现内核模块。此分区是可选的;通常情况下,它用于存储自定义设置,以便设备可以针对多个硬件 SKU 使用单个供应商映像。

odm_dlkm 分区

此分区专门用于存储 ODM 内核模块。将 ODM 内核模块存储在 odm_dlkm 分区(而不是 odm 分区)中后,无需更新 odm 分区即可更新 ODM 内核模块。

vendor 分区

此分区包含一些厂商私有的二进制文件以及驱动等内容,用于实现厂商特定功能以及服务,例如图像传感器,音频,显示等,具体作用可以参考于ODM分区,而在各大厂商的系统维护中,如今 一加 (OnePlus),小米(Xiaomi)等厂商也开始使用ODM分区来存放他们的私有驱动文件,即将 /odm 作为另一个 /vendor 分区处理。

vendor_dlkm 分区

此分区专门用于存储供应商内核模块。将供应商内核模块存储在 vendor_dlkm 分区(而不是 vendor 分区)中后,无需更新 vendor 分区即可更新内核模块。

vendor_boot 分区

Android 11 引入了通用内核映像 (GKI) 的概念。为了能够使用 GKI 轻松启动任意设备,Android 11 设备使用启动映像头文件版本 3,所有供应商专用信息都已从 boot 分区分离出来并转移到新的 vendor_boot 分区中,也就是在Android11中该分区由一个头文件、供应商 ramdisk 和设备树 blob (DTB) 组成。

而相对的,在安卓12中使用的是版本4,此时该分区由一个头文件、供应商 ramdisk 区段(包含串联起来的所有供应商 ramdisk 片段)、设备树 blob (DTB) 和供应商 ramdisk 表组成。

radio 分区

此分区包含无线装置映像,只有包含无线装置且在专用分区中存储无线装置专用软件的设备才需要此分区。

tos 分区

此分区用于存储 Trusty 操作系统的二进制映像文件,仅在设备包含 Trusty 时使用。Trusty 是 Google 的可信执行环境 (TEE) 操作系统实现,与 Android 并行运行。

pvmfw 分区

此分区会存储受保护的虚拟机固件 (pvmfw),即在受保护的虚拟机中运行的第一个代码。如需了解详情,请参阅受保护的虚拟机固件。

System-as-root

在 Android 9 中,非 A/B 设备应采用 system-as-root,以便通过系统专用 OTA 进行更新。

注意:如果设备使用的是 A/B 分区架构,则无需做出任何改动。

与将 /boot 改为recovery分区的A/B设备不同,非A/B设备必须保留单独的/recovery 分区,因为它们没有后备插槽分区(例如,从 boot_a 切换到 boot_b)。如果在非A/B 设备上移除 /recovery并使其与A/B架构类似,那么在/boot分区更新失败时,恢复模式可能会遭到破坏。因此,对于非A/B设备来说,/recovery分区必须作为单独的分区存在(不同于非A/B设备的/boot),这意味着恢复映像将继续延迟更新(即如同 Android 9 之前的设备中那样)。

对于SAR设备与先前的旧设备,最明显的区别便在于分区的挂载点上,见

(非AB设备)

AB分区与无缝更新

Android 有两种更新机制:A/B(无缝)更新和非 A/B 更新,支持无缝更新的系统分区类型有两种,一种是AB分区,一种是VAB分区。

安卓系统从7.0开始引入新的OTA升级方式,叫做A/B系统。A/B系统就是设备上有A和B两套可以工作的系统(用户数据只有一份,为两套系统共用),而这样做的好处就是,当OTA进行失败时可以直接切换到另外一个未经OTA的槽位,从而防止设备变砖,而缺点也很明显——两套系统分区意味着其占据多原来一倍的大小。

而在2020年9月9日,谷歌正式发布了Android11 代号 Android R,而伴随其发布,谷歌也向各大厂商几乎强制安利了一项技术,出厂安卓11的机型必须使用VAB架构 Android Virtual A/B ,而在后续版本Android 12/13 中又增加了 VABC (Virtual A/B with Compression),增加了压缩功能。

首先让我们来看一下传统分区与VAB分区的结构

A-only 即仅有一套分区表的系统分区模式,而后面安卓引入了A-only 动态分区。动态分区的内容可以见下方。

也就是说,在AB分区的设备中,system_a和system_b等ab分区是真实存在的,他们会占用空间,而在VAB中(以下以默认槽位A为例),system_a和system_b并非同时存在,因此不会占据大量空间。无缝更新最大的优点在于:几乎无感,安全。

OTA 更新可以在系统运行期间进行,不会打断正常的使用。在更新写入完成后,只需要重启一次切换槽位即可完成系统更新。如果 OTA因为刷机失败等原因导致无法启动,将继续启动先前的操作系统。

更新包可以流式传输到 A/B 设备,因此在安装之前不需要先下载更新包。流式更新意味着用户没有必要在 /data 或 /cache 上留出足够的可用空间以存储更新包。

相比之下A-Only设备则没有上述优点,因为只有一套系统分区,如果OTA失败则会直接导致设备无法开机

空间占用对比:


  • 以PixelOS为例

动态分区

动态分区是 Android 的用户空间分区系统。使用此分区系统,您可以在无线下载 (OTA) 更新期间创建、销毁分区或者调整分区大小。借助动态分区,供应商无需担心各个分区(例如 systemvendorproduct)的大小。取而代之的是,设备会分配一个 super 分区,其中的子分区可动态调整大小。各个分区映像不再需要为将来的 OTA 预留空间。相反,super 中剩余的可用空间还可用于所有动态分区。

通俗的来讲,就是将常见的 system,system_ext,product等分区包括在super分区里面,而动态分区并不意味着super分区就是

可以随意调节的,事实上可以动态调节的是super里面的分区,在总体大小保持固定的情况下,我们可以根据各个分区所需要使用的大小来动态分配。


参考资料:

①安卓常见分区:https://source.android.com/docs/core/architecture/partitions?hl=zh-cn#standard-partitions

②安卓A/B系统分区:https://source.android.google.cn/docs/core/ota/ab?hl=zh-cn

③安卓分区布局:https://source.android.google.cn/docs/core/architecture/bootloader/system-as-root?hl=zh-cn#ramdisk