菜单

启动镜像修补

相关源文件

本文档记录了 Magisk 中的启动镜像打补丁过程,这是 Magisk 在 Android 启动过程中获得早期控制权的关键组成部分。通过这种机制,Magisk 可以在不修改实际系统分区的情况下修改系统,从而在保持“系统无感”方法的同时实现 root 访问和模块支持。

有关 OTA(空中升级)生存机制的信息,请参阅 OTA 生存

启动镜像结构

在深入了解打补丁过程之前,了解 Android 启动镜像的结构非常重要。现代 Android 启动镜像通常遵循以下结构:

来源: native/src/boot/bootimg.cpp native/src/boot/cpio.rs86-145

  • Header:包含关于启动镜像的元数据,包括大小和加载地址信息
  • Kernel:Android 启动所用的 Linux 内核
  • Ramdisk:包含 init 进程和基本文件的初始 RAM 磁盘(CPIO 格式)
  • Device Tree Blob(s):设备的硬件配置
  • Signature:用于已验证启动的可选加密签名

打补丁过程概述

Magisk 的启动镜像打补丁过程遵循以下关键步骤:

来源: scripts/boot_patch.sh85-106 scripts/boot_patch.sh110-145 scripts/boot_patch.sh161-190 scripts/boot_patch.sh198-240 scripts/boot_patch.sh246-251

启动打补丁的实现

启动打补丁过程主要在两个关键组件中实现:

  1. Shell 脚本(boot_patch.sh) - 协调整体打补丁流程
  2. 原生可执行文件(magiskboot) - 处理底层启动镜像的修改

boot_patch.sh 脚本

该脚本是打补丁过程的主要协调者。它使用 magiskboot 工具对启动镜像执行复杂操作。

来源: scripts/boot_patch.sh30-67 scripts/boot_patch.sh85-105 scripts/boot_patch.sh110-145 scripts/boot_patch.sh161-190 scripts/boot_patch.sh198-240 scripts/boot_patch.sh246-251

关键配置标志

打补丁过程可以通过几个环境变量进行自定义:

标志描述默认
KEEPVERITY保留 dm-verity对于 system-as-root 设备,设置为 true
KEEPFORCEENCRYPT保留强制加密对于加密设备,设置为 true
PATCHVBMETAFLAG修改启动镜像中的 vbmeta 标志如果没有 vbmeta 分区,则设置为 true
RECOVERYMODE打补丁对象为 recovery 而非 bootfalse
LEGACYSAR强制内核加载 rootfs根据设备配置决定

来源: scripts/boot_patch.sh72-77 scripts/util_functions.sh329-368

Ramdisk 打补丁详情

Ramdisk 是 Magisk 在启动过程中获得控制权的启动镜像的关键部分。

Ramdisk 状态检查

打补丁之前,Magisk 会检查 ramdisk 的状态:

来源: scripts/boot_patch.sh112-117 native/src/boot/cpio.rs545-566

Ramdisk 修改

打补丁过程对 ramdisk 进行了以下关键修改:

  1. 添加 Magisk 组件:

    • magiskinit 二进制文件作为 /init
    • 创建 overlay 目录结构
    • 添加压缩的 Magisk 二进制文件 (magisk.xz, stub.xz, init-ld.xz)
  2. 创建配置文件:

    • 存储 KEEPVERITYKEEPFORCEENCRYPT 等标志
    • 保存原始启动镜像的 SHA1 以便将来恢复
    • 如果指定,配置 pre-init 设备
  3. 备份机制:

    • 创建原始 ramdisk 的备份,以便可能恢复

来源: scripts/boot_patch.sh161-190 native/src/boot/cpio.rs602-676

二进制打补丁

除了 ramdisk,Magisk 还修改其他启动镜像组件:

DTB 打补丁

设备树 Blob (DTB) 会根据配置修改以移除 verity,并支持旧的 SAR(System-as-Root)设备。

来源: native/src/boot/dtb.rs scripts/boot_patch.sh198-208

内核打补丁

对特定设备内核进行打补丁,以禁用会干扰 Magisk 的安全机制。

  1. 移除三星特有的安全功能

    • 三星 RKP(实时内核保护)
    • 三星 DEFEX(防止漏洞)
    • 三星 PROCA(进程认证)
  2. 强制内核加载 rootfs 以支持旧的 SAR 设备

来源: scripts/boot_patch.sh210-240

重新打包和签名

所有修改完成后,启动镜像将被重新打包。

来源: scripts/boot_patch.sh scripts/sign_chromeos.sh

启动镜像安装

打补丁完成后,启动镜像需要刷入到设备中。这通过以下几种机制之一完成:

  1. 直接刷入:使用 Magisk 应用的直接安装选项
  2. 手动刷入:用户通过自定义 recovery 或 fastboot 刷入启动镜像
  3. OTA 生存机制:通过 Magisk 的 addon.d 脚本安装 Magisk

来源:scripts/util_functions.sh394-416 scripts/flash_script.sh93-101 scripts/addon.d.sh118-126

与 Magisk 组件集成

修补后的启动镜像通过在启动过程中尽早注入 magiskinit 来实现 Magisk 的功能。

来源:scripts/boot_patch.sh179-181 native/src/init/rootdir.cpp

高级修补功能

A/B 分区支持

Magisk 通过检测并使用正确的分区来支持 A/B 分区方案的设备。

来源:scripts/util_functions.sh274-282

启动镜像检测

Magisk 采用复杂的算法来定位正确的启动镜像。

来源:scripts/util_functions.sh370-392

结论

启动镜像修补是 Magisk 的基础组成部分,它使 Magisk 能够获得对 Android 启动过程的早期控制,同时保持系统无关的方法。通过仔细修改启动镜像的关键组件——尤其是 ramdisk 和 init 进程——Magisk 可以在不修改系统分区的情况下将自身注入启动链,从而在提供 root 访问和模块支持的同时,根据需要保留 OTA 更新能力和安全功能。

修补过程被设计为灵活的,支持各种设备配置、A/B 分区方案,并适应不同的 Android 版本。它包括回退机制和安全检查,以防止设备变砖,并在需要时能够恢复原始启动镜像。