[探索 Android 设备分区]-安卓手机分区扫盲!折腾狂必看~~

##################################################

目录

安卓系统是怎么分区的?

用户权限扫盲/为什么需要 root 手机

示例获取安卓 5.0.2 手机信息以及系统分区

详解安卓 6.0 系统分区

传统安卓的 non-A/B 分区

传统分区介绍

传统系统升级方案

安卓 7.0 之后的 A/B 和 VAB 分区结构

A/B 主备分区

A/B 分区的系统升级方式以及优缺点

A/B 分区结构

虚拟 AB 分区

安卓 10 之后的动态分区

Shared System Image/SSI 概念

动态分区和 super 概念

示例一个 Android 10 的默认分区方案


##################################################

安卓系统是怎么分区的?

——————————

用户权限扫盲/为什么需要 root 手机

        root 明明是一个名词 表示超级管理员

        但是却发展成了一个动词 表示获取手机最高权限

        当我们进入系统后 发现提示符为 $ 表示普通用户权限

普通用户权限

        普通用户享有的权限是受限的

        linuxer 都明白 Linux 系统权限是怎么一回事

        而 Android 就是 Java 版的 Linux 系统所以权限概念也差不多:

        超级用户:

root

提示符为 #

超级用户权限可以干任何事情

完全控制手机 使用手机未开放的功能

甚至可以卸载系统软件和控制硬件

        普通用户:

普通 user 权限次于 root 权限

提示符为 $

只能执行系统设置允许之内的操作

例如 设置手机密码/重启关机/卸载第三方应用软件

而且不允许我们查看和对某些分区文件进行操作例如上传文件和下载拷贝

虽然有着普通软件做不到的权限 但是不够自由

        软件权限:

一般的第三方应用软件权限都是最低的/不一般的权限

使用的时候会先向用户发起请求得到授权才同意执行

例如我们常见的 录音/录屏/定位 啊什么的你都可以设置相应的权限

        以下是以普通用户身份进行的一系列操作:

Microsoft Windows [版本 6.3.9600]
(c) 2013 Microsoft Corporation。保留所有权利。

C:\Users\byme>cd /adb    /* 进入程序目录 */

C:\adb>adb devices    /* 查看连接设备信息 */
List of devices attached
8P5SSOHQINAYZPMF        device


C:\adb>adb devices -l    /* 查看连接设备的详细信息 */
List of devices attached
8P5SSOHQINAYZPMF       device product:GN5005 model:GN5005 device:GIONEE_G1605A t
ransport_id:1


C:\adb>adb shell    /* 获取设备终端 */
shell@GIONEE_G1605A:/ $ getprop ro.product.model    /* 查看机型 */
GN5005
shell@GIONEE_G1605A:/ $ settings get secure android_id    /* 查看安卓 ID */
b53a46e7ac129a55
shell@GIONEE_G1605A:/ $ getprop ro.build.version.release    /* 查看安卓系统版本 */
6.0
shell@GIONEE_G1605A:/ $ cat /proc/cpuinfo    /* 查看 CPU 信息 */
Processor       : AArch64 Processor rev 3 (aarch64)
processor       : 0
model name      : AArch64 Processor rev 3 (aarch64)
BogoMIPS        : 26.00
Features        : fp asimd evtstrm aes pmull sha1 sha2 crc32
CPU implementer : 0x41
CPU architecture: 8
CPU variant     : 0x0
CPU part        : 0xd03
CPU revision    : 3

Hardware        : MT6737
shell@GIONEE_G1605A:/ $ cat /proc/meminfo    /* 查看内存使用情况 */
MemTotal:        2930964 kB
MemFree:         1169904 kB
MemAvailable:    2178420 kB
Buffers:           14320 kB
Cached:          1024216 kB
SwapCached:            0 kB
Active:           620368 kB
Inactive:         844280 kB
Active(anon):     426168 kB
Inactive(anon):     3476 kB
Active(file):     194200 kB
Inactive(file):   840804 kB
Unevictable:           0 kB
Mlocked:               0 kB
SwapTotal:       1465480 kB
SwapFree:        1465480 kB
Dirty:                 0 kB
Writeback:             0 kB
AnonPages:        426080 kB
Mapped:           263612 kB
Shmem:              3580 kB
Slab:              68384 kB
SReclaimable:      24012 kB
SUnreclaim:        44372 kB
KernelStack:       20480 kB
PageTables:        21884 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:     2930960 kB
Committed_AS:   25283700 kB
VmallocTotal:   260046784 kB
VmallocUsed:      201108 kB
VmallocChunk:   259735280 kB
shell@GIONEE_G1605A:/ $ dumpsys battery    /* 获取电量信息 */
Current Battery Service state:
  AC powered: false
  USB powered: true
  Wireless powered: false
  status: 2
  status: 1
  health: 2
  present: true
  present: false
  level: 74
  level: 50
  scale: 100
  voltage: 4204
  temperature: 350
  technology: Li-ion
shell@GIONEE_G1605A:/ $

        执行有限的操作 例如你想查看个设备挂载情况都没权限:

shell@GIONEE_G1605A:/ $ ls /dev
opendir failed, Permission denied
1|shell@GIONEE_G1605A:/ $ ls
acct
cache
charger
config
custom
d
data
default.prop
dev
enableswap.sh
etc
factory_init.project.rc
factory_init.rc
factory_init.usb.rc
file_contexts
fstab.mt6735
init
init.aee.rc
init.c2k.rc
init.common_svc.rc
init.environ.rc
init.mal.rc
init.modem.rc
init.mt6735.rc
init.mt6735.usb.rc
init.project.rc
init.rc
init.recovery.mt6735.rc
init.trace.rc
init.trustonic.rc
init.usb.rc
init.volte.rc
init.xlog.rc
init.zygote32.rc
init.zygote64_32.rc
meta_init.c2k.rc
meta_init.modem.rc
meta_init.project.rc
meta_init.rc
mnt
nvdata
oem
persist
proc
property_contexts
protect_f
protect_s
root
sbin
sdcard
seapp_contexts
selinux_version
sepolicy
service_contexts
storage
sys
system
ueventd.mt6735.rc
ueventd.rc
vendor
verity_key
shell@GIONEE_G1605A:/ $ exit

C:\adb>

——————————

示例获取安卓 5.0.2 手机信息以及系统分区

        安卓 5 分区就不详细解释了 命令全都贴这边:

C:\adb>adb devices    /* 查看连接设备信息 */
List of devices attached
f7cdc8c device


C:\adb>adb devices -l    /* 查看连接设备的详细信息 */
List of devices attached
f7cdc8c                device product:PD1401CL model:vivo_X5M device:PD1401CL tr
ansport_id:3


C:\adb>adb shell getprop ro.product.model    /* 查看机型 */
vivo X5M

C:\adb>adb shell settings get secure android_id    /* 查看安卓 ID */
266e0dcc556e1c31

C:\adb>adb shell getprop ro.build.version.release    /* 查看安卓系统版本 */
5.0.2

C:\adb>adb shell cat /proc/cpuinfo    /* 查看 CPU 信息 */
processor       : 0
model name      : ARMv7 Processor rev 1 (v7l)
BogoMIPS        : 38.40
Features        : swp half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva id
ivt vfpd32 evtstrm
CPU implementer : 0x41
CPU architecture: 7
CPU variant     : 0x0
CPU part        : 0xd03
CPU revision    : 1

processor       : 1
model name      : ARMv7 Processor rev 1 (v7l)
BogoMIPS        : 38.40
Features        : swp half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva id
ivt vfpd32 evtstrm
CPU implementer : 0x41
CPU architecture: 7
CPU variant     : 0x0
CPU part        : 0xd03
CPU revision    : 1

processor       : 2
model name      : ARMv7 Processor rev 1 (v7l)
BogoMIPS        : 38.40
Features        : swp half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva id
ivt vfpd32 evtstrm
CPU implementer : 0x41
CPU architecture: 7
CPU variant     : 0x0
CPU part        : 0xd03
CPU revision    : 1

processor       : 3
model name      : ARMv7 Processor rev 1 (v7l)
BogoMIPS        : 38.40
Features        : swp half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva id
ivt vfpd32 evtstrm
CPU implementer : 0x41
CPU architecture: 7
CPU variant     : 0x0
CPU part        : 0xd03
CPU revision    : 1

processor       : 4
model name      : ARMv7 Processor rev 1 (v7l)
BogoMIPS        : 38.40
Features        : swp half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva id
ivt vfpd32 evtstrm
CPU implementer : 0x41
CPU architecture: 7
CPU variant     : 0x0
CPU part        : 0xd03
CPU revision    : 1

processor       : 5
model name      : ARMv7 Processor rev 1 (v7l)
BogoMIPS        : 38.40
Features        : swp half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva id
ivt vfpd32 evtstrm
CPU implementer : 0x41
CPU architecture: 7
CPU variant     : 0x0
CPU part        : 0xd03
CPU revision    : 1

processor       : 6
model name      : ARMv7 Processor rev 1 (v7l)
BogoMIPS        : 38.40
Features        : swp half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva id
ivt vfpd32 evtstrm
CPU implementer : 0x41
CPU architecture: 7
CPU variant     : 0x0
CPU part        : 0xd03
CPU revision    : 1

processor       : 7
model name      : ARMv7 Processor rev 1 (v7l)
BogoMIPS        : 38.40
Features        : swp half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva id
ivt vfpd32 evtstrm
CPU implementer : 0x41
CPU architecture: 7
CPU variant     : 0x0
CPU part        : 0xd03
CPU revision    : 1

Hardware        : Qualcomm Technologies, Inc MSM8939_BC
Revision        : 0000
Serial          : 0000000000000000
Processor       : ARMv7 Processor rev 1 (v7l)

C:\adb>adb shell cat /proc/meminfo    /* 查看内存使用情况 */
MemTotal:        1956260 kB
MemFree:          420112 kB
Buffers:           17228 kB
Cached:           998884 kB
SwapCached:            0 kB
Active:           438508 kB
Inactive:         874096 kB
Active(anon):     296624 kB
Inactive(anon):      372 kB
Active(file):     141884 kB
Inactive(file):   873724 kB
Unevictable:           0 kB
Mlocked:               0 kB
HighTotal:       1588220 kB
HighFree:         180884 kB
LowTotal:         368040 kB
LowFree:          239228 kB
SwapTotal:             0 kB
SwapFree:              0 kB
Dirty:                 0 kB
Writeback:             0 kB
AnonPages:        296648 kB
Mapped:           169920 kB
Shmem:               528 kB
Slab:              49552 kB
SReclaimable:      17648 kB
SUnreclaim:        31904 kB
KernelStack:       11640 kB
PageTables:        19624 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:      978128 kB
Committed_AS:   30802344 kB
VmallocTotal:     516096 kB
VmallocUsed:      137396 kB
VmallocChunk:     167964 kB

C:\adb>adb shell dumpsys battery    /* 获取电量信息 */
Current Battery Service state:
  AC powered: false
  USB powered: true
  Wireless powered: false
  status: 2
  health: 2
  present: true
  level: 94
  scale: 100
  voltage: 4287
  temperature: 336
  technology: Li-ion

C:\adb>adb shell ls    /* 查看根目录 */
acct
cache
charger
config
d
data
default.prop
dev
etc
file_contexts
firmware
fstab.qcom
init
init.PD1401CL.rc
init.PD1401CLT.rc
init.PD1415A.rc
init.PD1419C.rc
init.PD1420L.rc
init.PD1421CA.rc
init.PD1421F_EX.rc
init.PD1421V.rc
init.PD1422F_EX.rc
init.PD1422V.rc
init.PD1502.rc
init.PD1502A.rc
init.PD1502F_EX.rc
init.PD1503.rc
init.PD1503F_EX.rc
init.PD1505.rc
init.PD1510.rc
init.PD1510F_EX.rc
init.PD1515A.rc
init.at.rc
init.class_main.sh
init.environ.rc
init.mdm.sh
init.qcom.bms.sh
init.qcom.class_core.sh
init.qcom.early_boot.sh
init.qcom.factory.rc
init.qcom.rc
init.qcom.sh
init.qcom.syspart_fixup.sh
init.qcom.usb.rc
init.qcom.usb.sh
init.rc
init.target.rc
init.trace.rc
init.usb.rc
init.vivo.rc
init.vivo.usb.rc
init.vivo.usb.sh
init.zygote32.rc
mnt
oem
persist
proc
property_contexts
res
root
sbin
sdcard
seapp_contexts
selinux_version
sepolicy
service_contexts
storage
sys
system
tombstones
ueventd.qcom.rc
ueventd.rc
vendor
verity_key

C:\adb>adb shell df    /* 获取分区信息 */
Filesystem               Size     Used     Free   Blksize
/dev                   942.7M    72.0K   942.6M   4096
/sys/fs/cgroup         942.7M    12.0K   942.7M   4096
/mnt/asec              942.7M     0.0K   942.7M   4096
/mnt/obb               942.7M     0.0K   942.7M   4096
/system                  2.3G     1.6G   759.9M   4096
/oem                    59.0M    44.0K    58.9M   4096
/data                    3.9G   475.1M     3.4G   4096
/cache                 290.6M   508.0K   290.1M   4096
/persist                27.5M   124.0K    27.4M   4096
/firmware               64.0M    51.3M    12.6M   16384
/mnt/media_rw/sdcard0: Permission denied
/mnt/secure/asec: Permission denied
/storage/sdcard0         7.4G    21.8M     7.4G   32768

C:\adb>

        如果是系统还没启动开没有挂载那么多乱七八糟的 加载界面可以看到更干净一点的:

C:\adb>adb shell
shell@PD1401CL:/ $ df
Filesystem               Size     Used     Free   Blksize
/dev                   942.7M    72.0K   942.6M   4096
/sys/fs/cgroup         942.7M    12.0K   942.7M   4096
/mnt/asec              942.7M     0.0K   942.7M   4096
/mnt/obb               942.7M     0.0K   942.7M   4096
/system                  2.3G     1.6G   759.9M   4096
/oem                    59.0M    44.0K    58.9M   4096
/data                    3.9G   406.9M     3.5G   4096
/cache                 290.6M   512.0K   290.1M   4096
/persist                27.5M   124.0K    27.4M   4096
/firmware               64.0M    51.3M    12.6M   16384
shell@PD1401CL:/ $

——————————

详解安卓 6.0 系统分区

        在终端中输入 df 查看分区挂载情况:

C:\adb>adb shell    /* 获取一个终端访问设备 */
shell@GIONEE_G1605A:/ $ df    /* 查看设备的挂载情况 */
Filesystem               Size     Used     Free   Blksize
/dev                     1.4G   120.0K     1.4G   4096
/sys/fs/cgroup           1.4G    12.0K     1.4G   4096
/mnt                     1.4G     0.0K     1.4G   4096
/system                  3.9G     3.9G    54.4M   4096
/cache                 387.4M     2.4M   385.0M   4096
/protect_f               5.8M    60.0K     5.8M   4096
/protect_s               5.8M    56.0K     5.8M   4096
/nvdata                 27.5M     2.0M    25.5M   4096
/storage                 1.4G     0.0K     1.4G   4096
/data                    9.6G   512.8M     9.1G   4096
/mnt/runtime/default/emulated: Permission denied
/storage/emulated        9.6G   512.8M     9.1G   4096
/mnt/runtime/read/emulated: Permission denied
/mnt/runtime/write/emulated: Permission denied
1|shell@GIONEE_G1605A:/ $

        这些分区通常用于:

/dev    /* 用于存放设备驱动 */
/sys/fs/cgroup    /* 任意进程进行分组化管理的功能 操作接口以 文件/目录 的方式组织在操作系统的该目录下 用以限制一个进程组能够使用的资源上限 例如 CPU/内存/磁盘/网络带宽 还能够对进程进行优先级设置、审计以及将进程挂起和恢复等操作 Android 操作系统也就凭借着这个技术为每个应用程序分配不同的 cgroup 将每个程序进行隔离达到了一个应用程序不会影响其她应用程序环境的目的 */
/mnt    /* 设备默认挂载点 直接理解为挂载设备的目录 */
/system    /* 存放系统文件 就是我们刷 ROM 的分区 安卓的系统目录 里面存放的都是系统文件 */
/cache    /* 缓存数据存放分区 */
/protect_f    /* 正常情况下 protect_f 中的 A 文件和 protect_s 中的 B 文件是相同的 因为写的时候都会去写两个 nvram 文件 具有 NVRAM_CATEGORY_IMPORTAN_L4 属性的 NVRAM LID 会存在 protect_f 分区  */
/protect_s    /* 如果还具有 NVRAM_ATTR_MULTIPLE 属性会存一个 B 文件到 protect_s 中 protect_s 是对 protect_f 中部分 NVRAM 的复制 主要存储着 SIM Lock 数据 */
/nvdata    /* nvdata 分区是我们可以直接读写的分区 一般也称为 binregion 分区 是一个备份分区 备份 NVRAM LID 有此分区一般也存在 protect_f 和 protect_s 或 protect_1 和 protect_2 分区 */
/storage    /* 存储卡位置 */
/data    /* 用户程序目录 就是我们装 APK 安装包的分区 */
/mnt/runtime/default/emulated    /* 默认操作主存储 如果有外置存储则切换操作外置存储 */
/storage/emulated    /* 该目录下的 0 为手机的内部储存根目录 1 表示手机的内存卡储存根目录 */
/mnt/runtime/read/emulated    /* 读外置存储 */
/mnt/runtime/write/emulated    /* 写外置存储 */

        关于外置存储的实现:

    ./storage/emulated/0 是手机的内部储存根目录
    类似于虚拟 sd 卡目录的一个 快捷方式/软链接
    是可以直接访问的一个目录 被作为 sd 卡使用了
    这也是为什么现在安卓的手机不需要插存储卡就能使用了
    她的实际目录应该是
./data/media/0
    直接访问这个要 root 权限
    但被挂载成 ./storage/emulated/0

    为了实现动态的外置存储权限 Android 会挂载三个目录到 /dev/fuse 来对应同一个外置存储
    三个目录分别是
/mnt/runtime/default/${label}
/mnt/runtime/read/${label}
/mnt/runtime/write/${label}
    这三个目录代表不同的权限

    当一个应用进程取得了读外置存储的权限
    那么她将使用
/mnt/runtime/read/${label}
    目录来操作外置存储
    
    当一个应用程序取得了写外置存储的权限
    那么她将使用
/mnt/runtime/write/${label}
    目录来操作外置存储
    
    当一个应用程序没有获取操作外置存储的权限
    将使用
/mnt/runtime/default/${label}
    目录来操作主存储
    
    三个 fuse 目录最终都会作用于外置存储的 media 目录
        只不过对目录下的可进行的操作权限是不同的
    
    Android 的 FUSE file-system daemon 会根据应用程序进程使用的 fuse 目录来决定是否可以读写外置存储的 media 目录下数据

##################################################

传统安卓的 non-A/B 分区

——————————

传统分区介绍

        安卓传统的 non-A/B 分区主要有

/boot
/system
/vendor
/userdata
/cache
/recovery
/misc

        分区作用:

    /boot
Boot 引导分区
存放启动和引导的文件
包含 Kernel/内核 和 Ramdisk/虚拟内存
开机启动相关引导
如果 boot 分区损坏通常就卡在开机第一个 LOGO 界面

    /system
System 系统分区
存放整个安卓操作系统和系统预装软件
此分区损坏会卡在开机的第二屏 就是开机的动画界面 无法进入系统

    /vendor
Vendor 包含了开发厂商私有的可执行程序、库、系统服务和 app 等
可以将此分区看做是 system 分区的补充
厂商定制 ROM 的一些功能都可以放在此分区
该分区主要包含开发厂商的定制应用与库文件
部分厂商会把 Vendor 分区置于 System 分区中便于后期更新维护

    /userdata
Data 数据分区
存放用户数据,包括应用、音视频、图片、文档、系统设置等
擦除这个分区相当于清空所有软件的数据
包括各种软件和文件资料还有系统的各项设置
但是不会影响手机的正常启动

    /cache
缓存区
可以帮助你快速的打开系统最常访问的数据和应用程序
不需要重复加载
擦除缓存的话并不会影响个人数据而新的缓存也会在后续生成进来

    /recovery
Recovery 恢复分区
存放着一个小 linux 系统用于恢复和更新其她分区的内容
包含一个简易的 Linux 系统 类似于 Windows PE 可以理解为一个非常简易的操作系统
用于恢复和维护手机还可以对其他分区进行 重启/Reboot 擦除/Wipe Data 等操作
所以说我们刷机刷系统的时候 很多都是在这个 Recovery 分区进行的
不过现在也出现了越来越多不存在 Recovery 分区的手机

    /misc
主要用于 Android 系统和 bootloader 通信
使 Android 系统能够重启进入 recovery 系统并执行相应操作

——————————

传统系统升级方案

        传统手机分区的 OTA 升级过程比较简单:

    Android 系统收到服务端下发的 OTA 推送将 OTA 包下载至 cache 分区

    OTA 包下载完成后将向 misc 分区写入指令
    表明下次启动时进入 recovery 模式并使用该 OTA 包进行升级

    重启手机

    重启后最先进入 bootloader
    bootloader 会先判断按键组合以及电源寄存器等
    随后会读取 misc 分区的内容并解析
    由于前面中已经向 misc 分区写入了指令所以这时 bootloader 读取指令后会引导启动 recovery
	
	进入 recovery 后读取 cache 分区中的 OTA 包
	并解析其中的升级脚本按照其指令对系统各个分区进行升级

	如果 recovery 自身也需要升级
    会在此过程中向 system 中写入 recovery-from-boot.p 文件
	这是一个 recovery 升级所需要的 patch

	最后 recovery 会清除 misc 分区并重启手机

	重启后最先进入 bootloader 判断按键组合和电源寄存器以及 misc 分区内容等
	默认情况会启动 Android 系统 此时已经是 OTA 升级后的新版本系统
	新版本 Android 系统启动后会检查是否存在 recovery-from-boot.p 文件
	如果存在则会对 recovery 进行升级

##################################################

安卓 7.0 之后的 A/B 和 VAB 分区结构

——————————

A/B 主备分区

        从 Android 7.0 开始 Google 引入了新的 OTA 升级方式

A/B System Updates

        这种升级方式将 Boot、System 等分区变为两套

Slot A 主分区
Slot B 备用分区

        也就是 AB 分区:

    A/B 分区结构顾名思义将系统分区分成了 A 和 B 两个 槽/slot
    手机启动时会选择 A 槽或者 B 槽启动
    运行过程中仅使用当前槽位的分区
    一旦当前运行槽出现问题系统仍可以选择另一个槽进行启动
    从而保证系统良好的可用性

        平时用的叫主分区 没有在使用的是备用分区

	示例分区结构
Slot A
	Boot
	System
Slot B
	Boot
	System
Cache
Data

——————————

A/B 分区的系统升级方式以及优缺点

        系统升级的时候可以无缝升级

系统运行时 Slot A、Cache、Data 不影响
在后台 Slot B 升级系统
升级完成后
重启手机
此时主分区和备用分区自动切换

        在此过程中仅重启操作是会被用户感知的 这个重启与普通重启的耗时没有什么区别

        这样升级方便省时 还能防止升级失败导致卡机

当系统无法成功启动时就会切回之前的分区并不会影响用户当前运行的系统

        缺点也是很明显 总要有一个分区拿来做备份用吧

所以会占用双倍的 System 分区空间!

        不过

由于 A/B 分区结构可以实现一边从服务端获取 OTA 数据一边直接写入待升级的槽

不需要临时存储 OTA 包的空间

因此不再需要再在 cache 或 userdata 分区预留足够空间了

——————————

A/B 分区结构

        Google 定义了 A/B 槽的几种标识

    bootable 标识该槽的系统是否可以启动
有时也用 unbootable 来标识 例如高通 含义与 bootable 相反

    successful 标识该槽的系统是否成功启动过
仅当该槽系统能够启动、运行、进行 OTA 升级时才会从用户态标记该槽为 successful

    active 标识该槽是否是当前运行的系统
两个槽中只有一个能标记为 active

        系统重启后 在 zygote 启动前
init 会调用 update_verifier 服务通过 dm-verity 机制校验本次升级的镜像
        通过后则会被标记为 successful
        如果系统当前 active 的槽反复多次启动都没能标记为 successful

则将该槽标记为 unbootable 并将另外一个槽标记为 active

        A/B 分区结构详解:

    bootloader 分区
功能同传统 non-A/B 分区的 bootloader
只是此处会根据 A/B 槽的 bootable、successful、active 等标识来选择启动哪个槽
根据不同厂商的实现可以是唯一的不区分 A/B 的 bootloader 也可以自定义

    boot_a 分区和 boot_b 分区
包含 kernel 和 recovery 的 ramdisk
recovery 打包在 boot 分区中
所以不再需要 recovery 分区
并且 recovery 系统也不再负责 OTA 升级转而由 Android 系统中 update_engine 服务负责
此时 recovery 仅负责双清等其她操作
这里需要说明一下 recovery 集成在 boot 中是由 TARGET_NO_RECOVERY 和 BOARD_USES_RECOVERY_AS_BOOT 等变量决定的

    system_a 分区和 system_b 分区
功能同传统的 system 分区一样
只是区分了 A 和 B 两个槽

    vendor_a 分区和 vendor_b 分区
功能同 non-A/B 的 vendor 分区
只是区分了 A 和 B 两个槽

    data 分区
功能同 non-A/B 的 userdata
并且用户数据仅存储一份 不区分 A/B

    misc 分区
功能同 non-A/B 的 misc 且不区分 A/B

    persist 分区
用来存储一些持久化数据
不会随着 双清 或 OTA 等操作被清除
也不区分 A/B

    示例分区:
Slot A
	/boot_a
        recovery_a
	/system_a
    /vendor_a
Slot B
	/boot_b
        recovery_b
	/system_b
    /vendor_b
/cache
/data
/misc
/persist

——————————

虚拟 AB 分区

        为解决占用双倍 System 分区问题,采用新的 虚拟 AB 分区 VAB
        于是就又有了 Virtual A/B System Updates
        出厂搭载 Android 11 的机型普遍采用这种方式:

Boot
System
Cache
Date

        对于 Boot 和 System 分区来说,两代系统,相同文件共用
        不同文件存于虚拟 A/B 分区

        虽然解决了空间占用问题
        但是不管是 A/B 分区还是 VAB 分区
        由于 Recovery 分区被并到了 Boot 分区中导致要想刷第三方的 Recovery 就会比较麻烦一点
        例如临时 TWRP 镜像
        于是不推荐使用 Recovery 来刷机 而是通过更底层的 fastboot 来操作

##################################################

安卓 10 之后的动态分区

——————————

Shared System Image/SSI 概念

        为了进一步让原生 Android 和各厂商的软件进行解耦
        使设备代码的移植/系统大版本的升级 变得更加友好
        Google 引入了 SSI/Shared System Image 概念

    SSI 是指
在 Android 版本相同的情况下各个 Android 设备的 ROM 镜像中
system.img 都是由该版本的原生 AOSP 或厂商定制代码编译出的
是多产品共同使用的与具体硬件设备无关的系统镜像
而且她与具体硬件设备、产品型号有关的代码会被放在其她分区中

——————————

动态分区和 super 概念

        自 Android Q 即安卓 10.0 之后系统支持 动态分区/dynamic partition

        她将多个系统只读分区包括
system
product
vendor
odm
        或者其她厂商自定义分区合并为一个 super 分区

        物理分区只有 super 分区的概念而没有 system 等分区

    因此使用 fastboot 刷机时是无法直接通过命令进行刷机的:
fastboot flash system system.img

    而只能刷写 super 分区:
fastboot flash super super.img

        super 分区不区分 A/B 槽

一个 super 分区中包含了 A/B 两套只读分区
并且其中的只读分区也不需要显式指定分区大小
因为都是在用户态中动态分配挂载的
只要这些只读分区的总大小不超过 super 分区的物理大小即可

        示例一个 super 物理逻辑分区:

system
	system_ext

product interface
	product

vendor interface
	vendor
    [odm]

[odm]

        简单描述一下 super 物理分区中包含的几个逻辑分区的内容

    system 逻辑分区即 SSI
这里存放通用 Android 系统组件
原则上不同厂商不同型号的设备都通用

    product 逻辑分区
该 产品 分区是与特定产品有关的模块
包括对于 Android 系统的定制化

    vendor 逻辑分区
厂商对系统的定制
例如对 Android 系统附加的功能
包括一些闭源的程序等

    odm
此为可选的分区
包含 SOC 附加的程序
这些内容可以集成在 vendor 中也可以单独分离出 odm 分区

        额外知识 看看就好:

    考虑到有些场景下还是需要单独刷写 system 或其她 super 中的逻辑分区
    Android 新增了一个用户态的 fastbootd 程序用来在用户态中完成这个工作

    有时候我们在调试阶段也需要修改 system 等分区中的内容
    通常会采用以下方式写入:
adb root    /* 获取 root 权限 */
adb disable-verity    /* 关闭 dm-verity */
adb reboot    /* 重启使生效 */
adb root    /* 再次获取 root 权限 */
adb remount    /* 重新以读写方式挂载 */

    由于动态分区中每个分区是连续排列不需要预留空间的
    因此写入时可能会造成空间不足
    为了解决这个问题引入了 overlay 文件系统保证对原分区的修改在 upper 层中
    意为挂载在进行从而不影响原分区数据

——————————

示例一个 Android 10 的默认分区方案

        安卓 10 系统确实跟以前的分区差别蛮大的:

C:\adb>adb shell getprop ro.build.version.release
10

C:\adb>adb shell df -h
Filesystem                   Size  Used Avail Use% Mounted on
/dev/block/dm-6              2.1G  2.1G     0 100% /
tmpfs                        2.7G  1.4M  2.7G   1% /dev
tmpfs                        2.7G     0  2.7G   0% /mnt
tmpfs                        2.7G     0  2.7G   0% /apex
/dev/block/dm-5               25M   28K   24M   1% /patch_hw
/dev/block/dm-7              6.6M  6.6M     0 100% /cust
/dev/block/dm-8              1.4G  1.4G     0 100% /hw_product
/dev/block/dm-9              129M  129M     0 100% /odm
/dev/block/dm-10             985M  985M     0 100% /preload
/dev/block/dm-11             381M  381M     0 100% /vendor
/dev/block/dm-12             4.9M  4.9M     0 100% /vendor/preavs
/dev/block/dm-13             132K  132K     0 100% /version
none                         2.7G     0  2.7G   0% /mnt/update_engine
/dev/block/mmcblk0p71        109G  107G  1.7G  99% /data
/dev/block/dm-14              93M   93M     0 100% /preas
/dev/block/mmcblk0p65         97M  132K   89M   1% /cache
overlay                       93M   93M     0 100% /system/product/priv-app
overlay                       93M   93M     0 100% /system/product/app
overlay                       93M   93M     0 100% /system/product/etc/permissions
/dev/block/loop2             232K   36K  192K  16% /apex/com.android.apex.cts.OOXX@N
/dev/block/loop3             4.9M  4.9M     0 100% /apex/com.android.conscrypt@AOOXXOOXX
/dev/block/loop4             5.6M  5.6M     0 100% /apex/com.android.media@OOXXAYMDA
/dev/block/loop5              22M   22M     0 100% /apex/com.android.media.swcodec@OOXXOOXXA
/dev/block/loop6             1.7M  1.6M     0 100% /apex/com.android.resolv@OOXXAOOXX
/dev/block/loop7             102M  102M     0 100% /apex/com.android.runtime@N
/dev/block/loop8             840K  812K   12K  99% /apex/com.android.tzdata@OOXXAOOXX
none                         2.7G     0  2.7G   0% /sys/fs/cgroup
/data/media                  108G  107G  1.7G  99% /storage/emulated
/data/misc_ce/0/kdfs/storage 109G  107G  1.7G  99% /mnt/mdfs/.hmdfs
/data/media/0                109G  107G  1.7G  99% /mnt/mdfs/sdcard
/mnt/media_rw/222E-1201       29G   11G   19G  37% /storage/NNNE-NNNN
mdfs                         1.7G     0  1.7G   0% /mnt/mdfs/groups

C:\adb>

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

燃吹

呜呜呜没钱钱吃饭了……

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值