Changes the formatting of the key values at `Code Type 0xC4: Begin Extended Keypress Conditional Block` in cheats.md so that it is perfectly clear that those values are 64-bit values rather than 32-bit or 28-bit like `Code Type 0x8: Begin Keypress Conditional Block`, and also for the fact that the formatting matches the rest of the document and is thus cleaner.
Starting in 20.0.0, the browser needs more applet memory to function, so we can't steal as much any more.
Thus, we now steal 14 MB on 20.0.0+ instead of 40MB.
However, since this reduces memory available for custom system modules, we are adjusting to compensate.
ams.mitm's heap size has been reduced from 32MB to 12MB (recovering 20MB).
In addition, fs.mitm now uses a new mechanism for stealing memory from the applet pool while romfs is being built.
On net, we are compromising:
* Custom sysmodules lose memory available to them.
On 19.0.0/AMS 1.8.0, there was 30 MB available for custom sysmodules.
Stealing 14 MB instead of 40 MB, we lose 26 MB of that. Reducing ams.mitm's usage will gain us back 20.
Nintendo also appears to...use 4 extra MB, in 20.0.0, from my test homebrew.
So on 20.0.0/AMS 1.9.0, there should be 20 MB available for custom sysmodules.
On the bright side, on <20.0.0/AMS 1.9.0, I guess there will be 50 MB available for custom sysmodules now?
* totk mods will lose the ability to...put every file in the romfs on sd card. There will be some unknown maximum filecount for totk mods.
On the bright side, implementing the transient memory stealing should improve compatibility for some mods which strictly add files?
Also, fix a few very embarassing mistakes in kernel ldr:
* We have been mapping the page table region RWX for a few years now, accidentally.
* My attempt at making initial page tables not use bit 58 was broken in multiple ways.
* dmnt_extension
* update type 8 extension
* clearify that bit 27 does not correspond to a button
* update cheat.md with new code type 0xC4
* implement code type 0xC4
* Add type 1 extension
* remove C0Tcr6Ma aaaaaaaa VVVVVVVV (VVVVVVVV)
* Type 9 extension for floating point math
* updated according to review
This change was made for #2255, but the issue creator never confirmed if it resolved the issue.
This *does* better reflect what Nintendo's pm does, though, so I'm going to commit it regardless.
Parsing the SD fs is very slow. In addition, the only KIPs are either a) atmosphere modules, or b) FS.
The IPS subsystem was originally designed to make nogc/etc patches work for FS,
but these are now internal, and it appears that the literal only kip patches
that exist are for piracy.
It just doesn't make sense to slow down boot for every normal user for a feature
that has no actual usecase, and especially when fusee is already so minimal.
Static save files do not require an entry in the save data indexer to mount.
Prior to 17.0.0, save data files were considered static if userid was 0.
In 17.0.0+, only 8000000000000000 is static.
However, some users using cfw do not have an entry for 8000000000000120 in the indexer,
for various reasons (but mostly manual nand-restore, I think). Thus, on boot of 17.0.0+,
FS will say 8000000000000120 is not present (not in indexer), and NCM will create it anew.
The 8000000000000120 save will then be empty, and then the firmware can't boot.
To workaround this, logic has been re-enabled on 17.0.0+ for building the content meta database.
Thus, if the user encounters this error, the 8000000000000120 save will be emptied, but then
it will be automatically reconstructed, fixing the problem.
* fs.mitm: skeleton the use of special allocation in romfs build
* pm: add api for ams.mitm to steal application memory
* pm/mitm: okay, that api won't work, try a different one
* romfs: revert memory usage increases; we'll handle torture games case-by-case.
* pm/romfs: first (broken?) pass at dynamic heap.
I cannot wait to figure out all the ways this is wrong.
* Release the dynamic heap a little more eagerly
* romfs: animal crossing is also not a nice game
* romfs: fix issues in close-during-build
* romfs: zelda is a blight upon this earth
* ams_mitm: add ability to mirror bluetooth device pairing database to sd card via a system setting
* ams_mitm: address requested stylistic changes
* ams_mitm: make use of R_SUCCEED macro
* ams_mitm: use settings::BluetoothDevicesSettings instead of libnx type
* ams_mitm: fix logic error when truncating pairing database on read
* Update .ini comment
* ams_mitm: missing R_TRY around call to fs::FlushFile
* stratosphere: remove union from BluetoothDevicesSettings type
---------
Co-authored-by: ndeadly <24677491+ndeadly@users.noreply.github.com>
This causes all data to be emitted as .data$*. This breaks fzero-initialized-in-bss,
because linker puts stuff in .data even when it's all-zero and should end up in .bss.
* Setting retrieval was performed before the call that used the setting.
* Call to detect number of files passed incomplete path and was guaranteed to fail.
* Call to delete reports passed incomplete path and was guaranteed to do nothing.
This implements two optimizations on fs::Path, which N added in 12.0.0.
The current structure looks like:
```cpp
struct Path {
const char *m_str; // Points to the read-only path string
char *m_write_buffer_buffer; // Part of std::unique_ptr<char[], ams::fs::impl::Deleter>
ams::fs::impl::Deleter m_write_buffer_deleter; // Parse of std::unique_ptr<char[], ams::fs::impl::Deleter>, stores the size of the buffer.
size_t m_write_buffer_length; // Copy of the write buffer's size accessible to the Path() structure.
bool m_is_normalized; // Whether the path buffer is normalized
};
```
This is pretty wasteful. The write buffer size is stored twice, wasting 8 bytes, because one copy of the size isn't accessible to the path.
In addition, due to alignment, the bool wastes 7 padding bytes.
This commit:
* Encodes normalized in the low bit of the write buffer length, saving 8 bytes.
* Use a custom WriteBuffer class rather than generic unique_ptr, to avoid needing to store the WriteBuffer twice.
These each save 8 bytes, for a final size of 0x18 rather than 0x28.
* result: try out some experimental shenanigans
* result: sketch out some more shenanigans
* result: see what it looks like to convert kernel to use result conds instead of guards
* make rest of kernel use experimental new macro-ing
* Work around Clang's incomplete C++20 support for omitting typename
* vapours: fix Clang error about missing return in constexpr function
* stratosphere: fix call to non-constexpr strlen in constexpr function
strlen being constexpr is a non-compliant GCC extension; Clang
explicitly rejects it: https://reviews.llvm.org/D23692
* stratosphere: add a bunch of missing override specifiers
* stratosphere: work around Clang consteval bug
Minimal example: https://godbolt.org/z/MoM64v93M
The issue seems to be that Clang does not consider f(x) to be a
constant expression if x comes from a template argument that isn't
a non-type auto template argument (???)
We can work around this by relaxing GetMessageHeaderForCheck (by using
constexpr instead of consteval). This produces no functional changes
because the result of GetMessageHeaderForCheck() is assigned to a
constexpr variable, so the result is guaranteed to be computed
at compile-time.
* stratosphere: fix missing require clauses in definitions
GCC not requiring the require clauses to be repeated for member
definitions is actually a compiler bug:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96830
Clang rejects declarations with missing require clauses.
* Fix ALWAYS_INLINE_LAMBDA and parameter list relative order
While GCC doesn't seem to care about the position of the always_inline
attribute relative to the parameter list, Clang is very picky
and requires the attribute to appear after the parameter list
(and before a trailing return type)
* stratosphere: fix static constexpr member variable with incomplete type
GCC accepts this for some reason (because of the lambda?) but Clang
correctly rejects this.
This is needed for Animal Crossing 2.0.0, which has >99000 fucking files.
We now do several passes over dir/file tables instead of one pass,
doing entire hash tables before we touch dir/file tables. Thus we
no longer need to simultaneously allocate hash table and dir/file table space.
In addition, we now do repeated passes building a segment of hash tables
at a time, when insufficient memory is available. Similar is also now the
case for file/dir tables, we try 0x40000 work buffer and divide by 2
until we successfully alloc. We don't allow a work buffer <0x4000, for
write/perf reasons. If a game triggers that, let me know I guess.
Hard to imagine a worse torture-test for this code than animal crossing.
Nintendo used to do what we were doing because the function wasn't directly in the handler table,
but we've always been directly in the handler table, so we were trashing the last four arguments to light ipc
when called from aarch32. Nothing uses this, but needed to be fixed.
This is an optimization that saves the most common type of virtual call in the kernel (DynamicCast)
by storing class token as a member, rather than getting it via virtual call every time.
This does not currently cost any memory space on 64-bit targets, due to pre-existing padding space.
This optimization can be turned off via a compile-time flag for accuracy.
Homebrew which would hang when doing this were compiled with libnx < 3.0.0.
Homebrew which is compiled with < 3.0.0 cannot send messages to sm, because
of the incorrect serialization problem (which required homebrew recompile when
12.0.0 released).
Thus, there is no case where this makes a difference.
Nintendo does this as of latest firmware.
It's desirable because it removes the only usage of util::SNPrintf() from os library,
which means programs which don't otherwise use SNPrintf do not need to link it into .text.
This saves ~0xD40 of .text as of time-of-commit when successfully unlinking, and e.g.
reduces our sm (and other modules) memory size by a page.
Some notes:
* Unless `atmosphere!enable_log_manager` is true, Nintendo's log manager will be used instead.
* This prevents paying memory costs for LM when not enabling logging.
* To facilitate this, Atmosphere's log manager has a different program id from Nintendo's.
* `atmosphere!enable_htc` implies `atmosphere!enable_log_manager`.
* LogManager logs to tma, and the SD card (if `lm!enable_sd_card_logging` is true, which it is by default).
* Binary logs are saved to `lm!sd_card_log_output_directory`, which is `atmosphere/binlogs` by default.
mtc will jump back to us, so we need a compatible binary.
This also makes some changes to our layout to minimize the likelihood of
an incompatible mtc binary (I made some arbitrary .text/.rodata/.rwdata changes)
and saw identical mtc binaries, so hopefully this all works out.
Nintendo's Mariko tables result in trained frequency of 1599999 instead of 1600000.
PCV checks for rate == 1600000 exactly, when doing EMC init.
Thus EMC init does not succeed if we are trained to 1600000.
PCV has a fudge factor of 1000 used in SetEmcDvfsFreq, but this is not used in InitEmcDvfs.
This failure means that PCV cannot change rate back to 204MHz before sleep, and then after
wake extremely degraded performance is observed.
Restoring DRAM to 204MHz before boot causes EMC init to succeed/fixes performance degradation.
* ams: replace sept with tsec firmware
This replaces sept with a custom tsec key derivation firmware.
NOTE: This does not use any TSEC exploits whatsoever; it is a well-signed
TSEC binary assembled with envyas and signed with the real cauth key.
For more details, contact SciresM#0524.
* fusee: only set SBK if it's readable
* docs: update cheats doc to clarify Code Type 5 encoding
This change removes references to the "M" nibble for the "Register Address" encoding of Code Type 5 whis is not used in this mode.
In the dword block the "M" has been replaced with a "0"
* docs: update cheats doc to clarify register usage on Code Type 5
This adds additional clarification for "Register Address Encoding" mode of Code Type 5 that the "R" nibble reflects both the destination as well as the base memory address.
* docs: update cheats doc to make Code Types consistent
Code Types are now consistently written in hex notation.
* cs: add stub sysmodule to host command shell server
* cs: implement logic for main (linker error paradise, for now)
* cs: implement more of the system module's skeleton
* htcs: update client type names for libnx pr merge
* set.mitm: fake compatibility for usb!usb30_force_enabled on 9.0.0+
* set.mitm: add value meaning comment for usb!usb30_force_enabled
* loader: pretend to be polite about patch ordering
* sdmmc: begin skeletoning sdmmc driver
* sdmmc: add most of SdHostStandardController
* sdmmc: implement most of SdmmcController
* sdmmc: Sdmmc2Controller
* sdmmc: skeleton implementation of Sdmmc1Controller
* sdmmc: complete abstract logic for Sdmmc1 power controller
* sdmmc: implement gpio handling for sdmmc1-register-control
* sdmmc: implement pinmux handling for sdmmc1-register-control
* sdmmc: fix building for arm32 and in stratosphere context
* sdmmc: implement voltage enable/set for sdmmc1-register-control
* util: move T(V)SNPrintf from kernel to util
* sdmmc: implement BaseDeviceAccessor
* sdmmc: implement MmcDeviceAccessor
* sdmmc: implement clock reset controller for register api
* sdmmc: fix bug in WaitWhileCommandInhibit, add mmc accessors
* exo: add sdmmc test program
* sdmmc: fix speed mode extension, add CheckMmcConnection for debug
* sdmmc: add DeviceDetector, gpio: implement client api
* gpio: modernize client api instead of doing it the lazy way
* sdmmc: SdCardDeviceAccessor impl
* sdmmc: update test program to read first two sectors of sd card
* sdmmc: fix vref sel
* sdmmc: finish outward-facing api (untested)
* ams: changes for libvapours including tegra register defs
* sdmmc: remove hwinit
Before the MMU is up, all reads/writes must be aligned; the optimized
memcpy implementation does not guarantee all reads/writes it performs
are aligned.
This commit splits the libc impl to be separate for kernel/kernel_ldr,
and so now only kernel will use the optimized impl. This is safe,
as the MMU is brought up before kernel begins executing.
* sf: Begin experimenting with new interface declaration format
* sf: convert fs interfaces to new format
* sf: finish conversion of libstrat to new definitions
* sf: convert loader to new format
* sf: convert spl to new format
* sf: update ncm for new format
* sf: convert pm to new format
* sf: convert ro/sm to new format
* sf: update fatal for new format
* sf: support building dmnt under new scheme
* sf: update ams.mitm for new format
* sf: correct invocation def for pointer holder
* fs: correct 10.x+ user bindings for Get*SpaceSize
* ams: update to build with gcc10/c++20
* remove mno-outline-atomics
* ams: take care of most TODO C++20s
* fusee/sept: update for gcc10
* whoosh, your code now uses pre-compiled headers
* make: dependency fixes
10.x FS now receives a transfer memory to wipe BIS with and maps it.
This requires SVCs that emummc did not give itself access to.
This commit adds them, which prevents a FS process abort on re-init.
0.11.2 will release sometime in the next week or two or so.
I am writing this now while I remember all the things that have happened,
so that I don't forget about them when release comes.
There is also a PR for dmnt changes that will be merged into 0.11.2 not included here,
and there may be more changes before the release occurs.
This was needed to make stratosphere buildable with debugging on.
os:: assertions rely on GetCurrentThread() working, and this requires
the global os resource manager to be constructed. However, __appInit executes
before global constructors. We now require that hos::InitializeForStratosphere()
be called before anything else is done. This initializes the os resource manager,
sets the hos version for libnx, and may do more things in the future.
TODO: Consider replacing __appInit/__appExit with ams:: namespace functions in general,
and wrap them so that we guarantee hos::InitializeForStratosphere is called first, and
generally ensure a consistent stratosphere environment.
This was tested using `https://github.com/node-dot-cpp/alloc-test` plus a few other by-hand tests.
It seems to work for the case we care about (sysmodules without thread cache-ing).
External users are advised to build with assertions on and contact SciresM if you find issues.
This is a lot of code to have gotten right in one go, and it was written mostly after midnight while sick, so there are probably un-noticed issues.
The call to serviceCreate(...) tries to query pointer buffer size, but
since we haven't had a chance to return the server side of the session
yet, this deadlocks. Instead, we defer creating the session and
mounting the filesystem until the first time the ECS object is
used. If mounting the filesystem fails, the ECS is silently discarded.
Previously, we were only setting resource limit,
which didn't modify actual reserved pool size for
the system pool. This adds kernel patches which reduce
the applet pool size, granting the extra memory to
the system partition. The given value has been chosen
specifically to allow normal applet usages. Further
reduction may result in crashes during normal applet usage.
namespace sts::ams -> ams::exosphere, ams::.
This is to facilitate future use of ams:: namespace code in
mesosphere, as we'll want to include ams::util, ams::result, ams::svc...
Because I was working on multiple things at once, this commit also:
- Adds wrappers for/linker flags to wrap CXX exceptions to make them
abort. This saves ~0x8000 of memory in every system module.
- Broadly replaces lines of the pattern if (cond) { return ResultX; }
with R_UNLESS(!cond, ResultX());.
- Reworks the R_TRY_CATCH macros (and the result macros in general).
This implements waitable management for Events (and
implements Events). It also refactors PM to use new
Event/Waitable semantics, and also adds STS_ASSERT
as a macro for asserting a boolean expression. The
rest of stratosphere has been refactored to use
STS_ASSERT whenever possible.
The previous string construction discards two temporary std::string
instances (operator+ returns by value, not by reference), and creates a
std::string that it doesn't need to (the one around key). Instead we can
just append to the end of the initial std::string itself, saving on two
unnecessary created strings.
append() has a const char* overload as well (as does operator+), so we
can just append the key string as is without creating an entire new
string.
We can use a std::string here instead of setting up a scope guard and
manual allocations. We also don't need to care about null-termination,
as c_str() will automatically ensure this is done when passing it into
ini_parse_string().
* Implement Auto Reboot Timer (#518)
* Use > to check for values below -1
* Use TimeoutHelper and accept MS
* Add fatal_auto_reboot_interval into config (commented)
* Check for 0
Specifying 0 as the initial entry of a structure is a C-ism. C++ permits
using an empty set of braces to signify the same behavior, silencing
missing initializer warnings.
- individually listed packages required when using (dkp-)packman.
- added sept dependencies
- added requirement to use -r flag
- added recommendation for zip (for use if someone wants to make dist)
* fs.mitm: Fix mismatched new[] / delete
Using delete instead of delete[] on a pointer given by new[] is
undefined behaviour.
For memory sources, malloc/free are used because cleaning up is tricky
when data can be either allocated with new (RomfsHeader) or new[]
(metadata).
* set.mitm: Fix mismatched new[] / delete
about: Something doesn't work correctly in Atmosphère.
#assignees:
---
## Bug Report
[ If any section does not apply, replace its contents with "N/A". ]</br>
[ Lines between [ ] (square brackets) should be removed before posting. ]</br>
[ * ]</br>
[ Note: If the bug or crash you encountered is related to; ]</br>
[ - software used to make "backups", ]</br>
[ - software explicitly distributed for piracy, etc ]</br>
[ then contributors will not provide support for your issue and your issue will be closed. ]</br>
### What's the issue you encountered?
[ Describe the issue in detail and what you were doing beforehand. ]</br>
[ Did you make any changes related to Atmosphère itself? ]</br>
[ If so, make sure to include details relating to what exactly you changed. ]</br>
### How can the issue be reproduced?
[ * ]</br>
[ Include a detailed step by step process for recreating your issue. ]</br>
### Crash Report
[ Crash reports can be found under ``/atmosphere/crash_reports``. ]</br>
[ If your issue caused Atmosphère to crash, include the crash report(s) by creating a [gist](https://gist.github.com/) and pasting the link here. ]</br>
[ If you don't include a crash report in instances of crash related issues, we will ask you one to provide one. ]</br>
### System Firmware Version
X.X.X</br>
[ Replace X's with system firmware version at time of crash. ]</br>
[ You can find your firmware version in the Settings -> System, under "System Update". ]</br>
[ If it says "Update Pending", you can clear the pending update by rebooting to Maintenance Mode. ]</br>
### Environment?
- What bootloader (fusèe, hekate, etc) was Atmosphère launched by:
- Official release or unofficial build:
- [ Official release version x.x.x (or) unofficial build ]
- [ If using an unofficial build, include details on where/how you acquired the build. ]
- [ Ex: Self-compilation ]
- [ Ex: Kosmos' distribution of Atmosphère ]
- Do you have additional kips or sysmodules you're loading:
- Homebrew software installed: [ * ]
- EmuMMC or SysNAND:
- [ If using an EmuMMC, include whether it's partition-based or file-based. ]
### Additional context?
- Additional info about your environment:
- [ Any other information relevant to your issue. ]
[ If any section does not apply, replace its contents with "N/A". ]</br>
[ If you do not have the information needed for a section, replace its contents with "Unknown". ]</br>
[ Lines between [ ] (square brackets) are to be removed before posting. ]
[ Please search for existing [feature requests](https://github.com/Atmosphere-NX/Atmosphere/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3A%22features%2Ffeature-request%22) before you make your own request. ]</br>
[ Duplicate requests will be marked as such and you will be referred to the original request. ]
### What feature are you suggesting?
#### Overview:
- [ Include the basic, high-level concepts for this feature here. ]</br>
#### Smaller Details:
- [ These may include specific methods of implementation etc. ]</br>
#### Nature of Request:
[ Remove all that do not apply to your request. ]
- Addition
- [ Ex: Addition of certain original features or features from other community projects. ]
- [ If you are suggesting porting features or including features from other projects, include what license they are distributed under and what, if any libraries those project use. ]
- Change
- Removal
- [Ex: Removal of certain features or implementation due to a specific issue/bug or because of low quality code, etc.]
### What component do you feel this would best fit within?
[](https://discordapp.com/invite/ZdqEhed)

Atmosphère is a work-in-progress customized firmware for the Nintendo Switch.
Atmosphère is a work-in-progress customized firmware for the Nintendo Switch.
@ -17,19 +19,30 @@ Atmosphère consists of multiple components, each of which replaces/modifies a d
* Stratosphère: Custom Sysmodule(s), both Rosalina style to extend the kernel/provide new features, and of the loader reimplementation style to hook important system actions
* Stratosphère: Custom Sysmodule(s), both Rosalina style to extend the kernel/provide new features, and of the loader reimplementation style to hook important system actions
* Troposphère: Application-level Horizon OS patches, used to implement desirable CFW features
* Troposphère: Application-level Horizon OS patches, used to implement desirable CFW features
Licensing
=====
This software is licensed under the terms of the GPLv2, with exemptions for specific projects noted below.
You can find a copy of the license in the [LICENSE file](LICENSE).
Exemptions:
* [Nintendo](https://github.com/Nintendo) is exempt from GPLv2 licensing and may (at its option) instead license any source code authored for the Atmosphère project under the Zero-Clause BSD license.
Credits
Credits
=====
=====
Atmosphère is currently being developed and maintained by __SciresM__, __TuxSH__ and __hexkyz__.<br>
Atmosphère is currently being developed and maintained by __SciresM__, __TuxSH__, __hexkyz__, and __fincs__.<br>
In no particular order, we credit the following for their invaluable contributions:
In no particular order, we credit the following for their invaluable contributions:
* __switchbrew__ for the [libnx](https://github.com/switchbrew/libnx) project and the extensive [documentation, research and tool development](http://switchbrew.org) pertaining to the Nintendo Switch.
* __switchbrew__ for the [libnx](https://github.com/switchbrew/libnx) project and the extensive [documentation, research and tool development](http://switchbrew.org) pertaining to the Nintendo Switch.
* __devkitPro__ for the [devkitA64](https://devkitpro.org/) toolchain and libnx support.
* __devkitPro__ for the [devkitA64](https://devkitpro.org/) toolchain and libnx support.
* __ReSwitched Team__ for additional [documentation, research and tool development](https://reswitched.tech/) pertaining to the Nintendo Switch.
* __ReSwitched Team__ for additional [documentation, research and tool development](https://reswitched.github.io/) pertaining to the Nintendo Switch.
* __ChaN__ for the [FatFs](http://elm-chan.org/fsw/ff/00index_e.html) module.
* __ChaN__ for the [FatFs](http://elm-chan.org/fsw/ff/00index_e.html) module.
* __Marcus Geelnard__ for the [bcl-1.2.0](https://sourceforge.net/projects/bcl/files/bcl/bcl-1.2.0) library.
* __Marcus Geelnard__ for the [bcl-1.2.0](https://sourceforge.net/projects/bcl/files/bcl/bcl-1.2.0) library.
* __naehrwert__ and __st4rk__ for the original [hekate](https://github.com/nwert/hekate) project and its hwinit code base.
* __naehrwert__ and __st4rk__ for the original [hekate](https://github.com/nwert/hekate) project and its hwinit code base.
* __CTCaer__ for the continued [hekate](https://github.com/CTCaer/hekate) project's fork.
* __CTCaer__ for the continued [hekate](https://github.com/CTCaer/hekate) project's fork and the [minerva_tc](https://github.com/CTCaer/minerva_tc) project.
* __m4xw__ for development of the [emuMMC](https://github.com/m4xw/emummc) project.
* __Riley__ for suggesting "Atmosphere" as a Horizon OS reimplementation+customization project name.
* __Riley__ for suggesting "Atmosphere" as a Horizon OS reimplementation+customization project name.
* __hedgeberg__ for research and hardware testing.
* __hedgeberg__ for research and hardware testing.
* __lioncash__ for code cleanup and general improvements.
* __lioncash__ for code cleanup and general improvements.
The process for building Atmosphère is similar to building Fusée Gelée payloads and other Switch apps.
Building Atmosphère is a very straightforward process that relies almost exclusively on tools provided by the [devkitPro](https://devkitpro.org) organization.
In order to build Atmosphère you must have devkitARM and devkitA64 installed on your computer. You can find instructions on how to install and setup devkitARM and devkitA64 on various OSes [here](https://devkitpro.org/wiki/Getting_Started).
## Dependencies
+ [devkitA64](https://devkitpro.org)
+ [devkitARM](https://devkitpro.org)
+ [Python 2](https://www.python.org) (Python 3 may work as well, but this is not guaranteed)
Exosphère is a reimplementation of Arm's TrustZone (TZ), also known as Secure Monitor (Secure_Monitor.bin). It has the highest privilege mode available on the Switch’s processor, and has access to everything on the console.
exosphère is a customized reimplementation of the Horizon OS's Secure Monitor.
The Secure Monitor follows the same design principle as Arm's TrustZone and both terms can be used interchangeably in this context. It runs at the highest privilege mode (EL3) available to the main processor and is responsible for all the sensitive cryptographic operations needed by the system as well as power management for each CPU.
Exosphère will potentially play a big role in Jamais Vu and Déja Vu, which are upcoming software exploits for the Switch, allowing one to launch Atmosphère on a Fusée-Gélee patched (ipatched) Switch console, and will also enable one to launch into CFW directly from the Switch itself without the use of any sort of external device, such as a computer or RCM jig, provided they are on a low enough system firmware.
## TrustZone/Secure Monitor
TrustZone is responsible for all the cryptographic operations on the Switch. The idea behind the way it operates is that all the keys stay in the TrustZone, and userspace only gets "handles" to them. This would make sure that keydata never leaks and is kept secure. It also has a few more responsibilities, such as power management, providing a source of random numbers, and providing access to various pieces of information that are stored in the fuses.
## Extensions
## Extensions
Exosphère currently only contains one extension, an SMC allowing homebrew to find which version of Atmosphère is currently running, in order to find out what extensions are allowed to be used.
exosphère expands the original Secure Monitor design by providing custom SMCs (Secure Monitor Calls) necessary to the homebrew ecosystem. Currently, these are:
Additionally, exosphère expands the functionality of two SMCs provided by the Horizon OS for getting/setting configuration items. The following custom configuration items are provided by exosphère:
```
CONFIGITEM_EXOSPHERE_VERSION = 65000,
CONFIGITEM_NEEDS_REBOOT = 65001,
CONFIGITEM_NEEDS_SHUTDOWN = 65002,
CONFIGITEM_EXOSPHERE_VERHASH = 65003,
CONFIGITEM_HAS_RCM_BUG_PATCH = 65004,
CONFIGITEM_SHOULD_BLANK_PRODINFO = 65005,
CONFIGITEM_ALLOW_CAL_WRITES = 65006,
```
### smc_ams_iram_copy
This function implements a copy of up to one page between DRAM and IRAM. Its arguments are:
```
args->X[1] = DRAM address (translated by kernel), must be 4-byte aligned.
args->X[2] = IRAM address, must be 4-byte aligned.
args->X[3] = Size (must be <= 0x1000 and 4-byte aligned).
args->X[4] = 0 for read, 1 for write.
```
### smc_ams_write_address
This function implements a write to a DRAM page. Its arguments are:
```
args->X[1] = Virtual address, must be size-bytes aligned and readable by EL0.
args->X[2] = Value.
args->X[3] = Size (must be 1, 2, 4, or 8).
```
### smc_ams_get_emummc_config
This function retrieves configuration for the current [emummc](emummc.md) context. Its arguments are:
```
args->X[1] = MMC id, must be size-bytes aligned and readable by EL0.
args->X[2] = Pointer to output (for paths for filebased + nintendo dir), must be at least 0x100 bytes.
```
### CONFIGITEM_EXOSPHERE_VERSION
This custom configuration item gets information about the current exosphere version.
### CONFIGITEM_NEEDS_REBOOT
This custom configuration item is used to issue a system reboot into RCM or into a warmboot payload leveraging a secondary vulnerability to achieve code execution from warm booting.
### CONFIGITEM_NEEDS_SHUTDOWN
This custom configuration item is used to issue a system shutdown with a warmboot payload leveraging a secondary vulnerability to achieve code execution from warm booting.
### CONFIGITEM_EXOSPHERE_VERHASH
This custom configuration item gets information about the current exosphere git commit hash.
### CONFIGITEM_HAS_RCM_BUG_PATCH
This custom configuration item gets whether the unit has the CVE-2018-6242 vulnerability patched.
### CONFIGITEM_SHOULD_BLANK_PRODINFO
This custom configuration item gets whether the unit should simulate a "blanked" PRODINFO. See [here](../features/configurations.md) for more information.
### CONFIGITEM_ALLOW_CAL_WRITES
This custom configuration item gets whether the unit should allow writing to the calibration partition.
## lp0fw
This is a small, built-in payload that is responsible for waking up the system during a warm boot.
## sc7fw
This is a small, built-in payload that is responsible for putting the system to sleep during a warm boot.
## rebootstub
This is a small, built-in payload that provides functionality to reboot the system into any payload of choice.
fusée is a custom bootloader used to start the Atmosphère environment.
## fusée
fusée is the first piece of Atmosphère's code that runs on the hardware.
It is distributed as a standalone payload designed to be launched via RCM by abusing the CVE-2018-6242 vulnerability.
This payload is responsible for all the low-level hardware initialization required by the Nintendo Switch, setting up the cryptosystem, mounting/emulating the eMMC, injecting/patching system modules, and launching the exosphère component.
BCT.ini is the configuration file used by fusée-primary and fusée-secondary. It is read by fusee-primary.bin to setup and boot fusee-secondary.bin and is also read by fusee-secondary.bin to configure Exosphère or to specify the environment it should boot.
## Configuration
This file is located at the root of your SD.
```
BCT0
[stage1]
stage2_path = fusee-secondary.bin
stage2_addr = 0xF0000000
stage2_entrypoint = 0xF0000000
```
Add the following lines and replace the `X` according to the following list if you have trouble booting past the firmware version detection.
Fusée (not to be confused with Fusée Gelée) is a custom bootloader needed to start Atmosphère and replaces Nintendo's Package1loader/bootloader. It currently utilizes the [Tegra X1 RCM Vulnerability](https://nvidia.custhelp.com/app/answers/detail/a_id/4660/~/security-notice%3A-nvidia-tegra-rcm-vulnerability) in order to function.
Fusée is split into two separate parts: fusée-primary and fusée-secondary. This is due to the RCM Vulnerability only allowing payloads of a limited filesize to be sent to the device.
As of June 2018, there are new Switch systems being sold that prevent Fusée (or any payload that requires the Fusée Gelée exploit) from working due to having an ipatched bootrom. All ipatched systems share the HAC-S-JXE-C3 product code. While Fusée cannot work on these ipatched units, they still come on firmware 4.1.0, which is vulnerable to the upcoming Déja Vu software exploit. Note that if you update past 4.1.0 on one of these ipatched units, your odds of being able to install Atmosphère or run any homebrew become practically non-existent.
Additionally, a hardware revision of the Switch known as “Mariko” is believed to be in development. No such units have been seen in stores yet, but it is expected Nintendo will roll them out silently. The Mariko units will most likely patch the bootrom vulnerability Fusée Gelée, which is currently used to access CFW, and will likely have their own proprietary bootloader.
## Fusée-Primary
Fusée-primary is the payload file (fusee-primary.bin) sent to the Switch from an external device. Once sent, fusée-primary makes initial preparations before loading fusée-secondary from the Switch’s SD Card.
Fusée-primary can be configured via the [BCT.ini](../fusee/BCT.md) file located on the Switch’s SD card.
## Fusée-Secondary
Fusée-secondary is a payload file that stays on the root of the Switch’s SD Card (fusee-secondary.bin). It is automatically launched once fusée-primary has finished, and is responsible for preparing the Switch’s hardware for future running environments, such as the homebrew menu. Fusée-secondary is also responsible for validating and launching Exosphère.
Fusée-secondary contains various [.kip modules](/docs/main.md#modules). These modules modify existing features in the OS, and can also add new ones.
Fusée is also capable of chainloading other payloads such as Linux.
mesosphère is a work in progress customized kernel reimplementation.
The Horizon OS's kernel follows microkernel design principles and runs at the EL1 level. It is currently subdivided into a loader (kernel_ldr) and the main kernel code.
This module provides methods to intercept services provided by other system modules. It is further sub-divided according to the service it targets.
## bpc_mitm
bpc_mitm enables intercepting requests to power control services. It currently intercepts:
+ `am` system module (to intercept the Reboot/Power buttons in the overlay menu)
+ `fatal` system module (to simplify payload reboot logic significantly)
+ [nx-hbloader](https://github.com/switchbrew/nx-hbloader) (to allow homebrew to take advantage of the feature)
## fs_mitm
fs_mitm enables intercepting file system operations. It can deny, delay, replace, or redirect any request made to the file system. It enables LayeredFS to function, which allows for replacement of game assets.
## hid_mitm
hid_mitm enables intercepting requests to controller device services. It is currently disabled by default. If enabled, it intercepts:
+ [nx-hbloader](https://github.com/switchbrew/nx-hbloader) (to help homebrew not need to be recompiled due to a breaking change introduced in the past)
Note that hid_mitm is currently deprecated and might be removed entirely in the future.
## ns_mitm
ns_mitm enables intercepting requests to application control services. It currently intercepts:
+ Web Applets (to facilitate nx-hbloader web browser launching)
## set_mitm
set_mitm enables intercepting requests to the system settings service. It currently intercepts:
+ `ns` system module and games (to allow for overriding game locales)
+ All firmware debug settings requests (to allow modification of system settings not directly exposed to the user)
### Firmware Version
set_mitm intercepts the `GetFirmwareVersion` command, if the requester is `qlaunch` or `maintenance`.
It modifies the `display_version` field of the returned system version, causing the version to display
in settings as `#.#.#|AMS #.#.#|?` with `? = S` when running under system eMMC or `? = E` when running under emulated eMMC. This allows users to easily verify what version of Atmosphère and what eMMC environment they are running.
### System Settings
set_mitm intercepts the `GetSettingsItemValueSize` and `GetSettingsItemValue` commands for all requesters.
It does so in order to enable user configuration of system settings, which are parsed from `/atmosphere/system_settings.ini` on boot. See [here](../../features/configurations.md) for more information on the system settings format.
## dns_mitm
dns_mitm enables intercepting requests to dns resolution services, to enable redirecting requests for specified hostnames.
For documentation, see [here](../../features/dns_mitm.md).
This module is a reimplementation of the Horizon OS's `boot` system module, which is responsible for initializing and configuring hardware.
Atmosphère's reimplementation displays its own black and white splash screen and battery icons as replacements for the original assets used during display initialization.
This module is a reimplementation of the Horizon OS's `boot2` system module, which is responsible for launching all the other necessary system modules.
Atmosphère's reimplementation allows launching user provided system modules from the SD card. See [here](../../features/configurations.md) for more information.
This module is a reimplementation of the Horizon OS's `creport` system module, which is responsible for managing crash reports.
Atmosphère's reimplementation redirects writing of generated crash reports to the SD card under the folder `/atmosphere/crash_reports/`. It also prevents the automatic uploading of said crash reports.
This module is a reimplementation of the Horizon OS's `dmnt` system module, which provides a debug monitor.
## Extensions
Atmosphère implements an extension to provide cheat code functionality.
### Cheat Service
A HIPC service API is provided for interacting with the cheat code manager through the service `dmnt:cht`. See [here](../../features/cheats.md) for more information on the cheat code format.
The SwIPC definition for `dmnt:cht` follows:
```
interface ams::dmnt::cheat::CheatService is dmnt:cht {
This module is a reimplementation of the Horizon OS's `fatal` system module, which is responsible for managing fatal reports.
Atmosphère's reimplementation prevents error report creation and draws a custom error screen, showing registers and a backtrace. It also attempts to gather debugging info for any and all crashes and tries to save reports to the SD card under the folder `/atmosphere/fatal_reports/`.
This module is a reimplementation of the Horizon OS's `ldr` system module, which is responsible for creating processes from executable NSO images and registering their access control.
## Extensions
Atmosphère extends this module to allow executables to be replaced or patched by files stored on the SD card. Note that a few services are required for SD card access and therefore cannot be replaced or patched in this manner.
### Exefs Replacement
Atmosphère's reimplementation allows replacing executable files in the file system.
#### Partition Replacement
It is possible to replace the full exefs partition at once with a PFS0 file. In that case, Atmosphère will load the following file:
```
/atmosphere/contents/<programid>/exefs.nsp
```
#### File Replacement
When a process is created, loader will search for several NSO filenames in the program's exefs directory.
These filenames are, in this order:
- rtld
- main
- subsdk0
- subsdk1
- ...
- subsdk9
- sdk
Each NSO that is found will be loaded into the process contiguously. The process's entrypoint is at the first NSO to be loaded, usually `rtld` or `main`.
Additionally, when a process is loaded, loader will search for a `main.npdm` file in the exefs directory specifying the program's permissions.
Atmosphère extends this functionality by also searching for these files on the SD card. When searching for a file, loader will first check if it exists on the SD card. If it does, that file will be used instead. Otherwise, it will use the copy located in the exefs, if that is present. The following directory will be searched:
```
/atmosphere/contents/<programid>/exefs/
```
This allows the replacement of applets, system modules, or even games with homebrew versions.
##### File Stubbing
In order to prevent an NSO from being loaded even if it exists in the exefs, loader will also check if a stub file exists. If such a file exists, the NSO will not be loaded. The files should be named like `rtld.stub`, `main.stub`, etc. and may be empty.
##### Technical Semantics
loader's semantics for content override can (as you may observe from reading the above) be complicated to understand. The following is an abbreviated description of the very technical semantics by which loader decides what content to read when trying to read a file for a program id.
* If an external content filesystem exists for the program id, the external content filesystem is used directly with no further redirection.
* Otherwise, if the program ID is being overridden with [nx-hbloader](https://github.com/switchbrew/nx-hbloader/releases) (see Homebrew Support below), the nsp filesystem for hbl is used directly with no further redirection.
* Otherwise, if content redirection is enabled for the program ID (controlled by a configurable button combination) and a loose file exists on the SD card, the loose file is used.
* Otherwise, if a stub file exists, a "Not Found" error is returned.
* Otherwise, if an SD card executable filesystem ("exefs.nsp") exists, it is used without further redirection.
* Finally, the "real"/base code file system is used without further redirection.
In addition, there are a few other technical details relevant to Atmosphere's redirection:
* When overriding with nx-hbloader, the real code filesystem must exist. When "main.npdm" (a program capabilities descriptor file) is read, the content from the real code filesystem is read in order to determine whether an applet or an application is being overridden. This allows nx-hbloader to automatically support both applet and application environments.
* When overriding applications, the real code filesystem must exist and contain valid content. This is required to perform accurate-to-Nintendo content verification procedures.
* When programs are launched, both a program id and a "storage id" are specified by the launch requester. When the storage id specified is "none" (normally always invalid), Atmosphere assumes that a custom system module is attempting to be launched. This removes the aforementioned requirement on base content validity; the above procedure is still used to determine how to redirect content, however reads to the "real"/base code file system may return "Not Found" errors if the real/base code file system does not exist.
### NSO Patching
When an NSO is loaded, Atmosphère's reimplementation will search for IPS patch files on the SD card in the following locations.
This organization allows patch sets affecting multiple NSOs to be distributed as a single directory and also allows patches from multiple patch sets to be stacked. Patches will be searched for in each patch set directory. The name of each patch file should match the hexadecimal build ID of the NSO to affect, except that trailing zero bytes may be left off. Because the NSO build ID is unique for every NSO, this means patches will only apply to the files they are meant to apply to.
Patch files are accepted in either IPS format or IPS32 format.
Because NSO files are compressed, patch files are not made between the original version of a compressed NSO and the modified version of such an NSO. Instead, they are made between the uncompressed version of an NSO and the modified (and still uncompressed) version of that NSO. This also means that a patch file cannot be manually applied to the compressed version of an NSO; it must be applied to the uncompressed version. Atmosphère's reimplementation will correctly apply these patches while loading the process regardless of whether the NSO it finds is compressed or not.
When authoring patches, [hactool](https://github.com/SciresM/hactool) can be used to find an NSO's build ID and to uncompress NSOs. Recent versions of the [ReSwitched IDA loaders](https://github.com/reswitched/loaders) can be used to load uncompressed NSOs into IDA in such a way that you can [apply patches to the input file](https://www.hex-rays.com/products/ida/support/idadoc/1618.shtml). From there, any IPS tool can be used to create the patch between the original NSO and the patched NSO. Note that if the NSO you are patching is larger than 16 MiB, you will have to use a tool that supports IPS32.
### Homebrew Support
Atmosphère provides first class support for [nx-hbloader](https://github.com/switchbrew/nx-hbloader/releases) and [nx-hbmenu](https://github.com/switchbrew/nx-hbmenu/releases).
Launching of the nx-hbloader process is controlled by configurable button inputs. See [here](../../features/configurations.md) for more detailed information.
In addition, loader has extensions to enable homebrew to launch web applets. This normally requires the application launching the applet to have HTML Manual content inside an installed NCA. Atmosphère's reimplementation will automatically ensure that the commands used to check this succeed, and will redirect the relevant file system to the `/atmosphere/hbl_html/` subdirectory.
### IPC Commands
Atmosphère's reimplementation extends the HIPC loader services' API with several custom commands.
The SwIPC definition for the `ldr:pm` extension commands follows:
```
interface ams::ldr::pm::ProcessManagerInterface is ldr:pm {
This module is a reimplementation of the Horizon OS's `pgl` system module, which is responsible for launching programs and was introduced by firmware version `10.0.0`.
Currently, Atmosphère's reimplementation doesn't backport this module's functionalities to firmware versions lower than `10.0.0`.
This module is a reimplementation of the Horizon OS's `pm` system module, which is responsible for tracking running processes on the system, and managing resource limits.
## Extensions
Atmosphère extends this module with extra IPC commands and memory restriction changes.
### IPC Commands
Atmosphère's reimplementation extends the HIPC loader services' API with several custom commands.
The SwIPC definition for the `pm:dmnt` extension commands follows:
```
interface ams::pm::dmnt::DebugMonitorServiceBase is pm:dmnt {
Atmosphère's reimplementation shrinks the APPLET memory pool by 24 MiB by default, giving this memory to the SYSTEM pool. This allows custom system modules to use more memory without hitting the SYSTEM memory limit.
This module is a reimplementation of the Horizon OS's `ro` system module, which is responsible for loading dynamic libraries and was introduced by firmware version `3.0.0`.
Atmosphère's reimplementation backports this module's functionalities to firmware versions lower than `3.0.0` where said functionalities were provided by the `ldr` system module instead.
## Extensions
Atmosphère extends this module to allow libraries to be patched by files stored on the SD card.
### NRO Patching
When an NRO is loaded, Atmosphère's reimplementation will search for IPS patch files on the SD card in the following locations.
This organization allows patch sets affecting multiple NROs to be distributed as a single directory. Patches will be searched for in each patch set directory. The name of each patch file should match the hexadecimal build ID of the NRO to affect, except that trailing zero bytes may be left off. Because the NRO build ID is unique for every NRO, this means patches will only apply to the files they are meant to apply to.
Patch files are accepted in either IPS format or IPS32 format.
This module is a reimplementation of the Horizon OS's `spl` system module, which is responsible for providing secure platform services such as cryptographic operations.
Stratosphère allows customization of the Horizon OS and Switch kernel. It includes custom sysmodules that extend the kernel and provide new features. It also includes a reimplementation of the loader sysmodules to hook important system actions.
stratosphère provides customization of the Horizon OS at the system level. This includes a reimplementation of several system modules and additional, custom system modules that extend or add a variety of features.
The sysmodules that Stratosphère includes are:
## Modules
+ [boot](../modules/boot.md): This module boots the system and initalizes hardware.
The modules currently provided by stratosphère are:
+ [creport](../modules/creport.md): Reimplementation of Nintendo’s crash report system. Dumps all error logs to the SD card instead of saving them to the NAND and sending them to Nintendo.
+ [ams_mitm](modules/ams_mitm.md)
+ [fs_mitm](../modules/fs_mitm.md): This module can log, deny, delay, replace, and redirect any request made to the File System.
+ [boot](modules/boot.md)
+ [loader](../modules/loader.md): Enables modifying the code of binaries that are not stored inside the kernel.
+ [boot2](modules/boot2.md)
+ [pm](../modules/pm.md): Reimplementation of Nintendo’s Process Manager.
+ [creport](modules/creport.md)
+ [sm](../modules/sm.md): Reimplementation of Nintendo’s Service Manager.
Thermosphère is a hypervisor based implementation of emuNAND. An emuNAND is a copy of the firmware on the Switch’s internal memory (sysNAND), and is typically installed on an external SD Card.
thermosphère is a work in progress hypervisor implementation.
This aims to provide functionality at the EL2 level which remains unused by the Horizon OS.
An emuNAND operates completely independently of the sysNAND. This allows one to make or test various modifications and homebrew safely without needing to restore their NAND backup afterwards by testing things on the emuNAND, and switching back to the sysNAND when finished. In the case of past Nintendo systems such as the 3DS, an emuNAND could also be used to update your system to the latest firmware while keeping your sysNAND on a lower version, however this may be more difficult to do on the Switch due to Nintendo using efuse technology for major system updates.
Thermosphère is currently planned to be included in the 1.0 release of Atmosphère.
Troposphère contains various application-level modifications to the OS, such as launching homebrew directly from the homemenu or executing cheat/gameshark codes, similar to Luma3DS. Troposphère is not yet implemented in Atmosphère.
troposphère provides customization of the Horizon OS at the application level.
## reboot_to_payload
Sample application to perform a system reboot into a payload of choice.
This document serves as a place to store answers for common questions received about Atmosphère.
## What does "June 15th" mean?
When Atmosphère began development in February 2018, "June 15" was given as the estimate/target date for a first release, to coincide with the planned disclosure of a vulnerability.
This deadline was missed, hard.
People made rather a lot of fun of me (SciresM) for this.
Several months later, when the first Atmosphère release occurred, I captioned it "Happy June 15th!" and pretended like I hadn't missed the first deadline.
This amused me a lot, and so the practice has been kept up for every single release since.
Depending on who you ask, you may be told that this is a dumb joke and it is not funny.
This is incorrect. It is definitely a dumb joke, but it is also hilarious.
Atmosphère supports Action-Replay style cheat codes, with cheats loaded off of the SD card.
## Cheat Loading Process
By default, Atmosphère will do the following when deciding whether to attach to a new application process:
+ Retrieve information about the new application process from `pm` and `loader`.
+ Check whether a user-defined key combination is held, and stop if not.
+ This defaults to "L is not held", but can be configured with override keys.
+ The ini key to configure this is `cheat_enable_key`.
+ Check whether the process is a real application, and stop if not.
+ This guards against applying cheat codes to the Homebrew Loader.
+ Attempt to load cheats from `/atmosphere/contents/<program_id>/cheats/<build_id>.txt`, where `build_id` is the hexadecimal representation of the first 8 bytes of the application's main executable's build id.
+ If no cheats are found, then the cheat manager will stop.
+ Open a kernel debug session for the new application process.
+ Signal to a system event that a new cheat process has been attached to.
This behavior ensures that cheat codes are only loaded when the user would want them to.
In cases where `dmnt` has not activated the cheat manager, but the user wants to make it do so anyway, the cheat manager's service API provides a `ForceOpenCheatProcess` command that homebrew can use. This command will cause the cheat manager to try to force itself to attach to the process.
In cases where `dmnt` has activated the cheat manager, but the user wants to use an alternate debugger, the cheat manager's service API provides a `ForceCloseCheatProcess` command that homebrew can use. This command will cause the cheat manager to detach itself from the process.
By default, all cheat codes listed in the loaded .txt file will be toggled on. This is configurable by the user by editing the `atmosphere!dmnt_cheats_enabled_by_default` [system setting](configurations.md).
Users may use homebrew programs to toggle cheats on and off at runtime via the cheat manager's service API.
## Cheat Code Compatibility
Atmosphère manages cheat code through the execution of a small, custom virtual machine. Care has been taken to ensure that Atmosphère's cheat code format is fully backwards compatible with the pre-existing cheat code format, though new features have been added and bugs in the pre-existing cheat code applier have been fixed. Here is a short summary of the changes from the pre-existing format:
+ A number of bugs were fixed in the processing of conditional instructions.
+ The pre-existing implementation was fundamentally broken, and checked for the wrong value when detecting the end of a conditional block.
+ The pre-existing implementation also did not properly decode instructions, and instead linearly scanned for the terminator value. This caused problems if an instruction happened to encode a terminator inside its immediate values.
+ The pre-existing implementation did not bounds check, and thus certain conditional cheat codes could cause it to read out-of-bounds memory, and potentially crash due to a data abort.
+ Support was added for nesting conditional blocks.
+ An instruction was added to perform much more complex arbitrary arithmetic on two registers.
+ An instruction was added to allow writing the contents of register to a memory address specified by another register.
+ The pre-existing implementation did not correctly synchronize with the application process, and thus would cause heavy lag under certain circumstances (especially around loading screens). This has been fixed in Atmosphère's implementation.
## Cheat Code Format
The following provides documentation of the instruction format for the virtual machine used to manage cheat codes.
Typically, instruction type is encoded in the upper nybble of the first instruction u32.
### Code Type 0x0: Store Static Value to Memory
Code type 0x0 allows writing a static value to a memory address.
#### Encoding
`0TMR00AA AAAAAAAA VVVVVVVV (VVVVVVVV)`
+ T: Width of memory write (1, 2, 4, or 8 bytes).
+ M: Memory region to write to (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr, 4 = non-relative).
+ R: Register to use as an offset from memory region base.
+ A: Immediate offset to use from memory region base.
+ V: Value to write.
---
### Code Type 0x1: Begin Conditional Block
Code type 0x1 performs a comparison of the contents of memory to a static value.
If the condition is not met, all instructions until the appropriate End or Else conditional block terminator are skipped.
#### Encoding
`1TMCXrAA AAAAAAAA VVVVVVVV (VVVVVVVV)`
+ T: Width of memory read (1, 2, 4, or 8 bytes).
+ M: Memory region to read from (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr, 4 = non-relative).
+ C: Condition to use, see below.
+ X: Operand Type, see below.
+ r: Offset Register (operand types 1).
+ A: Immediate offset to use from memory region base.
+ V: Value to compare to.
#### Conditions
+ 1: >
+ 2: >=
+ 3: <
+ 4: <=
+ 5: ==
+ 6: !=
#### Operand Type
+ 0: Memory Base + Relative Offset
+ 1: Memory Base + Offset Register + Relative Offset
---
### Code Type 0x2: End Conditional Block
Code type 0x2 marks the end of a conditional block (started by Code Type 0x1 or Code Type 0x8).
When an Else is executed, all instructions until the appropriate End conditional block terminator are skipped.
#### Encoding
`2X000000`
+ X: End type (0 = End, 1 = Else).
---
### Code Type 0x3: Start/End Loop
Code type 0x3 allows for iterating in a loop a fixed number of times.
#### Start Loop Encoding
`300R0000 VVVVVVVV`
+ R: Register to use as loop counter.
+ V: Number of iterations to loop.
#### End Loop Encoding
`310R0000`
+ R: Register to use as loop counter.
---
### Code Type 0x4: Load Register with Static Value
Code type 0x4 allows setting a register to a constant value.
#### Encoding
`400R0000 VVVVVVVV VVVVVVVV`
+ R: Register to use.
+ V: Value to load.
---
### Code Type 0x5: Load Register with Memory Value
Code type 0x5 allows loading a value from memory into a register, either using a fixed address or by dereferencing the destination register.
#### Load From Fixed Address Encoding
`5TMR00AA AAAAAAAA`
+ T: Width of memory read (1, 2, 4, or 8 bytes).
+ M: Memory region to write to (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr, 4 = non-relative).
+ R: Register to load value into.
+ A: Immediate offset to use from memory region base.
#### Load from Register Address Encoding
`5T0R10AA AAAAAAAA`
+ T: Width of memory read (1, 2, 4, or 8 bytes).
+ R: Register to load value into. (This register is also used as the base memory address).
+ A: Immediate offset to use from register R.
#### Load from Register Address Encoding
`5T0R2SAA AAAAAAAA`
+ T: Width of memory read (1, 2, 4, or 8 bytes).
+ R: Register to load value into.
+ S: Register to use as the base memory address.
+ A: Immediate offset to use from register R.
#### Load From Fixed Address Encoding with offset register
`5TMR3SAA AAAAAAAA`
+ T: Width of memory read (1, 2, 4, or 8 bytes).
+ M: Memory region to write to (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr, 4 = non-relative).
+ R: Register to load value into.
+ S: Register to use as offset register.
+ A: Immediate offset to use from memory region base.
---
### Code Type 0x6: Store Static Value to Register Memory Address
Code type 0x6 allows writing a fixed value to a memory address specified by a register.
#### Encoding
`6T0RIor0 VVVVVVVV VVVVVVVV`
+ T: Width of memory write (1, 2, 4, or 8 bytes).
+ R: Register used as base memory address.
+ I: Increment register flag (0 = do not increment R, 1 = increment R by T).
+ o: Offset register enable flag (0 = do not add r to address, 1 = add r to address).
+ r: Register used as offset when o is 1.
+ V: Value to write to memory.
---
### Code Type 0x7: Legacy Arithmetic
Code type 0x7 allows performing arithmetic on registers.
However, it has been deprecated by Code type 0x9, and is only kept for backwards compatibility.
#### Encoding
`7T0RC000 VVVVVVVV`
+ T: Width of arithmetic operation (1, 2, 4, or 8 bytes).
+ R: Register to apply arithmetic to.
+ C: Arithmetic operation to apply, see below.
+ V: Value to use for arithmetic operation.
#### Arithmetic Types
+ 0: Addition
+ 1: Subtraction
+ 2: Multiplication
+ 3: Left Shift
+ 4: Right Shift
---
### Code Type 0x8: Begin Keypress Conditional Block
Code type 0x8 enters or skips a conditional block based on whether a key combination is pressed.
#### Encoding
`8kkkkkkk`
+ k: Keypad mask to check against, see below.
Note that for multiple button combinations, the bitmasks should be ORd together.
#### Keypad Values
Note: This is the direct output of `hidKeysDown()`.
+ 0000001: A
+ 0000002: B
+ 0000004: X
+ 0000008: Y
+ 0000010: Left Stick Pressed
+ 0000020: Right Stick Pressed
+ 0000040: L
+ 0000080: R
+ 0000100: ZL
+ 0000200: ZR
+ 0000400: Plus
+ 0000800: Minus
+ 0001000: Left
+ 0002000: Up
+ 0004000: Right
+ 0008000: Down
+ 0010000: Left Stick Left
+ 0020000: Left Stick Up
+ 0040000: Left Stick Right
+ 0080000: Left Stick Down
+ 0100000: Right Stick Left
+ 0200000: Right Stick Up
+ 0400000: Right Stick Right
+ 0800000: Right Stick Down
+ 1000000: SL
+ 2000000: SR
---
### Code Type 0x9: Perform Arithmetic
Code type 0x9 allows performing arithmetic on registers.
#### Register Arithmetic Encoding
`9TCRS0s0`
+ T: Width of arithmetic operation (1, 2, 4, or 8 bytes).
+ C: Arithmetic operation to apply, see below.
+ R: Register to store result in.
+ S: Register to use as left-hand operand.
+ s: Register to use as right-hand operand.
#### Immediate Value Arithmetic Encoding
`9TCRS100 VVVVVVVV (VVVVVVVV)`
+ T: Width of arithmetic operation (1, 2, 4, or 8 bytes).
+ C: Arithmetic operation to apply, see below.
+ R: Register to store result in.
+ S: Register to use as left-hand operand.
+ V: Value to use as right-hand operand.
#### Arithmetic Types
+ 0: Addition
+ 1: Subtraction
+ 2: Multiplication
+ 3: Left Shift
+ 4: Right Shift
+ 5: Logical And
+ 6: Logical Or
+ 7: Logical Not (discards right-hand operand)
+ 8: Logical Xor
+ 9: None/Move (discards right-hand operand)
+ 10: Float Addition, T==4 single T==8 double
+ 11: Float Subtraction, T==4 single T==8 double
+ 12: Float Multiplication, T==4 single T==8 double
+ 13: Float Division, T==4 single T==8 double
---
### Code Type 0xA: Store Register to Memory Address
Code type 0xA allows writing a register to memory.
#### Encoding
`ATSRIOxa (aaaaaaaa)`
+ T: Width of memory write (1, 2, 4, or 8 bytes).
+ S: Register to write to memory.
+ R: Register to use as base address.
+ I: Increment register flag (0 = do not increment R, 1 = increment R by T).
+ O: Offset type, see below.
+ x: Register used as offset when O is 1, Memory type when O is 3, 4 or 5.
+ a: Value used as offset when O is 2, 4 or 5.
#### Offset Types
+ 0: No Offset
+ 1: Use Offset Register
+ 2: Use Fixed Offset
+ 3: Memory Region + Base Register
+ 4: Memory Region + Relative Address (ignore address register)
+ 5: Memory Region + Relative Address + Offset Register
---
### Code Type 0xB: Reserved
Code Type 0xB is currently reserved for future use.
---
### Code Type 0xC-0xF: Extended-Width Instruction
Code Types 0xC-0xF signal to the VM to treat the upper two nybbles of the first dword as instruction type, instead of just the upper nybble.
This reserves an additional 64 opcodes for future use.
---
### Code Type 0xC0: Begin Register Conditional Block
Code type 0xC0 performs a comparison of the contents of a register and another value. This code support multiple operand types, see below.
If the condition is not met, all instructions until the appropriate conditional block terminator are skipped.
#### Encoding
```
C0TcSX##
C0TcS0Ma aaaaaaaa
C0TcS1Mr
C0TcS2Ra aaaaaaaa
C0TcS3Rr
C0TcS400 VVVVVVVV (VVVVVVVV)
C0TcS5X0
```
+ T: Width of memory write (1, 2, 4, or 8 bytes).
+ c: Condition to use, see below.
+ S: Source Register.
+ X: Operand Type, see below.
+ M: Memory Type (operand types 0 and 1).
+ R: Address Register (operand types 2 and 3).
+ a: Relative Address (operand types 0 and 2).
+ r: Offset Register (operand types 1 and 3).
+ X: Other Register (operand type 5).
+ V: Value to compare to (operand type 4).
#### Operand Type
+ 0: Memory Base + Relative Offset
+ 1: Memory Base + Offset Register
+ 2: Register + Relative Offset
+ 3: Register + Offset Register
+ 4: Static Value
+ 5: Other Register
#### Conditions
+ 1: >
+ 2: >=
+ 3: <
+ 4: <=
+ 5: ==
+ 6: !=
---
### Code Type 0xC1: Save or Restore Register
Code type 0xC1 performs saving or restoring of registers.
#### Encoding
`C10D0Sx0`
+ D: Destination index.
+ S: Source index.
+ x: Operand Type, see below.
#### Operand Type
+ 0: Restore register
+ 1: Save register
+ 2: Clear saved value
+ 3: Clear register
---
### Code Type 0xC2: Save or Restore Register with Mask
Code type 0xC2 performs saving or restoring of multiple registers using a bitmask.
#### Encoding
`C2x0XXXX`
+ x: Operand Type, see below.
+ X: 16-bit bitmask, bit i == save or restore register i.
#### Operand Type
+ 0: Restore register
+ 1: Save register
+ 2: Clear saved value
+ 3: Clear register
---
### Code Type 0xC3: Read or Write Static Register
Code type 0xC3 reads or writes a static register with a given register.
#### Encoding
`C3000XXx`
+ XX: Static register index, 0x00 to 0x7F for reading or 0x80 to 0xFF for writing.
+ x: Register index.
---
### Code Type 0xC4: Begin Extended Keypress Conditional Block
Code type 0xC4 enters or skips a conditional block based on whether a key combination is pressed.
#### Encoding
`C4r00000 kkkkkkkk kkkkkkkk`
+ r: Auto-repeat, see below.
+ kkkkkkkkkk: Keypad mask to check against output of `hidKeysDown()`.
Note that for multiple button combinations, the bitmasks should be OR'd together.
#### Auto-repeat
+ 0: The conditional block executes only once when the keypad mask matches. The mask must stop matching to reset for the next trigger.
+ 1: The conditional block executes as long as the keypad mask matches.
#### Keypad Values
Note: This is the direct output of `hidKeysDown()`.
+ 00000000 00000001: A
+ 00000000 00000002: B
+ 00000000 00000004: X
+ 00000000 00000008: Y
+ 00000000 00000010: Left Stick Pressed
+ 00000000 00000020: Right Stick Pressed
+ 00000000 00000040: L
+ 00000000 00000080: R
+ 00000000 00000100: ZL
+ 00000000 00000200: ZR
+ 00000000 00000400: Plus
+ 00000000 00000800: Minus
+ 00000000 00001000: Left
+ 00000000 00002000: Up
+ 00000000 00004000: Right
+ 00000000 00008000: Down
+ 00000000 00010000: Left Stick Left
+ 00000000 00020000: Left Stick Up
+ 00000000 00040000: Left Stick Right
+ 00000000 00080000: Left Stick Down
+ 00000000 00100000: Right Stick Left
+ 00000000 00200000: Right Stick Up
+ 00000000 00400000: Right Stick Right
+ 00000000 00800000: Right Stick Down
+ 00000000 01000000: SL Left Joy-Con
+ 00000000 02000000: SR Left Joy-Con
+ 00000000 04000000: SL Right Joy-Con
+ 00000000 08000000: SR Right Joy-Con
+ 00000000 10000000: Top button on Poké Ball Plus (Palma) controller
+ 00000000 20000000: Verification
+ 00000000 40000000: B button on Left NES/HVC controller in Handheld mode
+ 00000000 80000000: Left C button in N64 controller
+ 00000001 00000000: Up C button in N64 controller
+ 00000002 00000000: Right C button in N64 controller
+ 00000004 00000000: Down C button in N64 controller
### Code Type 0xF0: Double Extended-Width Instruction
Code Type 0xF0 signals to the VM to treat the upper three nybbles of the first dword as instruction type, instead of just the upper nybble.
This reserves an additional 16 opcodes for future use.
---
### Code Type 0xFF0: Pause Process
Code type 0xFF0 pauses the current process.
#### Encoding
`FF0?????`
---
### Code Type 0xFF1: Resume Process
Code type 0xFF1 resumes the current process.
#### Encoding
`FF1?????`
---
### Code Type 0xFFF: Debug Log
Code type 0xFFF writes a debug log to the SD card under the folder `/atmosphere/cheat_vm_logs/`.
Atmosphère provides a variety of customizable configurations to better adjust to users' needs.
## stratosphere.ini
This is the configuration file used by fusée for configuring user-space system modules.
This file is located under the `/atmosphere/config/` folder on your SD card and a default template can be found inside the `/atmosphere/config_templates/` folder.
### Configuring "nogc" Protection
"nogc" is a feature provided by fusée-secondary which disables the Nintendo Switch's Game Card reader. Its purpose is to prevent the reader from being updated when the console has been updated, without burning fuses, from a lower firmware version. More specifically, from firmware versions 4.0.0 or 9.0.0 which introduced updates to the Game Card reader's firmware. By default, Atmosphère will protect the Game Card reader automatically, but you are free to change it.
To change its functionality, add the following line to the `stratosphere` section and change the value of `X` according to the following list:
```
[stratosphere]
nogc = X
```
```
1 = force-enable nogc, so Atmosphère will always disable the Game Card reader.
0 = force-disable nogc, so Atmosphère will always enable the Game Card reader.
```
## Adding a Custom Boot Splashscreen
Atmosphère provides its own default splashscreen which is displayed at boot time. However, this can be replaced at will.
Boot splash screens must be 1280x720 resolution.
A script can be found inside the source tree (`/utilities/insert_splash_screen.py`) for inserting a custom splash screen into a release binary.
To do so, execute the following command on the script:
`python insert_splash_screen.py <path to your splash screen image> <path to /atmosphere/package3 on your SD card>`
## emummc.ini
This is the configuration file used for the [emummc](../components/emummc.md) component.
This file is located under the `/emuMMC/` folder on your SD card.
Please refer to the project's repository [here](https://github.com/m4xw/emuMMC) for detailed instructions and documentation.
## exosphere.ini
This is the configuration file used by exosphère.
This file is located in the root of your SD card and a default template can be found inside the `/atmosphere/config_templates/` folder.
### Configuring Debugging Modes
By default, Atmosphère signals to the Horizon kernel that debugging is enabled while leaving usermode debugging disabled, but this can cause undesirable side-effects. If you wish to change this behavior, go to the `exosphere` section and change the value of `X` according to the following list.
```
[exosphere]
debugmode = X
debugmode_user = X
```
```
1 = enable
0 = disable
```
### Blanking PRODINFO
Atmosphère provides a way for users to blank their factory installed calibration data (known as PRODINFO) in either emulated or system eMMC environments. You can find more detailed information on this inside the respective template file. Usage of this configuration is not encouraged.
## override_config.ini
This file is located under the `/atmosphere/config/` folder on your SD card and a default template can be found inside the `/atmosphere/config_templates/` folder.
### Overrides Format
Overrides are parsed from the `/atmosphere/config/override_config.ini` file during the boot process.
By default `override_config.ini` is not configured. It can be used to select the behavior of certain buttons and bind them to functionalities such as launching the Homebrew Menu or enabling the cheat code manager.
You can modify the override_key entries in `override_config.ini` with this list of valid buttons:
| Formal Name | .ini Name |
| ----------- | --------- |
| A Button | A |
| B Button | B |
| X Button | X |
| Y Button | Y |
| Left Stick | LS |
| Right Stick | RS |
| L Button | L |
| R Button | R |
| ZL Button | ZL |
| ZR Button | ZR |
| + Button | PLUS |
| - Button | MINUS |
| Left Dpad | DLEFT |
| Up Dpad | DUP |
| Right Dpad | DRIGHT |
| Down Dpad | DDOWN |
| SL Button | SL |
| SR Button | SR |
To invert the behavior of the override key, place an exclamation point in front of whatever button you wish to use. It will launch the actual game while holding down that button, instead of going into the Homebrew Menu. For example, `override_key=!R` will run the game only while holding down R when launching it, otherwise it will boot into the Homebrew Menu. Afterwards you may reinsert your SD card into your Switch and boot into Atmosphère as you normally would. You should now be able to boot into the Homebrew Menu by launching your designated program of choice.
## system_settings.ini
This file is located under the `/atmosphere/config/` folder on your SD card and a default template can be found inside the `/atmosphere/config_templates/` folder.
### Settings Format
Atmosphère provides a way to override the firmware debug settings used by the system. These can be parsed from the `/atmosphere/config/system_settings.ini` file during the boot process. This file is a normal ini file, with some specific interpretations.
The standard representation of a setting's identifier takes the form `name!key`. This is represented within `system_settings.ini` as a section `name`, with an entry `key`. For example:
```
[name]
key = ...
```
Settings can have variable types (strings, integral values, byte arrays, etc). To accommodate this, `system_settings.ini` must store values as a `type_identifier!value_store` pair. A number of different types are supported, with identifiers detailed below.
Please note that a malformed value string will cause a fatal error to occur on boot. A full example of a custom setting is given below (setting `eupld!upload_enabled = 0`), for posterity:
```
[eupld]
upload_enabled = u8!0x0
```
#### Supported Types
* Strings
* Type identifiers: `str`, `string`
* The value string is used directly as the setting, with null terminator appended.
* Integral types
* Type identifiers: `u8`, `u16`, `u32`, `u64`
* The value string is parsed via a call to `strtoul(value, NULL, 0)`.
* Setting bitwidth is determined by the identifier (8 for 1 byte, 16 for 2 bytes, and so on).
* Raw bytes
* Type identifiers: `hex`, `bytes`
* The value string is parsed as a hexadecimal string.
* The value string must be of even length, or a fatal error will be thrown on parse.
## Content Specific Flags
Atmosphère supports customizing CFW behavior based on the presence of `flags` on the SD card.
The following flags are supported on a per-program basis, by placing `<flag_name>.flag` inside `/atmosphere/contents/<program_id>/flags/`:
+ `boot2`, which indicates that the program should be launched during the `boot2` process.
+ `redirect_save`, which indicates that the program wants its savedata to be redirected to the SD card.
As of 0.18.0, atmosphère provides a mechanism for redirecting DNS resolution requests.
By default, atmosphère redirects resolution requests for official telemetry servers, redirecting them to a loopback address.
## Hosts files
DNS.mitm can be configured through the usage of a slightly-extended `hosts` file format, which is parsed only once on system startup.
In particular, hosts files parsed by DNS.mitm have the following extensions to the usual format:
+ `*` is treated as a wildcard character, matching any collection of 0 or more characters wherever it occurs in a hostname.
+ `%` is treated as a stand-in for the value of `nsd!environment_identifier`. This is always `lp1`, on production devices.
If multiple entries in a host file match a domain, the last-defined match is used.
Please note that homebrew may trigger a hosts file re-parse by sending the extension IPC command 65000 ("AtmosphereReloadHostsFile") to a connected `sfdnsres` session.
### Hosts file selection
Atmosphère will try to read hosts from the following file paths, in order, stopping once it successfully performs a file read:
+ (emummc only) `/atmosphere/hosts/emummc_%04lx.txt`, formatted with the emummc's id number (see `emummc.ini`).
+ (emummc only) `/atmosphere/hosts/emummc.txt`.
+ (sysmmc only) `/atmosphere/hosts/sysmmc.txt`.
+ `/atmosphere/hosts/default.txt`
If `/atmosphere/hosts/default.txt` does not exist, atmosphère will create it to contain the defaults.
### Atmosphère defaults
By default, atmosphère's default redirections are parsed **in addition to** the contents of the loaded hosts file.
This is equivalent to thinking of the loaded hosts file as having the atmosphère defaults prepended to it.
This setting is considered desirable, because it minimizes the telemetry risks if a user forgets to update a custom hosts file on a system update which changes the telemetry servers.
This behavior can be opted-out from by setting `atmosphere!add_defaults_to_dns_hosts = u8!0x0` in `system_settings.ini`.
On startup (or on hosts file re-parse), DNS.mitm will log both what hosts file it selected and the contents of all redirections it parses to `/atmosphere/logs/dns_mitm_startup.log`.
In addition, if the user sets `atmosphere!enable_dns_mitm_debug_log = u8!0x1` in `system_settings.ini`, DNS.mitm will log all requests to GetHostByName/GetAddrInfo to `/atmosphere/logs/dns_mitm_debug.log`. All redirections will be noted when they occur.
## Opting-out of DNS.mitm entirely
If you wish to disable DNS.mitm entirely, `system_settings.ini` can be edited to set `atmosphere!enable_dns_mitm = u8!0x0`.
Atmosphère is a work-in-progress customized firmware for the Nintendo Switch. Atmosphère consists of several different components, each in charge of performing different system functions of the Nintendo Switch.
Atmosphère is a work-in-progress customized firmware for the Nintendo Switch. Its design principle consists of a multi-layered approach where each layer replaces/modifies a different component of the Nintendo Switch's system.
The components of Atmosphère are:
## Components
+ [Fusée](../docs/components/fusee/fusee.md), a custom bootloader.
Atmosphère provides six core components, mimicking to some degree the various layers of the Earth's atmosphere:
+ [Exosphère](../docs/components/exosphere.md), a fully-featured custom secure monitor.
+ [fusée](components/fusee.md)
+ [Stratosphère](../docs/components/stratosphere.md), a set of custom system modules.
+ [exosphère](components/exosphere.md)
+ [Thermosphère](../docs/components/thermosphere.md), a hypervisor-based emuNAND implementation. This component has not been implemented yet.
+ [thermosphère](components/thermosphere.md)
+ [Troposphère](../docs/components/troposphere.md), Application-level patches to the Horizon OS. This component has also not been implemented yet.
+ [mesosphère](components/mesosphere.md)
+ [stratosphère](components/stratosphere.md)
+ [troposphère](components/troposphere.md)
### Modules
Additionally, Atmosphère also provides the following secondary components:
The Stratosphère component of Atmosphère contains various modules. These have a `.kip` extension. They provide custom features, extend existing features, or replace Nintendo sysmodules.
+ [emummc](components/emummc.md)
+ [libraries](components/libraries.md)
Stratosphère's modules include:
## Features
+ [boot](../docs/modules/boot.md)
Atmosphère provides several original features which add or expand functionalities for the customized firmware environment:
+ [creport](../docs/modules/creport.md)
+ [Cheats](features/cheats.md)
+ [fs_mitm](../docs/modules/fs_mitm.md)
+ [Configurations](features/configurations.md)
+ [loader](../docs/modules/loader.md)
+ [pm](../docs/modules/pm.md)
+ [sm](../docs/modules/sm.md)
### Building Atmosphère
## Building Atmosphère
A guide to building Atmosphère can be found [here](../docs/building.md).
A guide to building Atmosphère can be found [here](building.md).
### Upcoming Features
## Upcoming Features
A list of planned features for Atmosphère can be found [here](../docs/roadmap.md).
A list of planned features for Atmosphère can be found [here](roadmap.md).
### Release History
## Release History
A changelog of previous versions of Atmosphère can be found [here](../docs/changelog.md).
A changelog of previous versions of Atmosphère can be found [here](changelog.md).
## Frequently Asked Questions
Answers to one or more frequently asked questions may be found [here](faq.md).
The boot module is responsible for booting the system and initalizing hardware. A second boot module known as boot2 is integrated with the [pm (process manager)](../modules/pm.md) sysmodule in Atmosphère, and launches other processes.
creport is a reimplementation of Nintendo's crash reporter. Atmosphère's creport catches all error logs that would have been saved to the NAND and instead saves them to the SD card for debugging purposes. This is helpful because the errors no longer go to Nintendo and developers of homebrew can still see the errors to help with the debugging process. creport catches system errors, game crashes, and homebrew crashes.
fs_mitm is a sysmodule that enables intercepting file system operations. This module can log, deny, delay, replace, or redirect any request made to the filesystem. It enables LayeredFS to function, which allows for game mods.
loader is a reimplementation of the loader sysmodule. This module is responsible for creating processes from executable NSO images and registering their access control with the kernel, sm, and fs.
## Atmosphère Extensions
Atmosphère extends this module to allow executables to be replaced or patched by files stored on the SD card. Note that a few services are required for SD card access and therefore cannot be replaced or patched in this manner. This includes psc, bus, and pcv.
### Exefs Replacement
TODO: details on buttons affecting this.
When a process is created, loader will search for several NSO filenames in the title's exefs directory.
These filenames are, in this order:
- rtld
- main
- subsdk0
- subsdk1
- ...
- subsdk9
- sdk
Each NSO that is found will be loaded into the process contiguously. The process's entrypoint is at the first NSO to be loaded, usually `rtld` or `main`.
Additionally, when a process is loaded, loader will search for a `main.npdm` file in the exefs directory specifying the title's permissions.
Atmosphère extends this functionality by also searching for these files on the SD card. When searching for a file, loader will first check if it exists on the SD card. If it does, that file will be used instead. Otherwise, it will use the copy located in the exefs, if that is present. The following directory will be searched.
```
sdmc:/atmosphere/titles/<titleid>/exefs/
```
This allows the replacement of applets, sysmodules, or even games with homebrew versions.
In order to prevent an NSO from being loaded even if it exists in the exefs, loader will also check if a stub file exists. If such a file exists, the NSO will not be loaded. The files should be named like `rtld.stub`, `main.stub`, etc. and may be empty.
### NSO Patching
TODO: details on buttons affecting this.
When an NSO is loaded, the stratosphere implementatin of loader will search for IPS patch files on the SD card in the following locations.
This organization allows patchsets affecting multiple NSOs to be distributed as a single directory. Patches will be searched for in each patchset directory. The name of each patch file should match the hexadecimal build ID of the NSO to affect, except that trailing zero bytes may be left off. Because the NSO build ID is unique for every NSO, this means patches will only apply to the files they are meant to apply to.
Patch files are accepted in either IPS format or IPS32 format.
Because NSO files are compressed, patch files are not made between the original version of a compressed NSO and the modified version of such an NSO. Instead, they are made between the uncompressed version of an NSO and the modified (and still uncompressed) version of that NSO. This also means that a patch file cannot be manually applied to the compressed version of an NSO; it must be applied to the uncompressed version. The Stratosphere implementation of loader will correctly apply these patches while loading the process regardless of whether the NSO it finds is compressed or not.
When authoring patches, [hactool](https://github.com/SciresM/hactool) can be used to find an NSO's build ID and to uncompress NSOs. Recent versions of the [ReSwitched IDA loaders](https://github.com/reswitched/loaders) can be used to load uncompressed NSOs into IDA in such a way that you can [apply patches to the input file](https://www.hex-rays.com/products/ida/support/idadoc/1618.shtml). From there, any IPS tool can be used to create the patch between the original NSO and the patched NSO. Note that if the NSO you are patching is larger than 16 MiB, you will have to use a tool that supports IPS32.
### HBL Support
Atmosphère can use the loader module in order to turn any game on your Switch's home menu into a launchpoint for the Homebrew Menu, rather than launching it through the album applet. This allows one to launch the Homebrew Menu with access to the ~3.2GB of RAM that the Switch reserves for games and applications, as opposed to the 442MB of RAM we are limited to when launching the Homebrew Menu from the album. This also means that it is no longer necessary to install homebrew as `.nsp` files on your Switch so long as you are using this method, as the only reason to do so is to allow the homebrew to access all of the Switch's available memory.
In order to setup this method you will need the latest release of [hbmenu](https://github.com/switchbrew/nx-hbmenu/releases), and the latest release of [hbloader](https://github.com/switchbrew/nx-hbloader/releases). Place `hbmenu.nro` on the root of your Switch's SD Card, and place `hbl.nsp` in the atmosphere folder. From there, simply configure `loader.ini` in the atmosphere folder by replacing the Title ID in the ini (hbl_tid) (it is the Title ID for the album by default) with the Title ID of whatever game you wish to use to launch the Homebrew Menu. A list of Title IDs for Switch Games can be found [here](https://switchbrew.org/wiki/Title_list/Games). Afterwards you may reinsert your SD Card into your Switch and boot into Atmosphère as you normally would. You should now be able to boot into the Homebrew Menu by launching your designated game of choice.
### Button Overrides
By default `loader.ini` is configured to launch the Homebrew Menu when launching the game normally, and launching the game when selecting the game while holding down R. If you wish to change this, you can modify the override_key section of `loader.ini`. Placing an exclamation point in front of whatever button you wish to use will make it so that you will only launch the actual game while holding down that button, otherwise you will go into the Homebrew Menu. Removing the exclamation point will reverse this, meaning that you will boot into the Homebrew Menu only while holding down the assigned button when launching the game.
For example, `override_key=!R` will run the game only while holding down R when launching it, otherwise it will boot into the Homebrew Menu. `override_key=R` will only boot into the Homebrew Menu while holding down R when launching the game, otherwise it will launch the game as normal.
### SM MITM Integration
When the Stratosphere implementation of loader creates a new process, it notifies [sm](sm.md) through the `AtmosphereAssociatePidTidForMitm` command to notify any MITM services of new processes' identities.
pm is a reimplementation of Nintendo's process manager. This module is responsible for tracking running processes on the system, and managing resource limits. pm is also required to create and manage processes for homebrew applications.
## Atmosphère Extensions
There are a few ways in which the Stratosphere implementation of pm differs intentionally from the stock pm.
### IPC: AtmosphereGetProcessHandle
The Stratosphere implementation of pm adds an additional command to the [`pm:dmnt`](https://reswitched.github.io/SwIPC/ifaces.html#nn::pm::detail::IDebugMonitorInterface) interface, called `AtmosphereGetProcessHandle`. Its command ID is `65000` on all system firmware versions. It takes a `u64 process_id` and returns a process handle for the specified process, if that process is known. Notable exceptions include KIPs, which are not known to pm. If the specified process cannot be found, error code 0x20F is returned.
The SwIPC definition for this command follows.
```
interface nn::pm::detail::IDebugMonitorInterface is pm:dmnt {
The Stratosphere implementation of pm shrinks the APPLET memory pool by 24 MiB by default, giving this memory to the SYSTEM pool. This allows custom sysmodules to use more memory without hitting the SYSTEM memory limit.
sm is a reimplementation of Nintendo's service manager. It allows Atmosphère to add or remove process handle limits, add new services, or intercept service calls. This allows high-level intercepting of Horizon OS functionality.
## Atmosphère Extensions
There are a few ways in which the Stratosphere implementation of sm differs intentionally from the stock sm.
### IPC: MITM Commands
The Stratosphere implementation of sm adds a few additional commands to the [`sm:`](https://reswitched.github.io/SwIPC/ifaces.html#nn::sm::detail::IUserInterface) port session.
This command alters the registration for the named service, in order to allow services to intercept communication between client processes and their intended services. It is used by [fs_mitm](fs_mitm.md).
It takes the name of the service to install an MITM for, and returns two handles. The first is a port handle, similar to those returned from the [RegisterService](https://reswitched.github.io/SwIPC/ifaces.html#nn::sm::detail::IUserInterface(2)) command. The second is the server side of a session, called the query session. This session will used by sm to determine whether or not a new session should be intercepted, and to inform the MITM service of the identity of new processes.
The query session is expected to implement the following interface.
```
interface MitmQueryService {
[65000] ShouldMitm(u64 pid) -> u64 should_mitm;
[65001] AssociatePidTid(u64 pid, u64 tid);
}
```
The `ShouldMitm` command is invoked whenever a process attempts to make a new connection to the MITM'd service. It should return `0` if the process's connection should not be intercepted. Any other value will cause the process's connection to be intercepted. If the command returns an error code, the process's connection will not be intercepted.
The `AssociatePidTid` command is invoked on all MITM query sessions whenever a new process is created, in order to inform those services of the identity of a newly created process before it attempts to connect to any services.
If the process that installed the MITM attempts to connect to the service, it will always connect to the original service.
This command requires that the session be initialized, returning error code 0x415 if it is not.
If the given service name is invalid, error code 0xC15 is returned.
If the user does not have service registration permission for the named service, error code 0x1015 is returned.
If the service has not yet been registered, error code 0xE15 is returned.
If the service already has an MITM installed, error code 0x815 is returned.
#### AtmosphereUninstallMitm
Removes any installed MITM for the named service.
This command requires that the session be initialized, returning error code 0x415 if it is not.
#### AtmosphereAssociatePidTidForMitm
This command is used internally by the Stratosphere implementation of the [loader](loader.md) sysmodule, when a new process is created. It will call the `AssociatePidTid` command on every registered MITM query session.
If the given process ID refers to a kernel internal process, error code 0x1015 is returned. This command requires that the session be initialized, returning error code 0x415 if it is not.
### Minimum Session Limit
When a service is registered, the sysmodule registering it must specify a limit on the number of sessions that are allowed to be active for that service at a time. This is used to ensure that services like `fs-pr`, `fs-ldr`, and `ldr:pm` can only be connected to once, adding an additional layer of safety over the regular service verification to ensure that those services are only connected to by the highly priveleged process they are intended to be used by.
By default, the Stratosphere implementation of PM will raise any session limits to at least 8, meaning that for services like `fs-pr` and those mentioned above, up to 8 processes will be able to connect to those sessions, leaving 7 sessions for homebrew to use.
### Weak Service Verification
In system firmware versions before 3.0.1, if a process did not call the [Initialize](https://reswitched.github.io/SwIPC/ifaces.html#nn::sm::detail::IUserInterface(0)) command on its `sm:` session, normally used to inform sm of the process's identity, sm would assume that the process was a kernel internal process and skip any service registration or access checks. The Stratosphere implementation of sm reimplements this vulnerability, allowing homebrew processes to skip service registration and access checks.
The following features are planned to be added in future versions of Atmosphère:
atmosphère has a number of features that are either works-in-progress or planned. Please note that while time-estimates are given, they are loose, and things may be completed sooner or later than advertised.
+ Thermosphère, a hypervisor-based emunand implementation.
+ A feature-rich debugging toolset (a component of Stratosphère).
The following descriptions were last updated on January 14th, 2021
+ A custom debug monitor system module, providing an API for debugging Switch's processes. This may not be a reimplementation of Nintendo's own debug monitor.
+ This should include a gdbstub implementation, possibly borrowing from Luma3DS's.
## tma reimplementation
+ This API should be additionally usable for RAM Editing/"Cheat Engine" purposes.
* **Description** tma ("target manager agent") is a system module that manages communication between the Switch and a client PC. Atmosphere's implementation will allow homebrew on the switch to communicate with a connected PC to do various operations such as exchanging data or interacting with files. It will also serve as the communicator for Atmosphère's planned debugger. This will also include PC-side software for interacting with the Switch.
+ A custom shell system module, providing an means for users to perform various RPC (with support for common/interesting functionality) on their Switch remotely. This may not be a reimplementation of Nintendo's own shell.
* **Development Status**: Planned. Switch-side code is fully implemented but needs heavy refactoring/rebasing, as the code was originally authored in 2018.
+ This should support client connections over both Wi-Fi and USB.
* **Estimated Time**: 2021-2022.
+ A custom logging system module, providing a means for other Atmosphère components (and possibly Nintendo's own system modules) to log debug output.
+ This should support logging to the SD card, over Wi-Fi, and over USB.
## dmnt.gen2 reimplementation
+ An application-level plugin system.
* **Description**: A reimplementation of the Switch's debug monitor, dmnt will provide an interface for debugging applications or system modules running on the Switch. This will include a gdbstub for debugging actively-running system components or applications.
+ This will, ideally, work somewhat like NTR-CFW's plugin system on the 3DS, allowing users to run their own code in a game's process in their own thread.
* **Development Status**: Planned
+ An AR Code/Gameshark analog implementation, allowing for easy sharing/development of cheat codes to run on device.
* **Estimated Time**: 2021-2022
+ Further extensions to existing Atmosphère components.
+ General system stability improvements to enhance the user's experience.
## fs reimplementation
* **Description**: Following mesosphère's completion, atmosphère will have reimplemented all components of the BootImagePackage firmware except for the filesystem services system module. Reimplementing fs will allow for fixing Nintendo bugs (such as corruption when using exFAT filesystems and encoding inconsistencies with UTF-8 and Shift-JIS).
* **Development Status**: Planned.
* **Estimated Time**: 2021-2022.
## settings reimplementation
* **Description**: A planned reimplementation of the settings system module, and with it a removal of the settings mitm. This will greatly simplify atmosphère's boot process, and will allow much more flexible control over the various system settings.
* **Development Status**: Pending development by Adubbz.
* **Description**: A general-purpose hypervisor, thermosphère will enable the virtualization of the Switch's operating system; this is planned to enable debugging of the Switch's kernel.
* **Development Status**: Pending development by TuxSH.
* **Description**: General system stability improvements to enhance the user's experience.
* **Development Status**: Undergoing active development by all members of the atmosphère team.
* **Estimated Time**: June 15th.
# Completed features
The following features were previously included under the planned features section and are now complete.
Please note that this is not an exhaustive list of features present in atmosphère, and only serves to indicate what from the above has been completed.
## system updater homebrew
* **Description**: A user homebrew making use of the new system updater api, so that users can actually use the new api in practice.
* **Completion Time**: July 2020
## system updater api
* **Description**: A planned extension api for stratosphere (tenatively `ams:su`), this will provide an interface for homebrew to safely install system upgrades or downgrades. This will allow for much more easily transitioning safely between different versions of the operating system.
* **Completion Time**: June 2020
## exosphere re-write
* **Description**: exosphère, atmosphère's reimplementation of Horizon's Secure Monitor, was the first component authored for the project in early 2018. It is written in C, and in a style very different from the rest of atmosphère's code. In addition, exosphère was written to conform to constraints that no longer apply in an environment where it is not launched from the web browser, and where using a custom firmware image to orchestrate wake-from-sleep is possible. exosphère currently uses all but 1 KB of the space available to it, putting it at risk of breaking as future firmware updates are supported. A re-write will solve these issues.
* **Completion Time**: June 2020
## mesosphere
* **Description**: mesosphère is a reimplementation of the Horizon operating system's Kernel. It aims to provide an open-source reference for Nintendo's code.
* **Estimated Time**: September 2020
## ams-on-mariko
* **Description**: Atmosphere cannot run as-is on Mariko hardware. A large number of changes are needed in many components. Although secure monitor support is complete in exosphere, additional work is needed on the bootloader and stratosphere sides as well. Mariko support will also require further design thought; atmosphere's debugging design heavily relies on reboot-to-payload and (more generally) the ability to perform warmboot bootrom hax at will. This is not possible on Mariko, and will require a new design/software support for whatever solution is chosen.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.