Nintendo 3DS "Custom Firmware"
Luma3DS patches and reimplements significant parts of the system software running on all models of the Nintendo 3DS family of consoles. It aims to greatly improve the user experience and support the 3DS far beyond its end-of-life. Features include:
Luma3DS requires boot9strap to run.
Once boot9strap has been installed, simply download the latest release archive and extract the archive onto the root of your SD card to "install" or to upgrade Luma3DS alongside the homebrew menu and certs bundle shipped with it. Replace existing files and merge existing folders if necessary.
The main Luma3DS configuration menu can be accessed by pressing Select at boot. The configuration file is stored in /luma/config.ini
on the SD card (or /rw/luma/config.ini
on the CTRNAND partition if Luma3DS has been launched from the CTRNAND partition, which happens when SD card is missing).
The chainloader menu is accessed by pressing Start at boot, or from the configuration menu. Payloads are expected to be located in /luma/payloads
with the .firm
extension; if there is only one such payload, the aforementionned selection menu will be skipped. Hotkeys can be assigned to payload, for example x_test.firm
will be chainloaded when X is pressed at boot.
The overlay menu, Rosalina, has a default button combination: L+Down+Select. For greater flexbility, most Rosalina menu settings aren't saved automatically, hence the "Save settings" option.
GDB ports, when enabled, are 4000-4002
for the normal ports. Use of attach
in "extended-remote" mode, alongside info os processes
is supported and encouraged (for reverse-engineering, also check out monitor getmemregions
). The port for the break-on-start feature is 4003
without "extended-remote". Both devkitARM-patched GDB and IDA Pro (without "stepping support" enabled) are actively supported.
We have a wiki, however it is currently very outdated.
Luma3DS consists of multiple components. While the code style within each component is mostly consistent, these components have been written over many years and may not reflect how maintainers would write new code in new components/projects:
Process9
code and to inject all other custom components. This was the first component ever written for this project, in 2015NATIVE_FIRM
kernel (Kernel11
). It is injected by the above mentioned baremetal loader into the kernel by hooking its startup code, then hooks itself into the rest of the kernel. Its features include hooking system calls (SVCs), introducing new SVCs and hooking into interprocess communications, to bypass limitations in Nintendo's system design. This is the component that allows Rosalina to pause other processes on overlay menu entry, for example. This was written at a time when we didn't fully reverse-engineer the kernel, and originally released in 2017 alongside Rosalina. Further hooks for "game plugin" support have been merged in 2023err:f
(fatal error screen) reimplementation, and much more. Introduced in mid-2017, and has continuously undergone changes and received many external contributions ever sinceloader
to load them. The reimplemention allows for break-on-start GDB feature in Rosalina, as well as lifting FS access control restrictions the proper way. Introduced in 2019There are still a lot more features and consolidation planned for Luma3DS! Here is a list of what is currently in store:
TwlBg
and AgbBg
. This will allow much better, and more configurable, upscaling for top screen in DS and GBA games (except on Old 2DS). This is currently being developed privately in C++23 (no ETA). While this is quite a difficult endeavor as this requires rewriting the entire driver stack in semi-bare-metal (limited kernel with no IPC), this is the most critical feature for Luma3DS to have and will make driver sysmodule reimpelementation trivialProcess9
for TWL_FIRM
and AGB_FIRM
to allow for more features in DS and GBA compatibility mode (ones that require file access)Kernel11
reimplementationKernel11
pertaining to attaching a new KDebugThread
to a KThread
on thread creation, and another thread null-dereferencing thread->debugThread
. This causes the cheat engine to crashes games that create and destroy many threads all the time (like Pokémon).
Kernel11
is reimplemented.To build Luma3DS, the following is needed:
$PATH
dkp-pacman
(or, for distributions that already provide pacman, add repositories): https://devkitpro.org/wiki/devkitPro_pacman3ds-dev
metapackage: sudo dkp-pacman -S 3ds-dev --needed
While Luma3DS releases are bundled with 3ds-hbmenu
, Luma3DS actually compiles into one single file: boot.firm
. Just copy it over to the root of your SD card (ftpd is the easiest way to do so), and you're done.
This software is licensed under the terms of the GPLv3. You can find a copy of the license in the LICENSE.txt file.
Files in the GDB stub are instead triple-licensed as MIT or "GPLv2 or any later version", in which case it's specified in the file header. PM, SM, PXI reimplementations are also licensed under MIT.
Luma3DS would not be what it is without the contributions and constructive feedback of many. We would like to thanks in particular: