HLE,高级固件模拟
HLE 是 PS5PCEM 应答游戏所导入固件调用的方式。每个数字 NID 都成为主机栈上的一个 Zig 函数,并在 Windows 上保留客户机的 System V 调用约定。
仓库笔记截至 2026年10月10日
为什么固件不在游戏里
PlayStation 5 游戏并不自带它所调用的操作系统。它的导入是 11 个字符的标识符。PS5PCEM 由导出名称计算每个标识符:名称加上固定盐之后做 SHA-1,再取摘要的前八个字节,用一种 base64 变体编码。实现以可读名称注册,并可以要求该名称必须产生的标识符,因此拼错的导出会在构建模块时失败。
动态链接器把标识符与库、模块及其版本放在一起查找。同一个标识符可以存在于不止一个库中。对不携带可用元数据的导入,存在只按标识符查找的路径,而这种回退被视为最后手段,因为它有歧义。
调用跑在主机栈上
客户机直接调用固件,因此调用从客户机线程的栈开始,这个栈常常是 1 MB,因为那正是游戏所请求的大小。打开文件之类的主机工作需要大得多的栈帧。编译器在进入函数时、任何提前返回之前就预留这个栈帧。于是固件函数体可能在执行到真正需要这块空间的那一行之前就走出客户机栈,故障落在所有客户机映射之外。
每一次 HLE 调用都会在主机工作期间切换到该线程自己的主机栈。参数经内存传递,因此一个汇编桩就能服务每一种签名,包括浮点返回和聚合返回。嵌套的固件调用留在外层调用已经建立的那条栈上。在 Windows 上,客户机使用 System V AMD64 约定,主机使用 Microsoft x64,因此每个可被客户机调用的函数都按客户机约定声明。漏掉这个声明仍然能够编译,然后就会从错误的寄存器里读取参数。
HLE 表面覆盖什么
在这套机制之上,固件库提供直接内存与灵活内存、模块句柄、pthread、同步、文件、存档、纤程、字体、PNG、时钟、手柄、AudioOut、AJM、NGS2、ACM、AvPlayer、APR 和 AMPR。网络、SSL 和 NP Web API 保持各自的上下文与请求生命周期,并返回确定的离线错误。需要系统外壳的对话框会立即结束,并给出连贯的无头结果。
10 月 10 日的验证运行通过了完整的 ReleaseSafe HLE 套件,606 项测试全部通过。这个计数是固件套件的计数。它本身并不记录新的帧率,也不记录新的完整通关。
已经实现的部分
- NID 计算、带版本的符号登记表,以及每一次固件调用的主机栈切换。
- Windows 上的客户机 System V 调用;主机约定是 Microsoft x64。
- 内存、文件、线程、存档、媒体、音频编解码器,以及 APR/AMPR 命令路径。
- 无头对话框,以及不打开主机套接字的离线网络配置。
尚未实现的部分
- 游戏导入了、而 PS5PCEM 尚未实现的库,仍然会使导入失败。
- 对不在已发布依赖图中的模块做真正的按需加载,会返回错误。
- 需要真实系统外壳、账号或网络对端的平台服务仍然不可用。
相关机制
这些页面说明什么