import { Card, CardContent } from "../components/ui/Card"; import { MemoryLayout } from "../components/MemoryLayout"; const GITHUB_URL = "https://github.com/alula/hbpatcher"; const DIRTY_HACK_DISCORD_SOURCE = "https://discord.com/channels/269333940928512010/414949821003202562/1440485257550889221"; const FW_19_FIX_SOURCE = "https://github.com/Atmosphere-NX/Atmosphere/blob/7aa0bed869c7ed642d5503c6c80e3dc337bc56bd/stratosphere/loader/source/ldr_capabilities.cpp#L428"; export function AboutPage() { return (
This tool may or may not work correctly. It is not the responsibility of the author of this tool or the author of the homebrew. Users should obtain the latest version of homebrew recompiled against the latest libnx if possible over using this tool. This tool is only an assist for unmaintained homebrew to reduce the impact of kernel changes.
If you encounter unmaintained and closed-source homebrew that doesn't work with this patcher, please{" "} open an issue on GitHub {" "} or{" "} DM me on GBATemp .
Note: I do not offer support for patching piracy-related homebrew (such as DBI).
libnx v4.10.0 (or newer).
The updated library resolves the memory conflict and stays backward compatible with older Atmosphère versions and firmwares.
You can find the source code for this tool on{" "} GitHub .
This project is licensed under the GNU General Public License v2.0 or later (GPL-2.0-or-later). See the{" "} LICENSE {" "} file for details.
Atmosphère integrates kernel optimizations from Firmware 21.0.0.
This improves performance but breaks older homebrew compiled with
libnx versions before v4.10.0, causing crashes that can occur on
exit, during thread creation, or at runtime. If your homebrew is
unmaintained, use this tool to patch the .nro files.
If the app is still active, ask the developer to update it.
This tool scans your .nro files to see if they
contain old libnx code that writes to the conflicting memory
region. If it detects a conflict, it patches certain{" "}
libnx functions to move their TLS writes
{" "}
from the conflicting offset 0x108 to the safe offset{" "}
0x180.
Note that the patches applied by this tool do not{" "}
move the ThreadVars structure, which resides at the
very end of the region. Effectively, this reduces (squeezes) the
available space for TLS slots. While this works for the vast
majority of homebrew, applications that use an unusually large
number of TLS slots might overwrite critical thread data (and
cause crashes - this is an edge case, patching this is out of
scope for this tool).
The Thread Local Region is 0x200 bytes large. The
first 0x180 bytes are effectively reserved for the
kernel, while the last 0x80 bytes (
0x180-0x200) are for userland. Official software
respects this split, placing its TLS data at offset{" "}
0x180.
Previous versions of libnx chose to start user TLS
slots at 0x108 (encroaching on the kernel's area)
to maximize the number of available slots. This was safe until
Firmware 21.0.0, where Nintendo added{" "}
cache_maintenance_flag at 0x104 and{" "}
thread_cpu_time at 0x108.
Now, the kernel writes to 0x108 on every thread
switch, overwriting the TLS data that old homebrew stored there.
This corruption causes the crashes.
It might seem logical for the Homebrew Loader (hbl)
to handle this automatically, but that's out of scope for a
simple program loader. HBL's job is to execute code as-is, not
to dynamically repair binaries.
Trying to patch memory offsets on the fly is invasive and fragile; if HBL guesses wrong, it could break otherwise functioning homebrew. Furthermore, baking a patcher into the loader sets a bad precedent. The maintainers want to encourage proper fixes (recompilation) rather than relying on permanent "dirty hacks" within the OS itself.{" "} Source: Switchbrew
Atmosphère aims to reimplement Nintendo's kernel logic 1:1. When Nintendo changes how the kernel works, Atmosphère must follow suit to ensure official games run correctly.
While the developers have added quiet workarounds in the past (like the{" "} FW 19.0.0 debug flags ), this specific issue was too risky to mask. A workaround here would require adding conditional logic to the kernel scheduler—the most time-critical part of the system. Adding checks for "broken homebrew" during every thread switch would add complexity, potentially degrade performance system-wide, and could even introduce bugs in official games.