EmuMMC 额外系统内存补丁
问题描述
自 HOS 20.0.0 开始,任天堂浏览器需要在 applet 内存池中占用显著更多的内存。为了适应这一点,Atmosphère 在固件 20.0.0+ 上将 ExtraSystemMemoryForAtmosphere 从 40 MB 减少到 14 MB。
然而,在 emummc 模式 下运行时,由于 emummc 的运行性质,任天堂在线服务(浏览器、eShop、在线游戏)无论如何都是不可用的。这意味着为浏览器预留的额外内存被浪费了。
根本原因
在libraries/libmesosphere/source/board/nintendo/nx/kern_k_system_control.cpp中,GetAppletPoolSize() 函数原本是:
const size_t ExtraSystemMemoryForAtmosphere = kern::GetTargetFirmware() >= ams::TargetFirmware_20_0_0 ? 14_MB : 40_MB;
return base_pool_size - ExtraSystemMemoryForAtmosphere - KTraceBufferSize;
这段代码无条件地在 HOS 20.0.0+ 上减少了可用系统内存,而不管在线服务是否真的能够使用。
解决方案
此补丁在内核初始化时添加了 emummc 检测,并在 emummc 处于活动状态时为 Atmosphère 系统内存使用完整的 40 MB:
ALWAYS_INLINE bool IsEmummcActiveForInit() {
u64 value = 0;
smc::init::GetConfig(&value, 1, smc::ConfigItem::ExosphereEmummcType);
return value != 0;
}
// 在 GetAppletPoolSize() 中:
const bool is_emummc = IsEmummcActiveForInit();
const size_t ExtraSystemMemoryForAtmosphere = (is_emummc || kern::GetTargetFirmware() < ams::TargetFirmware_20_0_0) ? 40_MB : 14_MB;
影响
当运行 emummc 时(任意 HOS 版本):
ExtraSystemMemoryForAtmosphere= 40 MB- 为自制软件应用程序提供更多可用内存
- 为 Atmosphère 系统模块提供更多可用内存
- 浏览器/eShop 反正无法工作,因此没有功能损失
当在 HOS < 20.0.0 上运行 sysmmc 时:
- ExtraSystemMemoryForAtmosphere = 40 MB(不变)
- 当在 HOS 20.0.0+ 上运行 sysmmc 时:
- ExtraSystemMemoryForAtmosphere = 14 MB(不变)
- 浏览器和 eShop 保持完全功能
技术细节
Emummc 检测
补丁使用smc::ConfigItem::ExosphereEmummcType (65007)来查询 Exosphere 安全监视器以获取 emummc 状态:
在 sysmmc(系统 NAND)上运行时返回 0
当 emummc 处于活动状态时返回 1(或非零值)
此检查在内核初始化期间通过 smc::init::GetConfig() 执行。
内存布局
| Mode | HOS Version | ExtraSystemMemoryForAtmosphere |
|---|---|---|
| emummc | Any | 40 MB |
| sysmmc | < 20.0.0 | 40 MB |
| sysmmc | >= 20.0.0 | 14 MB |
为什么 emummc 不需要浏览器内存
EmuMMC 在一个独立的、离线的 NAND 分区/文件上运行。任天堂的认证服务器会验证主机的证书和 NAND 序列号,这些在使用 emummc 时无法匹配。这使得:
- eShop:无法访问(认证失败)
- 浏览器:功能受限/不可用(需要任天堂账户)
- 在线游戏:被禁止/屏蔽(证书不匹配)
因此,为这些服务预留额外的 applet 池内存是不必要的。
如何应用
Option 1: 使用 git apply
cd /path/to/atmosphere
git apply emummc-extra-system-memory.patchOption 2: 使用 patch 命令
cd /path/to/atmosphere
patch -p1 < emummc-extra-system-memory.patchOption 3: 手动编辑
Edit libraries/libmesosphere/source/board/nintendo/nx/kern_k_system_control.cpp:
- After
GetMemoryModeForInit()function (around line 51), add:
ALWAYS_INLINE bool IsEmummcActiveForInit() {
u64 value = 0;
smc::init::GetConfig(&value, 1, smc::ConfigItem::ExosphereEmummcType);
return value != 0;
}- In
GetAppletPoolSize()function, 替换:
const size_t ExtraSystemMemoryForAtmosphere = kern::GetTargetFirmware() >= ams::TargetFirmware_20_0_0 ? 14_MB : 40_MB;With:
const bool is_emummc = IsEmummcActiveForInit();
const size_t ExtraSystemMemoryForAtmosphere = (is_emummc || kern::GetTargetFirmware() < ams::TargetFirmware_20_0_0) ? 40_MB : 14_MB;Building
应用补丁后:
make clean
make mesosphere # Or full build: make修改后的 mesosphere 内核将包含在输出包中
Testing
- 在 HOS 20.0.0+ 上启动进入 emummc
- 验证系统成功启动
- 在自制软件应用程序中检查可用内存
- 确认与未打补丁版本相比,额外增加了约 26 MB 可用内存
Files Modified
libraries/libmesosphere/source/board/nintendo/nx/kern_k_system_control.cpp- 添加了
IsEmummcActiveForInit()辅助函数 - 修改了
GetAppletPoolSize()以使用支持 emummc 的逻辑
- 添加了
兼容性
- 兼容所有已应用 HOS 20.0.0+ 内存减少的 Atmosphère 版本
- 适用于 Erista 和 Mariko 硬件
- 对 sysmmc 操作无影响
安全性
- 无持久性固件更改
- 仅影响启动时的内核内存分配
- 在运行 sysmmc 时自动恢复原状
- 在 HOS < 20.0.0 上回退到原始行为
Generated for: Atmosphère custom fork
日期: 2025-12-01
补丁文件: emummc-extra-system-memory.patch
推荐使用Ultrahand一键配置:https://github.com/ppkantorski/Ultrahand-Overlay/releases/tag/v2.2.2
如需超频,推荐使用4IFIR:https://github.com/rashevskyv/4IFIR
thanks for @ppkantorski and @Cooler3D