Peterc3-dev/phone2a-apu-unlock

GitHub: Peterc3-dev/phone2a-apu-unlock

一个为 Nothing Phone 2a 的联发科 APU 650 NPU 提供 root 级内核设备节点访问与用户空间 ABI 握手探测的工具集。

Stars: 0 | Forks: 0

# phone2a-apu-unlock 一个 KernelSU sepolicy 模块加上 Rust ABI 探测器,用于在 Nothing Phone 2a 上向 shell 域开放 `/dev/apusys` 的访问权限,并包含对 MT6886 APU 650 用户空间握手的特性分析。 **状态:** ABI 已验证 —— 握手在真实硬件上有效。DLA 提交路径:未实现。 ## 这实际上是什么 这是在 Phone 2a 上对 MediaTek APU 650 NPU 进行探索的一个切入点: - 一个 KernelSU 模块 (`ksu-module/`),添加了一些 sepolicy 规则,以便 `shell` 域可以对 `/dev/apusys` 和 DMA-buf heap 节点执行 `read/write/open/ioctl` 操作。 - 一个小型的 Rust 二进制程序 (`apu650-probe/`),它打开设备,发出四个已记录的 ioctl (`HANDSHAKE`、`MEM`、`CMD`、`UTIL`),并转储设备的能力位掩码。 - 编译时的 `static_assert` 检查,用于验证 Rust 结构体布局是否与 C 内核头文件匹配。(这在前几次迭代中捕获了一个关于 union 填充错误的真实 bug;如果没有它们,编码后的 `_IOC_SIZE` 将会发生偏移,导致每个 ioctl 都会返回 `-EINVAL`。) - 一个 Frida 脚本 (`frida/`),用于拦截 vendor NN HAL 服务中的 `ioctl()` 调用,以便在封闭的用户空间进行调用时(例如在拍摄相机 Ultra HDR 照片时)捕获真实的 APU 流量。 ## 这不是什么 - **不是 NeuroPilot 的替代品。** MediaTek 的 NeuroPilot 软件栈(`ncc-tflite` 编译器、`libneuron` 运行时)是存在的,可通过 Genio Yocto SDK 公开重新分发,并会生成 `mdla3.0` `.dla` 文件,这些文件的目标加速器代数与 APU 650 相同。 - **不是通往 MTK NPU 的唯一开源路线。** [Google 的 LiteRT](https://github.com/google-ai-edge/LiteRT/tree/main/litert/vendors/mediatek) 和 [PyTorch ExecuTorch](https://docs.pytorch.org/executorch/stable/backends-mediatek.html) 都附带了官方的 MediaTek 后端。它们封装了同样封闭的运行时;一旦运行时就位,Phone 2a 上的 APU 就可以从这些软件栈中访问。 - **不是一个 `.dla` 逆向工程项目。** 没有人公开逆向过该格式,因为没有必要 —— MediaTek 已经提供了发射器。 - **不是 TFLite 到 DLA 的编译器。** 只是提供了内核驱动程序的切入点。 ## 实际的差距在哪里 三个观察结果: 1. Dimensity 7200 / MT6886 **不在 Google 一级支持的 LiteRT SoC 列表中**(该列表枚举了 D7300、D8300、D9000 系列;7200 被省略了)—— 参见 [ai.google.dev/edge/litert/next/mediatek](https://ai.google.dev/edge/litert/next/mediatek)。 2. Phone 2a 的官方消费者镜像**并未提供可用于 Nothing 厂商构建所需的相机/语音路径之外通用推理的 NeuroPilot 用户空间**。 3. 据报道,公开可用的 NeuroPilot AOT 路径与 Google 内部构建相比存在残缺 —— 参见 [LiteRT issue #6462](https://github.com/google-ai-edge/LiteRT/issues/6462)(由于内部编译器标志,速度差距高达约 153 倍)。 因此,这套工具提供了对设备节点的 root 域访问权限,以及在一个被厂商软件栈视为二等公民的芯片上运行用户空间探测器的可能。这才是它真正的价值所在。要从“握手成功”跨越到“有用的推理”,你仍然需要封闭的 NeuroPilot SDK,或者需要有人花上几个月的时间进行逆向工程工作来编写一个开源的发射器。 ## 测试环境 仅限一台设备,仅限一个构建版本。**未在其他任何地方进行过验证。** | | | |---|---| | 手机 | Nothing Phone 2a (代号 Pacman,型号 A142) | | 构建版本 | BP2A.250605.031.A3 (Pacman_B4.0-260225-1817) | | 操作系统 | Android 16 | | 内核 | 5.15.189-android13-8 | | Bootloader | 已解锁 | | Root | KernelSU-Next v3.2.0 LKM,已修补 init_boot_b | | 模块 | `apu650-unlock-ksu-v0.3.zip` 已在 KSU 管理器中刷入 | ## 进行握手(快速入门) 完整流程位于 `docs/UNLOCK.md` 中。摘要: 1. **解锁 Bootloader**,通过 Nothing 的官方流程:。有 7 天的等待期。 2. **提取匹配的 `init_boot.img`**,来自 spike0en 的归档:。请与你安装的 `ro.build.fingerprint` 相匹配。 3. **安装 KernelSU-Next 管理器**(,v3.2.0 或更高版本,**LKM 模式**)。通过管理器修补 `init_boot.img`,然后刷入到当前活动槽位: fastboot flash init_boot_b patched_init_boot.img # 或者 _a,根据 ro.boot.slot_suffix 而定 4. **打开一次 KSU-Next 管理器**以引导启动 `ksud`,然后在 SuperUser 选项卡中开启 **Shell**(UID 2000)。 5. **构建并安装解锁模块:** cd ksu-module zip -r ../apu650-unlock-ksu-v0.3.zip module.prop sepolicy.rule customize.sh post-fs-data.sh adb push ../apu650-unlock-ksu-v0.3.zip /sdcard/ # KSU-Next manager → Modules → Install from storage → 选择该 zip → reboot 6. **构建探测器并运行:** cd apu650-probe rustup target add aarch64-linux-android # 首先在 ~/.cargo/config.toml 中设置 linker — 参见 apu650-probe/README.md cargo build --release --target aarch64-linux-android cd .. scripts/first-contact.sh 如果一切正常: ``` opened /dev/apusys fd=3 version=0x3 dev_mask=0x56 mem_mask=0x36 flags=0x0 meta_size=32 dev[1] num=2 meta="0x15556" dev[2] num=1 meta="" ... ``` 请对照 `docs/HANDSHAKE.md` 来解析你的数值。 ## 仓库结构 ``` apu650-probe/ Rust handshake binary + Cargo project ksu-module/ v0.3 KernelSU sepolicy module sources frida/ ioctl tap script + decoder dla/ TFLite test model scaffolding (no compiler — see docs/DLA.md) abi/ machine-readable ioctl + ops catalog (JSON) scripts/ first-contact.sh + frida-tap.sh docs/ UNLOCK, ABI, HANDSHAKE, DLA, FRIDA, ROADMAP ``` ## 限制 —— 在假设它适用于你之前请阅读此内容 - **仅在一台设备上进行了测试。** 不同的地区/运营商构建版本*应该*是兼容的(相同的 SoC,相同的内核源码树),但这尚未得到验证。 - **Phone 2a Plus (PacmanPro) 未经测试。** 属于相同的 SoC 系列 (MT6886),因此大概率工作方式相同,但我们没有数据。 - **DLA 提交未实现。** 你可以与驱动程序通信,但实际上无法运行推理。目前要进行推理,你需要通过 MediaTek 的 Genio SDK;本仓库不绕过它。 - **修补后的 `init_boot.img` 是特定于设备和构建版本的。** 它不能移植到其他 MTK 手机上;请分别提取每一个相匹配的 boot 产物。 - **解锁 Bootloader 会使你的 Nothing 保修失效。** 虽说如此,但特此声明。 ## 许可证 本项目基于 MIT 许可证(参见 `LICENSE`)。`apu650-probe/src/uapi.rs` 派生自的 `mdw_ioctl.h` 头文件是 GPL-2.0 协议;Rust 转录版本是公共 ABI 的结构镜像,用于互操作性(未链接任何内核代码)。 **Genio SDK 由 MediaTek 单独授权,不可重新分发。** 请勿将提取的 SDK 二进制文件推送到此仓库或任何公开镜像。 ## 致谢 - **spike0en** —— [Nothing OTA archive](https://github.com/spike0en/Nothing_OTA_Archive) 是构建版本匹配的 `init_boot.img` 的来源。 - **MediaTek 的 `mtk-apusys-driver`**([gitlab](https://gitlab.com/mediatek/aiot/bsp/mtk-apusys-driver)) —— 公开的 GPL-2.0 驱动程序源码树是该 ABI 的唯一事实来源。 - **NothingOSS** —— [Phone 2a kernel sources](https://github.com/Nothing-OSS) 确认该驱动程序源码树与 Genio 的 android13 头部分逐字节匹配。 - **KernelSU-Next**([rifsxd/KernelSU-Next](https://github.com/rifsxd/KernelSU-Next)) —— LKM 模式的 root 使得无需重新构建内核即可修改 sepolicy。 - **frida** —— 在不修改厂商软件栈的情况下拦截 ioctl 的绝佳工具。
标签:Android内核, KernelSU, NPU, Rust, 可视化界面, 硬件交互, 移动开发, 系统底层, 网络流量审计, 通知系统