Skip to content

MemoryHack Patch & for Any CFWPack

Latest

Choose a tag to compare

@sskyNS sskyNS released this 08 Dec 11:27
· 5 commits to master since this release

EmuMMC 额外系统内存补丁

问题描述

自 HOS 20.0.0 开始,任天堂浏览器需要在 applet 内存池中占用显著更多的内存。为了适应这一点,Atmosphère 在固件 20.0.0+ 上将 ExtraSystemMemoryForAtmosphere40 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.patch

Option 2: 使用 patch 命令

cd /path/to/atmosphere
patch -p1 < emummc-extra-system-memory.patch

Option 3: 手动编辑

Edit libraries/libmesosphere/source/board/nintendo/nx/kern_k_system_control.cpp:

  1. 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;
}
  1. 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

  1. 在 HOS 20.0.0+ 上启动进入 emummc
  2. 验证系统成功启动
  3. 在自制软件应用程序中检查可用内存
  4. 确认与未打补丁版本相比,额外增加了约 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