bbhost HLE Layer 实现解析:PS4 系统库的 PC 版重写——文件、线程、音频、网络与 NP
【免费下载链接】bbhost
Definitive Bloodborne PC Experience
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.cpp | C 标准库与线程 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
相关推荐
5000 行 C 代码干掉整个 PS4 系统库:HLE 运行时怎么让原版血源直接在 PC 上跑
5000 行 C 代码干掉整个 PS4 系统库:HLE 运行时怎么让原版血源直接在 PC 上跑 2026 年秋,《血源诅咒》——这款独占 PS4 超过十年的作品
逆向工程图形学系统编程从零重写一整套PS4系统库:driveclub-recomp的libkernel再实现(线程、互斥锁、信号量与TLS)实战解读
从零重写一整套PS4系统库:driveclub recomp的libkernel再实现(线程、互斥锁、信号量与TLS)实战解读 driveclub recomp
gow3_pc运行时原理:387个PS4系统API如何被逐一重写,从音频到存档全实现
gow3_pc运行时原理:387个PS4系统API如何被逐一重写,从音频到存档全实现 gow3_pc 是一个《战神3 重制版》(God of War III R
逆向工程图形学游戏开发
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考