ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

bbhost HLE Layer 实现解析:PS4 系统库的 PC 版重写——文件、线程、音频、网络与 NP

bbhost HLE Layer 实现解析:PS4 系统库的 PC 版重写——文件、线程、音频、网络与 NP

【免费下载链接】bbhost

Definitive Bloodborne PC Experience

项目地址:https://gitcode.com/gh_mirrors/bb/bbhost
点击查看免费下载

bbhost 是一款在 Windows 和 Linux 上原生运行《Bloodborne》的移植层——游戏自身的 x86-64 代码直接跑在 PC CPU 上,而它依赖的 PS4 系统库,则由 bbhost 的 HLE 层(高层仿真层)以 PC 版重写来应答。这篇文章逐模块解析这套 HLE 实现:文件系统如何沙箱化、线程同步如何重建于 futex、音频与影片如何回放、以及联机功能如何靠私有服务器加 P2P UDP 完整落地,帮你理解一个"不做模拟机"的项目是怎么把 660 个系统调用全部接住的。

为什么是 HLE:利用 PS4 是 x86-64 的"免模拟"路线 🎮

大多数模拟器需要解释或重编译目标 CPU 的指令,而 PS4 的 CPU 本身就是 x86-64——游戏代码不需要翻译,只需要"一个可以住的地方"。bbhost 的做法因此分两半:

  • CPU 侧原生运行:加载游戏的 ELF 可执行文件,完成重定位,把它的导入符号链接到 bbhost 自己的实现(见 src/core/elf.cpp),然后直接启动;
  • 系统库全部重写:游戏从 PS4 系统库导入的 660 个命名函数,每一个都由 src/hle/ 下的 PC 实现应答——这就是 HLE 层的职责范围。

所有模块在 src/hle/modules.h 中注册,启动时由 src/hle/runtime.cpp 的register_hle()依次挂入:

模块文件职责
libc.cpp / pthread.cppC 标准库与线程 API
fs.cpp / fios.cpp文件与异步文件操作
kernel.cpp内存管理与进程原语
audio.cpp / avplayer.cpp音频输出与影片播放
net.cpp / np_matching2.cpp网络套接字与 PlayStation Network

HLE 函数绑定机制:系统调用如何接到 PC 实现上 🔗

HLE 层与游戏代码之间通过 ELF 的导入表(import table)对接。src/hle/runtime.cpp 中的hle_make_stub为每个导入符号生成一个 stub 地址并写入 GOT 表项;src/hle/stub_table.inc 是一张自动生成的 768 项跳板表,未被认领的调用会落入hle_unknown_log,在日志中记录函数名和 NID,方便开发者追踪尚未实现的系统调用。

这个设计带来两个实际好处:一是每次"漏实现"都留下可审计的痕迹,而不是静默崩溃;二是 HLE 函数以GUEST_ABI调用约定编译,与游戏代码在同一个进程里零开销互调。

文件系统重写:沙箱路径映射与 Mod 叠加层 📁

文件层是 HLE 中最"用户可感知"的部分。src/hle/fs.cpp(约 1500 行)实现了带沙箱的路径映射器:游戏看到的/app0、/savedata0等 PS4 路径,只被映射到配置中允许的宿主机目录——g_allowed_roots 之外的路径一律不可达,保证游戏进程碰不到玩家磁盘上的其他东西。

几个值得注意的细节:

  • 只读 dump 原则:游戏本体目录刻意保持只读,玩家修改走叠加层(overlay)。src/hle/fs.h 中mods目录会在/app0读取之前优先解析,修改过的资产永远不必写回 dump 本身;
  • 叠加层性能优化:多层 overlay 逐层探测路径的开销曾被实测为每次文件打开约 0.1 ms,因此引入了 OverlayIndex 索引,命中索引的路径不再落盘探测;
  • 异步文件操作:src/hle/fios.cpp 实现sceFios2的文件/目录句柄与异步 API,内部同步完成,句柄表用互斥锁保护,错误码精确还原SCE_FIOS_ERROR_*定义。

线程与同步:gsync 竞技场与 futex 🧵

线程层是 HLE 中最精巧的部分。游戏线程控制块(gsync::Thread)是游戏代码自己会读取的结构,bbhost 的 ThreadBody 必须恰好嵌进这 248 字节的槽位——static_assert直接约束了这一点。

同步原语则集中在 src/hle/sync.cpp:

  • 固定地址竞技场:sync arena 在0xE000000000处 mmap 出 64 MiB,因为游戏代码会按 40 位掩码解析互斥锁持有者地址,且垃圾句柄必须可识别并拒绝;
  • 跨平台 futex:锁等待底层走 core/futex.cpp,Windows 上映射到条件变量与事件,Linux 上用原生 futex;
  • 错误码换算:游戏使用 FreeBSD 风格的 errno,PS4 API 又期望0x8002xxxx错误格式,pthread.cpp 用一行sce()完成换算。

音频与视频:48 kHz 音频端口与 ATRAC9 影片 🔊

音频层很克制。src/hle/audio.cpp 用AudioPort结构跟踪每个sceAudioOut端口(采样率、声道、位深),端口数据最终送入宿主机音频(SDL3);而语音/麦克风相关 API 全部返回"成功但静音"的空实现,避免游戏代码在语音路径上空转。

影片播放由 src/hle/avplayer.cpp 负责:用 FFmpeg 解封装,音频用 third_party/libatrac9/ 解码 PS4 的 ATRAC9 格式,帧节奏与游戏翻帧同步,过场动画因此能和画面保持一致的速度。

网络与 NP:合作、入侵与召唤符在 PC 上如何工作 🌐

联机是 HLE 层里工程量最大的部分之一。《Bloodborne》的联机功能建立在 PS4 的 NP Matching2、Signaling、WebAPI 与 Auth 之上,bbhost 用私有服务器加 P2P UDP 完整替换了 FromSoftware 的原生服务(详见 docs/online.md):

  • 匹配:游戏的 Matching2 调用(创建/搜索/加入房间、成员事件)全部转发到私有服务器的会话服务——np_matching2.cpp 负责翻译,游戏规则本身仍由游戏代码决定;
  • 信号与打洞:np_signaling.cpp 实现 P2P 连接状态机,配合 src/net/stun.cpp 的 STUN 地址学习与 NAT 打洞;打洞失败时服务器可中转流量;
  • 跨平台套接字:src/hle/net.cpp 用一层薄抽象抹平 winsock 与 BSD socket 的差异(WSAGetLastError映射到 POSIX errno、WSAPoll对应poll),让同一套 HLE 代码在两个平台上行为一致。

公共服务器的连接参数写在bbhost.toml中:

[online] host = "thehuntersdream.com" scheme = "https" require_account = true

账号没有密码:PC 通过 Discord 或恢复码绑定账号,账号名即游戏内联机 ID(由 src/hle/system.cpp 的sceNpGetOnlineId应答)。

内核与内存:模拟 6 GiB PS4"直接内存" 💾

所有 HLE 模块的地基是 src/hle/kernel.cpp 实现的内存管理。PS4 向游戏暴露一块 6 GiB 的"直接内存"(direct memory),CPU 与 GPU 通过同一块物理内存访问。bbhost 的做法是:

  • 在 固定低位虚拟地址 上分配后备(Linux 用 memfd,Windows 用 section),因为 Gnm 地址是 40 位,地址必须落在特定窗口;
  • 维护 活跃映射快照,供 GPU 页表按需导入;
  • 提供 写监视 接口,让纹理缓存能侦测游戏对 GPU 内存的 CPU 侧写入——这是"没有任何调用告知过的内存变化"的唯一发现途径。

总结:一套可审计的系统库重写 ✅

HLE 层的工程特点可以概括为三点:沙箱化(游戏只够得到配置允许的目录与虚拟地址窗口)、可审计(未实现调用、文件缺失、崩溃路径都留下日志痕迹,如 hle_dl_panic 会顺带打印最近打开的文件清单)、双平台同构(一套代码靠薄抽象适配 Windows 与 Linux)。

想继续深入了解,建议按这个顺序阅读:

  • 运行与配置:docs/running.md
  • 联机实现细节:docs/online.md
  • 图形侧(HLE 的兄弟系统):docs/rendering.md
  • 游戏函数重写:docs/decomp.md

对 HLE 层源码感兴趣的读者,可以从 src/hle/hle.h 的入口接口读起,再沿着register_hle()的注册顺序逐个模块走一遍,基本就能看到全部 660 个系统调用是如何被接住的。

【免费下载链接】bbhost

Definitive Bloodborne PC Experience

项目地址:https://gitcode.com/gh_mirrors/bb/bbhost
点击查看免费下载

相关推荐

上一篇:Prisma 本地集群 MySQL 数据库直连(SQL Database Access)实战指南
下一篇:微信防撤回补丁实测:3分钟装好,撤回的消息再也拿不走了

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进