Android的img镜像

一个完整的Android img镜像通常由多个文件构成,其中最主要的三个文件分别是boot.img、system.img和recovery.img。

boot.img,即引导镜像文件,包含了kernel(内核)和ramdisk(内存磁盘)等关键信息。这个文件的作用是引导设备启动,加载并运行Android系统的核心组件。

system.img,即系统镜像文件,包含了Android系统的所有文件。这些文件是设备运行Android应用程序和服务的基础,也是设备实现各种功能的关键。

recovery.img,即恢复镜像文件,主要用于恢复系统或进行刷机操作。这个文件同样包含了一个Linux内核(zImage)和一个内存磁盘镜像(ramdisk.img)。与boot.img不同的是,recovery.img中的Linux内核调用的init命令解析的init.rc及其相关文件的内容有一定的差异。这种差异使得设备在启动时可以根据用户的选择,选择使用boot.img中的Linux内核正常启动系统,或者选择使用recovery.img中的Linux内核进入恢复模式,进行系统的恢复或刷机操作。

了解了Android img镜像的基本组成后,我们再来探讨其生成原理。Android img镜像的生成过程实际上是一个打包过程,即将上述提到的各个文件按照一定的规则和结构打包成一个img文件。这个过程通常由专门的工具完成,如make工具等。通过配置相应的Makefile文件,我们可以指定要打包的文件、打包后的文件名以及打包选项等。当执行make命令时,工具会根据Makefile中的配置信息,将各个文件按照指定的结构和规则打包成一个img文件。

生成的img文件可以直接刷入Android设备中,从而实现系统的升级或刷机。在刷机过程中,设备会首先从boot.img或recovery.img中选择一个Linux内核启动系统。如果选择boot.img中的Linux内核,则设备会正常启动并运行Android系统;如果选择recovery.img中的Linux内核,则设备会进入恢复模式,允许用户进行系统的恢复或刷机操作。

在实际应用中,我们可以通过修改img镜像中的文件来实现对Android系统的定制和优化。例如,我们可以替换system.img中的文件来添加或删除系统应用程序,从而改变设备的功能和外观。同时,我们也可以利用recovery.img来备份和恢复系统,以及在设备出现故障时进行刷机修复。

总之,Android的img镜像生成原理涉及到多个文件的打包和组合。通过深入了解其组成和差异,我们可以更好地理解Android系统的升级和刷机过程,从而更好地维护和优化我们的Android设备。

不同 IMG 的打包方式差异

  • system.img / vendor.img / product.img
  • 这些属于文件系统镜像。编译系统先把对应的文件放到 out/…/system/、out/…/vendor/等临时根目录,再用工具打包:
    • 老版本常用 make_ext4fs 或 mkuserimg_mke2fs 打成 ext4 sparse 镜像;
    • Android 10+ 很多设备改用 mkfs.erofs 打成 EROFS 只读镜像。
  • boot.img / recovery.img
  • 不是普通文件系统,而是用 mkbootimg 把内核(kernel Image) + ramdisk.img(cpio 归档) + 偏移参数拼接成单一二进制镜像,同时写入头部信息供 bootloader 解析。
  • userdata.img / cache.img
  • 通常是创建一个空的文件系统镜像(ext4/ f2fs),格式化后输出,真正的数据是设备首次开机时由系统写入的。
  • vbmeta.img
  • 由 avbtool 根据其他镜像的哈希值生成,用于 AVB(Android Verified Boot)安全校验签名。

U盘刷机和线刷原理区别

U盘刷机是设备自己从U盘里读镜像并在本地写内部存储,通常运行在 Recovery 或 Bootloader 层级; 线刷是设备被PC通过USB控制,实时接收镜像数据并在 BootROM/Bootloader 层级写入内部存储

设备端运行的程序阶段不同

U盘刷机常见运行阶段

  • Recovery 模式(最常见)
    • 完整 Linux 内核 + Android 恢复环境
    • 挂载 U盘(vfat/exFAT),解析 ZIP,调用 updater/ dd/ 文件系统写入
  • Bootloader / SPL 阶段(部分盒子、开发板)
    • 支持从 USB Mass Storage 读取 image 并裸写分区
  • BootROM 级(少数 SoC)
    • ROM 代码支持从 USB 存储引导烧录程序(工厂用) 👉 总体偏向较高层级或可选功能,依赖固件里实现了 U盘 读取和解析能力。 线刷常见运行阶段
  • Bootloader / Fastboot
  • BootROM(EDL / Download / Preloader) 👉 偏向更底层、标准化、强制存在的烧录通道,通常由 SoC 架构保证。

系统分区

核心解答:SoC 与 Android system_ext/product/vendor 的区别

在图中,8397 SoCAndroid system_ext/product/vendor 代表了完全不同的软硬件层级和所有权边界。

维度 8397 SoC(含 lun aios/models) Android system_ext / product / vendor
本质定义 硬件芯片及底层 Bootloader/固件层。代表 SoC 厂商(高通)提供的硬件算力与最基础的底层软件环境。 操作系统层。代表 Android 开源项目(AOSP)编译出的系统文件,运行在 Linux 内核之上。
包含内容 lun aios: 运行在 SoC 底层或独立安全域的 AI Agent 操作系统。- lun models: 端侧大模型二进制资源。- (隐含)Bootloader、TEE、底层 DSP 固件等。 system_ext: AOSP 核心框架的扩展(如 OEM 深度定制的系统服务)。- product: 设备制造商(OEM)定制的应用、主题、铃声等。- vendor: 芯片供应商(SoC 厂商,如高通)提供的硬件抽象层(HAL)和驱动库。
所有者 SoC 供应商(高通)及特定的 AI 软件团队。 system_ext/product: Google (AOSP) & OEM(如车企)。- vendor: SoC 供应商(高通等)。
更新与刷写方式 img 刷写 / 线刷包刷写:通常需要进入 EDL(紧急下载)模式或专用的底层刷机模式(如 QFIL)。- 权限极高,可直接操作 UFS 存储。 二进制发布,集成到 super 分区:通过 Recovery、OTA 或 Fastboot 更新 super.img 来间接更新。- 运行时受 Android 框架管理。
核心职责 提供最底层的硬件算力、安全隔离(如 Hypervisor 多 OS 并行)以及极速的 AI 推理环境。 提供用户界面、应用运行框架、系统服务以及与硬件交互的标准化接口。

super 分区

super 分区是 Android 10(Q)引入 动态分区(Dynamic Partitions)​ 后新增的一个逻辑分区容器,用来把传统的多个物理分区(如 system、vendor、product、system_ext等)打包在同一个物理存储区域里,并在运行时通过 Device Mapper​ 映射成多个逻辑分区。

A/B分区

维度 A/B 分区 非 A/B
系统副本 两份(_a / _b) 一份
更新方式 后台写另一槽,重启切换 Recovery 里覆盖原分区
是否需要 Recovery 可不依赖 必须有
断电风险 可回退另一槽 易变砖
存储占用 更大(双份关键分区) 较小
Android 版本趋势 10+ 几乎标配(尤其 GMS 设备) 老旧设备/部分定制板卡

Android系统的编译

在 Android 7.0 发布之前,Android 仅使用 GNU Make 描述和执行其 build 规则。Make 构建系统得到了广泛的支持和使用,但在 Android 层面变得缓慢、容易出错、无法扩展且难以测试。Soong 构建系统正好提供了 Android build 所需的灵活性。 Soong 构建系统是在 Android 7.0 (Nougat) 中引入的,旨在取代 Make。它利用 Kati GNU Make 克隆工具和 Ninja 构建系统组件来加速 Android 的构建。

Soong

Soong 构建系统是在 Android 7.0 (Nougat) 中引入的,旨在取代 Make。它利用 Kati GNU Make 克隆工具和 Ninja 构建系统组件来加速 Android 的构建。

Kati

把 Android.mk 转成 Ninja 的工具(读作 kah-tee),Android 早期大量模块都用 Android.mk 写构建规则,不可能一夜之间全改成新的 Android.bp。Kati 充当了过渡桥梁,让遗留的 Make 体系能无缝接入高速的 Ninja 构建后端。

Ninja

Ninja 是一个小而快的构建系统(类似 Make,但设计理念完全不同)。 核心定位:它是一个底层执行器,设计目标是极致的速度,而不是给人写复杂逻辑的。 特点: 无逻辑:Ninja 文件(.ninja)是纯声明式的,不支持条件分支、循环等高级语法,只能描述“输入→输出→命令”的依赖图。这正是它能极快解析的原因。 并行高效:天生支持高并发(-j),能最大化利用多核 CPU 做增量编译(只重编改动过的文件)。 在 AOSP 中的角色:无论是 Soong(解析 Android.bp)还是 Kati(解析 Android.mk),最终都会生成 .ninja 文件,然后由 Ninja 统一读取并执行真正的编译、链接、打包命令。

两者在构建流水线里的分工

当你在 AOSP 根目录敲下 m 或 make 时,大致流程是:

  1. Soong​ 解析所有 Android.bp → 生成 out/soong/build.ninja
  2. Kati​ 解析所有 Android.mk → 生成对应的 build-*.ninja
  3. 合并:上层构建脚本把这些 ninja 文件组合起来
  4. Ninja​ 读取最终的 ninja 文件 → 调度 clang、javac 等工具真正地把代码编出来 简单类比:
  5. Kati​ 是把“老式说明书(Make)”翻译成“标准工单(Ninja)”的人;
  6. Soong​ 是直接按“新式子弹点(bp)”开出“标准工单(Ninja)”的人;
  7. Ninja​ 是车间里只看工单、闷头狂跑机器的执行者。

两条前端生成路线(并行/先后)

Soong 和 Kati 各自处理不同类型的构建描述文件,最终目标都是产出 .ninja 文件。

Soong 路线(处理 Android.bp)
  1. Blueprint先解析所有 Android.bp 的声明式语法,交给 Soong(Go 写的逻辑层)。
  2. Soong 解析模块属性、处理变种(multilib、arch 等)、计算依赖图。
  3. 最终生成 out/soong/build.ninja,描述所有 Android.bp 对应的编译/链接规则。
Kati 路线(处理 Android.mk)
  1. Kati(ckati)读取传统的 Android.mk 以及 build/core/ 下的各类 .mk 配置逻辑。
  2. 把 Makefile 里的条件、函数、宏展开,翻译成纯声明式的 Ninja 规则。
  3. 最终生成 out/build- .ninja,描述所有遗留 Android.mk 模块的构建动作。
合并与 Ninja 执行阶段

soong_ui 会生成一个 out/combined-

.ninja,把上面两份 ninja 文件整合起来,作为真正执行的入口。 Ninja被调用后: 读取合并后的 ninja 文件,在内存里构建完整的依赖图。 利用文件时间戳、depfile 做增量检查,只重编有变动的部分。 按 -j 并行度最大化调度底层编译器(clang、javac 等)执行实际编译、链接、打包。 ##### 产物输出阶段 编译过程中生成 .o、.a、.so、.jar、APK 等中间和最终产物,存放在 out/target/product/ /​ 下对应目录(system/、vendor/、lib/ 等)。 最后由打包逻辑调用相关工具,把产物组装成 system.img、vendor.img、boot.img​ 等系统镜像。 用一条线串起来就是: m / lunch → soong_ui → Android.bp → Blueprint/Soong → out/soong/build.ninja​ ↘ Android.mk → Kati → out/build-*.ninja → out/combined-*.ninja → Ninja(并行执行编译器)→ out/target/… → 各类 .img 镜像

作者 littlepudding

奇瑞汽车,车载智能语音开发

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注