3DS reverse engineering

Discussion of development of software for any "obsolete" computer or video game system. See the WSdev wiki and ObscureDev wiki for more information on certain platforms.
Post Reply
nocash
Posts: 1405
Joined: Fri Feb 24, 2012 12:09 pm
Contact:

3DS reverse engineering

Post by nocash »

I've started adding ARM11 support to my disassembler some days ago, and I am now examining 3DS bootroms, and try to learn about the 3DS in general. I have a New3DS console laying around for some years, but I could never make any sense of it (and don't really know how to start a game, and least how to program homebrew code for it). But I've managed to view two game trailers - and the stereoscopic 3D does actually look neat! I might like that hardware - if I could ever figure out how to use it.

For understanding the 3DS hardware I/O registers, my starting point is here: https://www.3dbrew.org/wiki/IO_Registers
At first glance, that refers to things like "ABC Registers for ABC Services used Process ABC for ABC module" - without giving much of a hint what "ABC" stands for.
At second glance, it looks as names like "ABC" are just newly invented homebrew aliases for well-known NDS/DSi registers. Plus some new 3DS registers. At the moment I couldn't say if there are many new registers, or if it the 3DS is just a DSi with some extra gimmicks.

Some general specs are here: https://www.3dbrew.org/wiki/Hardware the two main differences seem to be new GPU for stereoscopic 3D and the newer ARM11 CPU.

The GPU seems to be some standard off-the-shelf hardware (DMP PICA), so I hope that specs are openly available. It might be difficult to emulate that thing though, and possibly slow when using raw software emulation (without trying to parse the stuff to opengl or direct3d). The bootrom seems to be capable of displaying an error message? Though I can't see any font data in the bootrom, or is there a built-in font in the GPU itself?

The ARM11 seems to be DualCore? Or even QuadCore for New3DS? I had believed the 3DS would just have ARM9+ARM11. But now it looks as if it's actually ARM9+ARM11+ARM11 (+ARM11+ARM11 for New3DS. That - and the speed of 268MHz (or even 804MHz) per ARM11 core - that would be also difficult (and very slow) to emulate. Not to mention the Virtual Memory on ARM11 side, which might also slowdown emulation.

Many I/O registers are said to be accessible by ARM9 and ARM11. I wonder what that means in practice, especially if there are two or more ARM11 cores. It isn't too clear if there are separate sets of I/O ports for each core, or if all cores access the same registers (with only one of them being supposed to do so at once).

I have no idea where the homebrew register names came from. As far as I remember somebody mentioned that the official 3DS SDK is using names like SCFG_xxx (same/similar as on DSi) (EDIT: Or was it something different, like REG_OS_PAUSE_JTAG or HWi_WSYS09_JTAG on 3DS, instead of the DSi's SCFG_JTAG?). So the homebrew names might be just there for lack of official names. Though in case of "MP" it looks as if the homebrewers didn't even realize why they had used that name for it (I guess it stands for local MultiPlayer wifi, going by their description). Btw. are there any documents with official register names? Or official specs for the hardware? Or more homebrew specs other than 3dbrew wiki?

Would be cool if somebody could answer such newbie questions!
Last edited by nocash on Sat Feb 23, 2019 11:24 am, edited 1 time in total.
Pokun
Posts: 2675
Joined: Tue May 28, 2013 5:49 am
Location: Hokkaido, Japan

Re: 3DS reverse engineering

Post by Pokun »

Although I haven't tried it myself, I noticed that Nintendo has relaxed developer registration for individuals so it's easier than ever to legally get development tools and documents for Nintendo's systems. But now I also read that by registering you are swearing that you don't leak it or use it for homebrew or emulator development, and breaching the contract may jeopardize your emulator or the homebrew wiki you contribute to.
nocash
Posts: 1405
Joined: Fri Feb 24, 2012 12:09 pm
Contact:

Re: 3DS reverse engineering

Post by nocash »

I've plundered the 3dbrew hardware register pages, and collected and reformatted the info for viewing as 80 column text. The result is now included in a new "3DS Reference" section in gbatek: http://problemkaputt.de/gbatek.htm#3dsreference
At the moment, it is just containing shamelessly copied info from of 3dbrew pages, I didn't write any of the descriptions myself (and, in most cases, I didn't even read them yet). Plans for future would be to read & verify & rewrite & extend the text step by step, until, hopefully, I could honestly say that I've written & contributed a good bit of information on my own someday.

Anyways, for now, the text is just reflecting what I know about the console - if it's missing important parts that are already known and documented elsewhere - please let me know! There's also a todo-list at the end of the 3DS section with some specific issues & questions (and plenty of "unknown" bits in the register descriptions).
Pokun wrote:Although I haven't tried it myself, I noticed that Nintendo has relaxed developer registration for individuals so it's easier than ever to legally get development tools and documents for Nintendo's systems. But now I also read that by registering you are swearing that you don't leak it or use it for homebrew or emulator development...
Yeah, looks as if they are announcing something like that here: https://developer.nintendo.com/ it does almost sound to good to be true - free devkits for everyone without any programming experience whatsoever? I guess it may turn out that the free devkit might require expensive devhardware, and programming manuals for 3D consoles are traditionally only covering OS functions and libraries instead of hardware specs. Either way, I am not so motivated to swear & register for obtaining documentation.

The code in the 3DS bootrooms is surprisingly easy to read. I was almost thinking that it were written in ASM, or that their compiler evolved to produce more meaningful code. On the other hand, wide parts of the bootrom consists of mini-functions that do things like "[register]=value" (which is inefficient by itself, but a compiler can't screw up too much on such basic commands). The part that isn't easy to read is the boot error text output - I think pixel drawing is yet a bit too complex for compiler code.
Alongsides, I have also found the font for the error message - the size and encoding are rather unexpected:

Code: Select all

;------------------
font_3x5_pix:      SPC  !   "   #   $   %   &   '   (   )
 dd 02B5D48Ch  ;00 000 010 101 101 011 101 010 010 001 100
 dd 02BF1B12h  ;00 000 010 101 111 110 001 101 100 010 010
 dd 02152412h  ;00 000 010 000 101 010 010 010 000 010 010
 dd 001DCA12h  ;00 000 000 000 111 011 100 101 000 010 010
 dd 0217560Ch  ;00 000 010 000 101 110 101 011 000 001 100
;---                *   +   ,   -   .   /   0   1   2   3
 dd 00001FBFh  ;00 000 000 000 000 000 001 111 110 111 111
 dd 2A001A89h  ;00 101 010 000 000 000 001 101 010 001 001
 dd 171C2ABFh  ;00 010 111 000 111 000 010 101 010 111 111
 dd 2A404AA1h  ;00 101 010 010 000 000 100 101 010 100 001
 dd 00824FFFh  ;00 000 000 100 000 100 100 111 111 111 111
;---                4   5   6   7   8   9   :   ;   <   =
 dd 2FFFF008h  ;00 101 111 111 111 111 111 000 000 001 000
 dd 2C96D497h  ;00 101 100 100 101 101 101 010 010 010 111
 dd 3FE7F020h  ;00 111 111 111 001 111 111 000 000 100 000
 dd 09A69497h  ;00 001 001 101 001 101 001 010 010 010 111
 dd 0FE7F108h  ;00 001 111 111 001 111 111 000 100 001 000
;---                >   ?   @   A   B   C   D   E   F   G
 dd 264B2DFEh  ;00 100 110 010 010 110 010 110 111 111 110
 dd 11B6DB24h  ;00 010 001 101 101 101 101 101 100 100 100
 dd 0AF74BFFh  ;00 001 010 111 101 110 100 101 111 111 111
 dd 10BEDB25h  ;00 010 000 101 111 101 101 101 100 100 101
 dd 22772DE7h  ;00 100 010 011 101 110 010 110 111 100 111
;---                H   I   J   K   L   M   N   O   P   Q
 dd 2A365AB2h  ;00 101 010 001 101 100 101 101 010 110 010
 dd 2A367B6Dh  ;00 101 010 001 101 100 111 101 101 101 101
 dd 3A3A5F75h  ;00 111 010 001 110 100 101 111 101 110 101
 dd 2AB65B62h  ;00 101 010 101 101 100 101 101 101 100 010
 dd 2A57DAA3h  ;00 101 010 010 101 111 101 101 010 100 011
;---                R   S   T   U   V   W   X   Y   Z   [
 dd 33F6DB7Bh  ;00 110 011 111 101 101 101 101 101 111 011
 dd 2C56DB4Ah  ;00 101 100 010 101 101 101 101 101 001 010
 dd 3256D492h  ;00 110 010 010 101 101 101 010 010 010 010
 dd 2956FAA2h  ;00 101 001 010 101 101 111 101 010 100 010
 dd 2E5D5ABBh  ;00 101 110 010 111 010 101 101 010 111 011
;---
;well, that is a bit crazy, saving memory for the sake of
;keeping more unused ROM zerofilled.
;or perhaps it's done for not overloading the HLL-coded wrchr
;function with much too many amounts of data : /
Oh, and no$gba was also updated together with gbatek - http://problemkaputt.de/gba.htm - with some basic groundwork for possible future 3DS support - and a rather bewildering bugfix for a problem that I wasn't aware off at all (it seems that all builds in the past some years did have the profiler feature enabled by default - making no$gba debug version to run slow as glaciers).

Code: Select all

23 Feb 2019 - no$gba version 2.9d
- debug/setup: disabled profiler by default (for fast emulation) (thanks Dwedit)
- debug/disass: disassembler support for UAL syntax (optional) and ARM11 opcodes
- dsi/help: added SD_EXT_IRQ_STAT/MASK (insert/eject state and irq for emmc)
- 3ds/help: added 3DS register specs (thanks 3dbrew.org/wiki/IO_Registers)
iamrifki
Posts: 3
Joined: Sat Feb 09, 2019 4:30 pm

Re: 3DS reverse engineering

Post by iamrifki »

Have you ever heard of the Citra Emulator, nocash? https://github.com/citra-emu/citra
nocash
Posts: 1405
Joined: Fri Feb 24, 2012 12:09 pm
Contact:

Re: 3DS reverse engineering

Post by nocash »

Heard of it, yes. But I may be wrong about what it is doing... as far as I know it's emulating the ARM11 cpu, and the 3DS OS, without trying to emulate the 3DS hardware. I have had a brief look at the citra homepage and github page yesterday, and I didn't find source code files for hardware emulation (except perhaps for the yuv-to-rgb Y2R part), and for console specs they do only have a link to an ARM11 pdf, and to the 3dbrew wiki. I may have missed some important stuff though, maybe there's much more low level HW emulation in there...?

What I know of: For citra related 3DS sound, there is a separate github page from wwylele with Teak DSP emulation, and with readme pages describing the Teak MMIO registers. That is looking like pretty cool low level stuff : )
naseyuki
Posts: 6
Joined: Wed Feb 13, 2019 6:30 pm

Re: 3DS reverse engineering

Post by naseyuki »

-
Last edited by naseyuki on Tue Jun 16, 2020 5:10 pm, edited 1 time in total.
nocash
Posts: 1405
Joined: Fri Feb 24, 2012 12:09 pm
Contact:

Re: 3DS reverse engineering

Post by nocash »

Oh, yeah, I hope it won't be the end of the world, but the next gen handheld scene community can be sometimes as helpful as saying "Don't worry about that, I think that we already know how to do it!" ; )

3dbrew has this about shaders https://www.3dbrew.org/wiki/GPU/Shader_Instruction_Set the opcode table is a bit hard to read, but I hope that it will make some more sense when analyzing it step by step. The page says that it was rev-engineered, I don't know if nintendo has better specs for it. Why are that shader instructions so special at all, I thought that the PICA200 gpu would be standard hardware? I haven't checked if there are official specs for it yet though.

This page https://www.3dbrew.org/wiki/GPU/Internal_Registers seems to cover the main part of the gpu. The page formatting appears to be a little bit very insane - but the actual info isn't so bad - the trick is to split the 9 sections to 9 separate pages/files/chapters, that's making it much easier to read.

The one big thing that seems to be missing is information about matrices. Searching the 3dbrew wiki gives only three hits for matrix (mostly for pages that describe fileformats), but there isn't anything mentioning that the GPU could do matrix maths - is that still missing/undocumeted?
Or is it really unsupported by the GPU?
The ARM11 seems to have some SIMD extension, maybe that allows to do matrix maths on ARM11 side?
naseyuki
Posts: 6
Joined: Wed Feb 13, 2019 6:30 pm

Re: 3DS reverse engineering

Post by naseyuki »

-
Last edited by naseyuki on Tue Jun 16, 2020 5:10 pm, edited 1 time in total.
nocash
Posts: 1405
Joined: Fri Feb 24, 2012 12:09 pm
Contact:

Re: 3DS reverse engineering

Post by nocash »

Thanks for the shader example. Okay, if they are doing it like that then there seems to be really no matrix hardware.
I guess one could also use the shader for matrix by matrix multiplication, best with pre-swapped rows/columns in one matrix, or otherwise use the ARM11 for that multiplication.

If there's no matrix hardware, that does also solve another question that I had in mind: I was wondering if the GPU were automatically producing stereoscopic output (by setting Left and Right projection matrices before rendering the scene). But now it's looking as if one must render Left and Right scenes separately.

Some 3D related terms are a bit confusing to me. I can't grasp what is meant by "Uniform", or, I get some idea what it is, but not why it's called like that. Looking at https://en.wikipedia.org/wiki/Uniform_(disambiguation) doesn't help either (I couldn't say if or which of that meanings does apply in this case). For now, I am just treating it as slang for saying "constant", or "immediate", or "general purpose".

---

For booting code, I think I have now figured out how to do that... The bootrom does first load a "NCSD" sector (from first eMMC sector), which points to a "FIRM" sector, which contains entrypoints & load addresses for bootcode. And storing the "sighax" values in the FIRM's RSA signature field should most probably allow to freely modify the entrypoints & bootcode.

So far, that sounds relative simple and comfortable. I'll only need to figure out which encryption keys are needed for modification (and if they are console-unique). But for now, I can just wire the console to a SD/MMC card reader - and then see where I can get from there (and with the wires attached I could also easily unbrick the console if something goes wrong).

---

Also good to know that there's no official documentation for the GPU, then I won't have to waste time on searching for it!
naseyuki
Posts: 6
Joined: Wed Feb 13, 2019 6:30 pm

Re: 3DS reverse engineering

Post by naseyuki »

-
Last edited by naseyuki on Tue Jun 16, 2020 5:10 pm, edited 1 time in total.
calima
Posts: 1745
Joined: Tue Oct 06, 2015 10:16 am

Re: 3DS reverse engineering

Post by calima »

3dlabs' logic was something like "it is uniform to all executions of this shader in this drawcall", vs varying "it varies between different executions". Varying being a variable passed between shader stages. In the above asm, varyings are called either inputs or outputs.
nocash
Posts: 1405
Joined: Fri Feb 24, 2012 12:09 pm
Contact:

Re: 3DS reverse engineering

Post by nocash »

Thanks! I was wondering if one needed to study uniform maths for fully understanding this console.
nocash
Posts: 1405
Joined: Fri Feb 24, 2012 12:09 pm
Contact:

Re: 3DS reverse engineering

Post by nocash »

Hmmmm, the 3DS project seems to have died before I got started with it : /

After disassemblid the New 3DS XL a bunch of times, one of the pins in one of the three top-screen-unit connectors got bent inside of the connector, making it impossible to fully insert the FFC cable. The connector has 31 pins, the total width of the socket is about 9.4mm. I think that it is this specific part: https://www.molex.com/molex/products/da ... ECTORS.xml that is, the black socket with white lid, on the far left edge of this photo: https://d3nevzfk7ii3be.cloudfront.net/i ... A2dBL.full

Does anybody know how to get a replacement part for that?

Currently, the console switches off a few seconds after power up, with the bottom screen backlight flashing for a short moment. I assume the broken connector goes to top screen backlight (and probably speakers/sliders). It might be possible to bridge the backlight pins with a resistor (if I knew where those pins are on mainboard), maybe the console would boot up with that, so I could at least continue rev-engineering the console (just without top screen).

---

What I was doing was hooking the 3DS mainboard's eMMC chip to an SD/MMC card reader, which didn't work with neither of my card readers. I had no problems doing the same thing with the DSi. I think the difference is that DSi has resistors in the CLK and CMD lines (those should help in cases where the console pulls CLK low, while the card reader wants to pull it high). The 3DS board does have solder pads for that resistors too, but they are just bridged with wires. So I had cut that wires, and attached cables for later attaching resistors on the other PCB side. Well, and with that cables in place, I was optimistic that I won't ever have to remove the mainboard again - and then discovered that the FFC connector had died : /

PS.
molex webpage wrote:Durability (mating cycles max) 10
I can confirm that 10 cycles appear to be maximum, mine died after plugging/unplugging 5-7 times.
zoogie
Posts: 10
Joined: Sat Nov 10, 2018 5:38 pm

Re: 3DS reverse engineering

Post by zoogie »

nocash wrote:Hmmmm, the 3DS project seems to have died before I got started with it : /

After disassemblid the New 3DS XL a bunch of times, one of the pins in one of the three top-screen-unit connectors got bent inside of the connector, making it impossible to fully insert the FFC cable. The connector has 31 pins, the total width of the socket is about 9.4mm. I think that it is this specific part: https://www.molex.com/molex/products/da ... ECTORS.xml that is, the black socket with white lid, on the far left edge of this photo: https://d3nevzfk7ii3be.cloudfront.net/i ... A2dBL.full

Does anybody know how to get a replacement part for that?

Currently, the console switches off a few seconds after power up, with the bottom screen backlight flashing for a short moment. I assume the broken connector goes to top screen backlight (and probably speakers/sliders). It might be possible to bridge the backlight pins with a resistor (if I knew where those pins are on mainboard), maybe the console would boot up with that, so I could at least continue rev-engineering the console (just without top screen).

---

What I was doing was hooking the 3DS mainboard's eMMC chip to an SD/MMC card reader, which didn't work with neither of my card readers. I had no problems doing the same thing with the DSi. I think the difference is that DSi has resistors in the CLK and CMD lines (those should help in cases where the console pulls CLK low, while the card reader wants to pull it high). The 3DS board does have solder pads for that resistors too, but they are just bridged with wires. So I had cut that wires, and attached cables for later attaching resistors on the other PCB side. Well, and with that cables in place, I was optimistic that I won't ever have to remove the mainboard again - and then discovered that the FFC connector had died : /

PS.
molex webpage wrote:Durability (mating cycles max) 10
I can confirm that 10 cycles appear to be maximum, mine died after plugging/unplugging 5-7 times.
Any luck getting that part and resuming 3ds R&D?

If you need some assistance in getting the thing fully softmodded, I could help you in PMs with that. It's really easy if you already have a userland entry point.
The online guides tend to be overly wordy because they are mostly dealing with people who aren't technically savvy. I can steer you around most of that.
nocash
Posts: 1405
Joined: Fri Feb 24, 2012 12:09 pm
Contact:

Re: 3DS reverse engineering

Post by nocash »

Damaged hardware
I didn't got a replacement part. Molex is listing several distributors like mouser, and those distributors seem to be stating that they don't have that connector in stock, and that one could contact them for ordering details. I haven't tried that... the connectors seem to be produced in reels of 3000 pieces, which makes me doubt that they would happily process orders of 1-2 pieces, though maybe they'd say "no problem". Does anybody have experiences ordering such exotic parts?

The other option would be buying a new New3DSXL mainboard for about $40 or so. That would hopefully also get me rid of having a japanese firmware on the console (which is really distracting, I can't even power-off the console without running into a mysterious japanese power-off message; I've been usally holding the power-button pressed for some seconds to make that message disappear).

Anyways, I've got the console resurrected (with lower-screen only) by bridging the upper backlight contacts with a resistor (wired to the two "square" gold contacts on the right board-edge, next to the power-managment chip) (I've tried 180, 1K5, 3K3 and 10K ohm, of which 1K5 worked best; 180 worked, too, but that would produce more heat, and 3K3 and 10K didn't work at all).

Hardmod
I've got the hardmod working so far that I can dump the CID and CSD when connecting the New3DS to the SD/MMC slot of a DSi console, so I do at least know that my wiring is correct (and that it was correct all the time, and that I wouldn't have needed to take apart the console a dozen of times to check the damn wiring). I've meanwhile also found a webpage that says that New3DS works only with some card readers (as opposed to Old3DS), so that might explain why my PC can read DSi eMMC, but not 3DS eMMC. My theory is that JEDEC might have intentionally vandalized the MMC specs to make newer eMMC chips incompatible with standard MMC card readers, which might help to phase-out MMC, and to push ahead their newer UFS standard. Or maybe they have just unintentionally screwed up the MMC standard.

In theory I could use the DSi hardware to install sighax & new firmware on the 3DS. The problem is that I would need a OTP dump for obtaining the firmware encryption key. Or alternately: I would need to know the (de-)crypted content of the firmware sectors, then I could simply install my new code by XORing the decrypted old/new bytes, I guess that's how it's usually done?
The first problem would be: Are there many different firmwares to deal with? Or are the firmwares all same (at least concerning the first some bytes with entrypoint)? If there are different firmwares, how are chances to know which version I have (on japanese console without top screen)?
The second problem would be: If the firmware is already patched, is there some standard for dealing with that situation? Ie. detect if it is patched, and to remove the patch (or keep using the existing patch - if it's containing a standarized stub that loads the actual firmware from some unencrypted region).

Software/specs
Apart from fighting with (defunct) hardware, I've spent the last some weeks on forensic analysis of several 3dbrew pages. I am having quite some problems to understand the language used there. If a sentence begins with something like "As of version 1.2.3-45 there is (in almost all cases, but not always, there are certain exceptions)..." well, then I am so confused that I find it difficult to read the rest of the sentence.
My current strategy is to annotate everything "Uh, what does that mean?", and then, to carefully remove all irrelevant & confusing words in the sentence step by step (which can sometimes end up with figuring out that the whole sentence was completely irrelevant, but it takes time to get there).
Well, and the rest of the time I am trying to re-order the information, like moving the most important tables to the begin of the page/chapter, and merging tables+subtables into a single table... hopefully making it easier to grasp what it is all about.
Post Reply