Atmosphère CFW:任天堂Switch自定义固件完全指南
项目标题与描述
Atmosphère是一款针对任天堂Switch的定制化固件(CFW),旨在通过模块化组件全面替换和增强原厂系统功能。项目采用GPLv2开源协议,支持从1.0.0到20.1.0的所有Horizon系统版本,提供完整的系统重实现与深度定制能力。
功能特性
- 多层级系统替换:包含Fusée(一级加载器)、Exosphère(安全监视器)、Thermosphère(虚拟NAND支持)、Stratosphère(系统模块)和Troposphère(应用层补丁)五大核心组件
- 虚拟系统支持:通过emuMMC实现完整的虚拟NAND功能,支持SD卡和文件两种存储方式
- 多版本兼容:动态钩子技术实现单一载荷支持所有系统版本(1.0.0-20.1.0)
- 高级存储重定向:完全自定义/Nintendo目录路径,突破8字符长度限制
- 硬件级控制:提供完整的SDMMC驱动替代,支持eMMC与SD卡互操作
- 开源生态:基于GPLv2协议,集成多家开源项目成果
安装指南
系统要求
- 任天堂Switch主机(所有型号)
- MicroSD卡(FAT32格式)
- 支持RCM注入的设备或工具
安装步骤
- 下载最新Atmosphère版本包
- 解压文件到SD卡根目录
- 复制emuMMC组件到指定位置:
bash
make clean
make -j
./hactool.exe -t kip emummc.kip --uncompressed emummc_unpacked.kip
python2.7 tools/kip1converter.py emummc_unpacked.kip emummc.data
cat emummc.caps emummc.data > emummc.kipm
- 将生成的kipm文件放入
/bootloader/sys/
目录 - 通过RCM注入payload启动系统
依赖项
- devkitA64工具链
- libnx库
- FatFs文件系统模块
- bcl压缩库
使用说明
基础使用
系统启动后自动加载Atmosphère环境,可通过组合键访问系统菜单:
c
// 示例:虚拟系统初始化流程
void emummc_initialize() {
sdmmc_ensure_device_attached();
sdmmc_ensure_initialized();
mutex_lock_handler(FS_SDMMC_EMMC);
// ... 初始化虚拟NAND
}
虚拟系统配置
通过exosphere配置文件设置虚拟系统参数:
ini
[emummc]
emummc_type=1
emummc_id=0
fs_version=1200
storage_path=/emuMMC/raw1
API调用示例
c
// SDMMC读写操作示例
uint64_t sdmmc_wrapper_read(void *buf, uint64_t bufSize, int mmc_id,
unsigned int sector, unsigned int num_sectors) {
mutex_lock_handler(mmc_id);
int res = sdmmc_storage_read(&storage, sector, num_sectors, buf);
mutex_unlock_handler(mmc_id);
return res;
}
核心代码
系统初始化模块
c
/*
* 系统初始化入口点
* 负责内存分配、钩子安装和路径设置
*/
void __init() {
__initheap(); // 初始化堆内存
text_base = (uintptr_t)&_start; // 获取代码基地址
fs_offsets = get_fs_offsets(FS_VER_2000); // 获取FS偏移量
// 安装系统钩子
setup_hooks();
setup_nintendo_paths();
// 初始化SDMMC控制器
sdmmc_initialize();
}
虚拟存储控制器
c
/*
* emuMMC虚拟存储实现
* 支持分区和文件两种虚拟化方式
*/
int emummc_storage_read(sdmmc_storage_t *storage, u32 sector,
u32 num_sectors, void *buf) {
if (emummc_ctx.EMMC_Type == emuMMC_SD_File) {
// 文件模式读取
return file_based_read(sector, num_sectors, buf);
} else {
// 分区模式读取
return sdmmc_storage_read(storage,
emummc_ctx.EMMC_StoragePartitionOffset + sector,
num_sectors, buf);
}
}
内存管理核心
c
/*
* DMA地址计算与缓冲区管理
* 确保内存访问符合SDMMC控制器要求
*/
intptr_t sdmmc_calculate_dma_addr(sdmmc_accessor_t *_this,
void *buf, unsigned int num_sectors) {
char *_buf = (char *)buf;
char *actual_buf_end = &_buf[512 * num_sectors];
// 检查DMA缓冲区边界
for (int i = 0; i < 2; i++) {
char *dma_buffer_start = _this->parent->dmaBuffers[i].device_addr_buffer;
if (dma_buffer_start <= _buf &&
actual_buf_end <= &dma_buffer_start[_this->parent->dmaBuffers[i].device_addr_buffer_size]) {
return i; // 返回合适的DMA缓冲区索引
}
}
return -1; // 无合适缓冲区
}