skip to content
icePigeon's Blog

在 Debian 13 上借助用 Redroid 跑明日方舟

/ 4 min read

Table of Contents

前言

最近想在家里的 Debian 13 宿主机上跑明日方舟,通过 scrcpy 远程操作,之后也方便接入 MAA。

先试了 Redroid 的 Android 16 镜像,系统和核显都能正常工作,但游戏一进入下载资源的界面就闪退。按照 MAA 文档的建议换成 Android 11 后,还是会崩溃。

最后借助 Codex 找到了 ARM 转译库里的问题,留下来的兼容补丁只有一个字节。不得不说现在的大模型很厉害!

最终配置

宿主机是 Debian 13,CPU 为 Ryzen 9 7940HS,核显为 Radeon 780M。最终使用 Redroid 11 的 x86-64 镜像。

关键启动参数如下:

androidboot.use_memfd=1
androidboot.redroid_gpu_mode=host
androidboot.redroid_gpu_node=/dev/dri/renderD128
androidboot.redroid_width=1280
androidboot.redroid_height=720
androidboot.redroid_fps=60

宿主机还需要加载 binder_linux,向容器提供三个 Binder 设备并配置容器内权限,同时映射 GPU 设备 /dev/dri/renderD128。检查 SurfaceFlinger 后,确认实际使用的是 AMD radeonsi 硬件渲染,显示为 1280×720、60Hz。

最后那个字节

Android 11 上的闪退,最终定位到了 libndk_translation.so:它在处理内存权限时清除了执行位,导致一页原本可执行的 Android 运行时代码变成了 rw-。后续调用 java.io.File.exists 时,进程便因权限错误崩溃。

补丁修改了 MprotectForGuest 中的一个掩码,让调用者请求的执行权限能够保留下来:

83 e2 fa ; 修改前:and edx, 0xfffffffa
83 e2 fe ; 修改后:and edx, 0xfffffffe

实际只把 fa 改成了 fe。这处修改针对本次固定版本的 Android 11 镜像,不能直接套用到其他版本的转译库。

修复后,游戏通过了原来的闪退位置,进入资源包选择和下载界面,连续运行数分钟没有新增崩溃。720p 音视频串流也正常。不过这轮只验证到资源下载,登录、战斗和持续 60fps 还没有实测。确认补丁在重建容器后仍然生效后,我删除了旧 Android 16 的容器、数据和镜像。

原生 x86 支持去哪了

说到底,这次需要折腾 ARM 转译,是因为当前安装包没有原生 x86 库。至少在 2025 年 5 月的玩家反馈中,就已经有人发现:旧教程说《明日方舟》支持原生 x86,实际安装却需要 ARM 转译。具体是哪次更新停止提供的,我没有找到明确记录;有人提出可能与“移动安全联盟”的 SDK 有关。这次检查的国服 2.7.61 APK 则确实只有 arm64-v8a 和 armeabi-v7a,没有 x86 或 x86_64。

少了原生支持,在这台 x86 主机上就只能多加一层 ARM 转译,还得为转译层的兼容问题打补丁。GPU 加速解决不了 CPU 指令转译的额外开销。Google 的开发文档也建议提供原生 x86-64 库,以避免转译层带来的性能和稳定性问题。

原本可以直接运行的游戏,如今要绕这么一圈,付出性能代价,还要自己处理闪退。这样的兼容性倒退,实在不知道有何意义。