本文档记录了 Magisk 中的启动镜像打补丁过程,这是 Magisk 在 Android 启动过程中获得早期控制权的关键组成部分。通过这种机制,Magisk 可以在不修改实际系统分区的情况下修改系统,从而在保持“系统无感”方法的同时实现 root 访问和模块支持。
有关 OTA(空中升级)生存机制的信息,请参阅 OTA 生存。
在深入了解打补丁过程之前,了解 Android 启动镜像的结构非常重要。现代 Android 启动镜像通常遵循以下结构:
来源: native/src/boot/bootimg.cpp native/src/boot/cpio.rs86-145
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
启动打补丁过程主要在两个关键组件中实现:
boot_patch.sh) - 协调整体打补丁流程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 而非 boot | false |
LEGACYSAR | 强制内核加载 rootfs | 根据设备配置决定 |
来源: scripts/boot_patch.sh72-77 scripts/util_functions.sh329-368
Ramdisk 是 Magisk 在启动过程中获得控制权的启动镜像的关键部分。
打补丁之前,Magisk 会检查 ramdisk 的状态:
来源: scripts/boot_patch.sh112-117 native/src/boot/cpio.rs545-566
打补丁过程对 ramdisk 进行了以下关键修改:
添加 Magisk 组件:
magiskinit 二进制文件作为 /init创建配置文件:
KEEPVERITY 和 KEEPFORCEENCRYPT 等标志备份机制:
来源: scripts/boot_patch.sh161-190 native/src/boot/cpio.rs602-676
除了 ramdisk,Magisk 还修改其他启动镜像组件:
设备树 Blob (DTB) 会根据配置修改以移除 verity,并支持旧的 SAR(System-as-Root)设备。
来源: native/src/boot/dtb.rs scripts/boot_patch.sh198-208
对特定设备内核进行打补丁,以禁用会干扰 Magisk 的安全机制。
移除三星特有的安全功能
强制内核加载 rootfs 以支持旧的 SAR 设备
来源: scripts/boot_patch.sh210-240
所有修改完成后,启动镜像将被重新打包。
来源: scripts/boot_patch.sh scripts/sign_chromeos.sh
打补丁完成后,启动镜像需要刷入到设备中。这通过以下几种机制之一完成:
来源:scripts/util_functions.sh394-416 scripts/flash_script.sh93-101 scripts/addon.d.sh118-126
修补后的启动镜像通过在启动过程中尽早注入 magiskinit 来实现 Magisk 的功能。
来源:scripts/boot_patch.sh179-181 native/src/init/rootdir.cpp
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 版本。它包括回退机制和安全检查,以防止设备变砖,并在需要时能够恢复原始启动镜像。