本文档解释了 Magisk 在设备启动过程中如何初始化并修改 Android 系统以启用其功能。它涵盖了启动镜像修补过程、启动顺序流程以及 Magisk 如何在系统中建立自身。有关启动镜像修补实现细节的信息,请参阅 启动镜像修补。
Magisk 的启动流程主要包括两个阶段:
启动过程对 Magisk 至关重要,因为它需要在系统初始化早期建立自身,获得修改 Android 系统所需的权限,而无需永久更改系统文件。
在设备能够使用 Magisk 启动之前,必须修补启动镜像以包含 Magisk 组件。此过程发生在 Magisk 安装期间。
来源:scripts/boot_patch.sh84-254 scripts/flash_script.sh93-94
在此过程中,Magisk 执行以下操作:
当设备使用 Magisk 修补的启动镜像启动时,会发生以下顺序:
来源:native/src/init/rootdir.cpp266-339 native/src/init/rootdir.cpp344-378 scripts/util_functions.sh274-324
magiskinit 是放置在修补后的启动镜像中以替换原始的 /init 的二进制文件。它是修补后的启动镜像加载时运行的第一个进程。
主要职责
来源:native/src/init/init.hpp1-40 native/src/init/lib.rs42-107
Magisk 根据设备配置采用不同的策略。
来源:native/src/init/rootdir.cpp266-339 native/src/init/rootdir.cpp344-378 native/src/init/selinux.rs64-280
Magisk 需要修补 SELinux 策略才能正常运行。它根据 Android 版本采用多种策略。
| 策略 | Android 版本 | 方法 |
|---|---|---|
| LD_PRELOAD | Android 10+ | 预加载一个库来替换 security_load_policy。 |
| SELINUXFS | Android 8.0-9.0 (Treble) | 直接挂载 selinuxfs 并劫持节点。 |
| LEGACY | Android 6.0-7.1 | 在挂载 selinuxfs 后阻止 init 流程。 |
来源:native/src/init/selinux.rs27-41 native/src/init/selinux.rs123-172
Magisk 修改了几个关键的初始化脚本以建立其功能。
init.rc - 被修补以:
init.zygote.rc* - 被修补以:
来源:native/src/init/rootdir.cpp46-137 native/src/init/rootdir.cpp177-204
Magisk 在启动过程的早期设置临时目录结构,用于存储其文件并提供挂载点。
来源:native/src/init/mount.cpp213-250 native/src/include/consts.rs15-30
Magisk 包含一个 addon.d 脚本,用于在 OTA (Over-The-Air) 更新期间保持 Magisk 的存在。此脚本:
来源:scripts/addon.d.sh1-168 scripts/util_functions.sh417-441
Magisk 的启动流程是一种复杂的实现,它允许 Magisk:
这种设计确保 Magisk 能够在最大化兼容性和最小化设备变砖风险的同时,提供 root 访问权限和系统修改功能。