It is currently Wed May 22, 2019 2:12 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 38 posts ]  Go to page Previous  1, 2, 3
Author Message
PostPosted: Thu May 16, 2019 6:48 pm 
Offline

Joined: Fri Feb 24, 2012 12:09 pm
Posts: 899
Yipieh, I got my screen output and backlight enable working. Currently it's only showing a striped bitmap, but it should be no issue to display text output instead of that test screen.

profi200 wrote:
There was no need to reverse engineer the GPU/LCD init code. It has been figured out long ago. Most of the register names are missing but it works well: https://github.com/derrekr/fastboot3DS/ ... gfx.c#L249 boot9strap has very similar code.
Good point. Using that might have been easier. But after disassembling the bootcode, I ended up writing my own code... it took a bit longer than 1-2 days though.
After extracting the GPU/LCD related code from the bootrom, I still about 2400 lines of messy video code. The most messy/buggy/confusing part was the table-based backlight initialization.
Those tables contain only one halfword each. But the bootrom tries to read more than one halfword from each table, and then does weird squaring and interpolation on those table value(s). I guess all that code could make sense with bigger tables, but with the 1-entry-only tables it's just crazy nonsense.

Then I spend some days on having made a silly mistake (most of my GPU register writes did hang the CPU... which turned out to be just caused by using a wrong I/O base address, kinda stupid).

And then I finally got a picture displayed, but the console powered off shortly after backlight enable. I got that fixed by setting 10202000h+240h (and +A40h) to 0020h. A bigger value like 0040h causes power-off. I am not sure what has happened there, part of the problem might be that I've replaced the top-screen backlight by a resistor (which may be too small for large brightness settings). But even then, my initialization should be same as for bootrom error messages (the bootrom does work okay, even with the resistor, but my own code behaves differently for some reason).
EDIT: Seems to be now working as with bootrom. I think the problem was caused by a bug in my I2C reading function for retriving MCU type/version (which had returned all FFh's, ie. lcd_type=F, and mcu_version=F.FF; correct would have been type=1 and ver=3.38hex).

profi200 wrote:
When i was measuring how much time/cycles the CPU spends waiting for a single byte I2C transfer (switched to using interrupts since) i got far over 10000 cyles on ARM11 (measured using the MPCore performance monitor)...
I had no problems at all with the power LED but i only use it as sleep indicator anyway.
Do you know what frequency that MPCore timer counts at? Bootrom code looks like... 134MHz?
And is that 10000 cycles for one raw I2C byte? Or a whole "Device+Index+Databyte" sequence with 3 bytes in total?
The delay is needed only after the last Databyte of each transfer. If you were doing only one transfer per frame, then you have had more than enough delay time.
Btw. I have edited the I2C delay stuff in previous post. The bootrom seems to aim at 2*188 cycles delay after last byte... although my early tests included a much longer DSi-style delay before each byte - which should have worked, too (theoretically, but somehow it didn't work in practice).

profi200 wrote:
Everything detects modified FIRM partitions by looking for the sighax signatures. That's it.
That's not so very suitable for detection. It would require to (RSA-)decrypt the signature and then examine if it contains normal padding bytes (or have a database with all currently known used sighax signatures (which could run into billions if somebody likes bruteforcing more and more variants).
And worst, the FIRM cannot by (AES-)decrypted without OTP dump, so impossible to examine the signatures at all (like, when you get a console, don't have a OTP dump, and want to patch it via hardmod - one could do that only with original FIRM, or with a backup-copy of the original FIRM stored in some unused eMMC sectors). But well, not so much of a problem if there's no standard for backups yet.

PSI wrote:
Hi nocash, I made an account to get a chance to talk to you. I'm also making a 3DS emulator: https://github.com/PSI-Rockin/Corgi3DS
My emulator runs the boot ROMs and successfully loads NATIVE_FIRM off the NAND. It doesn't get much further than that as Kernel11 needs MMU, but it's also capable of booting ARM9 payloads such as GodMode9 from an SD image.
Cool, nice to hear that there is someone doing low-level emulation for 3DS. The other low-level thing that I know of is the Teak/DSP emulation from wwylele, which is also quite impressive (although that part is most distant from the boot process).

Yeah, the MMU is keeping me away from adding 3DS support in no$gba, too. At the moment, I don't even know what page-size it is using. I have no clear picture of what needs to be done for emulating it.

Another small obstacle is that no$gba is currently designed to map most I/O ports to only ARM7, or only ARM9. Whilst 3DS seems to allow to access (many) I/O ports from either ARM9 or ARM11 (or both). Well, that isn't a major problem, but I may need to rewrite a bunch of code, instead of just re-using the old DSi emulation for 3DS.

The good thing about 3DS is that the bootroms are dumped meanwhile, so one can start emulation & research at power-up time. For the DSi, the bootroms are still undumped. And, when I had starting to emulate DSi, it wasn't even known how to decrypt the eMMC bootsectors, so emulation had to start excecution after the yet unknown boot process (that wasn't so funny to work that way).

_________________
homepage - patreon


Top
 Profile  
 
PostPosted: Thu May 16, 2019 9:36 pm 
Offline

Joined: Mon May 13, 2019 5:32 pm
Posts: 3
The MMU is well-documented on ARM's official docs. I haven't looked too deeply into it, although I know a few things: it's completely accessed through CP15 registers, it works through a "page-walking" scheme (where the code provides pointers to page tables in memory to the MMU), and page sizes range from 4 KB to 16 MB. It seems rather complex, and there's also the issue of having to emulate access privileges...

The good news is that the boot ROMs don't need any MMU emulation at all, so you can feasibly get the boot ROM error screen just by pretending the NAND isn't there. It writes directly to framebuffer to display the error too. I do think you need timer emulation (and interrupts) to get the error screen however, and of course you need PXI (aka IPC).

To actually get a firmware or payload to boot is more involved. You need AES, SHA, and RSA hardware all implemented, and the eMMC protocol must obviously be implemented too. You will also need the OTP and the NAND CID: OTP is used to derive the console-unique keys to decrypt the NAND, and the CID is also used for decryption. The boot process is semi-documented on 3dbrew, so you get some idea of what's going on.


Top
 Profile  
 
PostPosted: Fri May 17, 2019 4:47 am 
Offline

Joined: Fri May 10, 2019 4:48 am
Posts: 3
nocash wrote:
profi200 wrote:
There was no need to reverse engineer the GPU/LCD init code. It has been figured out long ago. Most of the register names are missing but it works well: https://github.com/derrekr/fastboot3DS/ ... gfx.c#L249 boot9strap has very similar code.

Those tables contain only one halfword each. But the bootrom tries to read more than one halfword from each table, and then does weird squaring and interpolation on those table value(s). I guess all that code could make sense with bigger tables, but with the 1-entry-only tables it's just crazy nonsense.

I have not reverse engineered that but usually everyone just dumps the backlight levels from HOME menu. Careful with these since there is apparently no safety limit on the backlight. In the early days someone caused his 3DS to heat up by setting the backlight regs very high.

nocash wrote:
profi200 wrote:
When i was measuring how much time/cycles the CPU spends waiting for a single byte I2C transfer (switched to using interrupts since) i got far over 10000 cyles on ARM11 (measured using the MPCore performance monitor)...
I had no problems at all with the power LED but i only use it as sleep indicator anyway.
Do you know what frequency that MPCore timer counts at? Bootrom code looks like... 134MHz?
And is that 10000 cycles for one raw I2C byte? Or a whole "Device+Index+Databyte" sequence with 3 bytes in total?
The delay is needed only after the last Databyte of each transfer. If you were doing only one transfer per frame, then you have had more than enough delay time.
Btw. I have edited the I2C delay stuff in previous post. The bootrom seems to aim at 2*188 cycles delay after last byte... although my early tests included a much longer DSi-style delay before each byte - which should have worked, too (theoretically, but somehow it didn't work in practice).

You should really take a look inside the ARM11 MPCore TRM. It's half the frequency of the CPU core so 134 MHz.
Frequency formula: http://infocenter.arm.com/help/topic/co ... JJEHG.html
General registers: http://infocenter.arm.com/help/topic/co ... 02s02.html
The performance monitor actually counts all cycles minus a few missed ones at start/reset so it runs at core frequency.

If i recall correctly it was the entire transfer including device and register select. Still very slow for a single byte reg write. In the very early days we polled the MCU from ARM11 (which of course was not a good idea). It worked fine without any delays (with the ARM11 having all caches on so it's really fast). It caused RTC drifts though which we did not notice until later.

nocash wrote:
profi200 wrote:
Everything detects modified FIRM partitions by looking for the sighax signatures. That's it.
That's not so very suitable for detection. It would require to (RSA-)decrypt the signature and then examine if it contains normal padding bytes (or have a database with all currently known used sighax signatures (which could run into billions if somebody likes bruteforcing more and more variants).
And worst, the FIRM cannot by (AES-)decrypted without OTP dump, so impossible to examine the signatures at all (like, when you get a console, don't have a OTP dump, and want to patch it via hardmod - one could do that only with original FIRM, or with a backup-copy of the original FIRM stored in some unused eMMC sectors). But well, not so much of a problem if there's no standard for backups yet.

There are only 2 known FIRM partition sighax signatures in the wild. Ours and the one boot9strap uses. It's enough to check hashes. Of course someone could bruteforce more but everyone is using these 2 only. Bruteforcing more is kinda pointless.
There are 2 different types of backups being made currently. Either full 1:1 eMMC copies or the most important files like OTP, sector one, movable.sed...
The tool almost everyone uses for this is: https://github.com/d0k3/GodMode9

nocash wrote:
Yeah, the MMU is keeping me away from adding 3DS support in no$gba, too. At the moment, I don't even know what page-size it is using. I have no clear picture of what needs to be done for emulating it.

It's actually not so hard. It's a massive step up from MPUs but it really is just a lookup table with attributes/permissions. 2 levels for <section (1 MiB). Then there are supersections which are basically just 16 sections (16 MiB).
Example code (not the nicest but works): https://github.com/derrekr/fastboot3DS/ ... ware/mmu.c
Documentation: http://infocenter.arm.com/help/topic/co ... BHIGI.html

Should be noted that the tables require quite some alignment for the MMU to perform well (all explained in the TRM and the ARM ARM (architecture reference manual).


Btw: A reminder on the #3dsdev IRC channel.


Top
 Profile  
 
PostPosted: Sat May 18, 2019 10:07 pm 
Offline

Joined: Fri Feb 24, 2012 12:09 pm
Posts: 899
I am having troubles to extract the Wifi Firmware from the "NWM" module. Here, http://4dsdev.kuribo64.net/thread.php?pid=470#470 plutoo mentioned "Having a quick glance at NWM, it looks like it contains 3 different versions of wlan firmware, labeled 1, 4 and 5."

I have extracted the safe mode NWM .code file (and decompressed it). And had several quick glances (and longer glances) at the file, but I can't see anything "labeled 1, 4 and 5". Is there some table of contents with those 1,4,5 numbers/labels?

What I can find is this:
Code:
  Offset    Content
  3C879h    main code (with "A_INIT" string)
  3D96Ah    main code (with "A_INIT" string)
  451ADh    main code (with "A_INIT" string)
  4F380h    stub code (len 316h) (bytes 36 61 00 21 04 63 .. 1D F0)
  4F698h    stub data (len 38h?)
So there seem to be 3 different main versions (maybe for DSi, 3DS, and 3DS-local-multiplayer?), and, apparently only 1 version for the eeprom-loading stub. Additionally to main/stub, there might be also 1-3 database versions somewhere in the file.
Without table of contents it's hard to guess the exact start address, size, and target address of the above sections. The stub size seems to be 316h bytes... but I can't even find that size value in the .code file. Am I missing something obvious?

_________________
homepage - patreon


Top
 Profile  
 
PostPosted: Sun May 19, 2019 6:12 am 
Offline

Joined: Fri Feb 24, 2012 12:09 pm
Posts: 899
Okay, I've found the DSi-style "00524C00h" load address, and alongsides also found all the other stuff at nearby addresses, including CMP opcodes for the "label 1,4,5" part. Instead of a table of contents, the addresses are just hardcoded constants in the literal pool. Base address seems to be 100000h, ie. ARM address 13D84Ch means file offset 3D84Ch.
Code:
  Offset
  07248h    value 00524C00h   ;dst for stub.data and/or main.code?          ;\
  0724Ch          00145142h ;src.end  ;\len 78F6h  (2nd main) (aka label 5) ;
  07250h          0013D84Ch ;src      ;/                                    ;/
  ...
  097C4h    cmp r0,1h         ;\
  097C8h    cmp r0,4h         ; "labels" for different main's
  097CCh    cmp r0,5h         ;/
  ...
  098E8h    value 00524C00h ;dst for stub.data and/or main.code             ;\
  098ECh          00145142h ;src.end  ;\len 78F6h  (2nd main) (aka label 5) ;
  098F0h          0013D84Ch ;src      ;/                                    ;/
  098F4h    value 0053FE18h ;dst for database?                          ;\
  098F8h          0014F380h       ;\len 1E8h (probably database?)       ;
  098FCh          0014F198h       ;/                                    ;/
  09900h    value 00527000h ;dst for stub.code (aka 927000h)            ;\
  09904h          0014F696h ;src.end ;\len 316h (stub.code)             ;
  09908h          0014F380h ;src     ;/         <-- file.offs = 4F380h  ;/
  0990Ch          0014F6D0h ;src.end ;\len 38h (stub.data)
  09910h          0014F698h ;src     ;/
  0991xh          ..
  09920h          0013D84Bh       ;\len FD3h (1st main) (aka label 1)
  09924h          0013C878h       ;/
  09928h          0014F197h       ;\len A053h (3rd main) (aka label 4)
  0992Ch          00145144h       ;/
Well, with that... I guess I could now try to upload the wifi firmware to the Xtensa CPU, and see what happens.

_________________
homepage - patreon


Top
 Profile  
 
PostPosted: Sun May 19, 2019 7:15 am 
Offline

Joined: Sun May 19, 2019 7:01 am
Posts: 2
bürp

so I see you're attempting to emulate the 3DS, good luck with this project

I have a few things to say, tho

nocash wrote:
Yeah, the MMU is keeping me away from adding 3DS support in no$gba, too. At the moment, I don't even know what page-size it is using. I have no clear picture of what needs to be done for emulating it.

Another small obstacle is that no$gba is currently designed to map most I/O ports to only ARM7, or only ARM9. Whilst 3DS seems to allow to access (many) I/O ports from either ARM9 or ARM11 (or both). Well, that isn't a major problem, but I may need to rewrite a bunch of code, instead of just re-using the old DSi emulation for 3DS.

The good thing about 3DS is that the bootroms are dumped meanwhile, so one can start emulation & research at power-up time. For the DSi, the bootroms are still undumped. And, when I had starting to emulate DSi, it wasn't even known how to decrypt the eMMC bootsectors, so emulation had to start excecution after the yet unknown boot process (that wasn't so funny to work that way).

if I were you, I would make a separate no$3ds/whatever emulator for this. the 3DS may share a lot of hardware with the DSi for backwards compatibility purposes, but for the purpose of running 3DS software, most of the underlying hardware is completely different.

I'd just worry that cramming all these consoles into one project would result in a bloated codebase, but eh, your choice.

other than that, well, have fun! emulating the 3DS at low level sounds like an interesting challenge.

--

also, if you're ever interested into updating the DS documentation: I have a whole pile of errata/additions sitting at the melonDS forum (I would link to the thread, but I'm afraid I might get hit by some spam protection, seeing as I'm a newb here)

there's also quite a bunch of low-level research on the 3D GPU thing it uses, but enough offtopicness


Top
 Profile  
 
PostPosted: Sun May 19, 2019 7:41 am 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 21391
Location: NE Indiana, USA (NTSC)
Go ahead and post the link. We don't have a "no external links for new users" policy.

_________________
Pin Eight | Twitter | GitHub | Patreon


Top
 Profile  
 
PostPosted: Sun May 19, 2019 8:35 am 
Offline

Joined: Sun May 19, 2019 7:01 am
Posts: 2
'aight

general GBAtek addendum/errata
the development forum for more
3D GPU info here and here


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 38 posts ]  Go to page Previous  1, 2, 3

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 0 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group