dldi – chishm & stub

Well, i was trying to allow SEDS to be distributed as a single .nds file, while it actually requires plenty of stubs to be installed on the flash card in order to re-load fresh updates of itself (or to return to the “runme” root program). Making sure that stubs (and runme) are downloaded on demand was quite easy, but then i stumbled upon an unexpected difficulty: DLDI patching.

As most modern linkers perform that “driver patching” automatically when loading our homebrew, we tend to forget that they even exists (especially me, since i’m owning a pre-DLDI linker that works with built-in drivers of the libfat :P). Arialia first notified me of that i was missing something in the process… Then began the hide-and-seek game with (undocumented?) process of loading and patching code with DLDI drivers.

Lick said on gbadev.org:>
Chishm has already proven that it works. His VRAM boot stub gets patched before it’s executed. There’s hackery involved so check its source.
me:>
thanks. I’ll google that.

A bit of googling could not locate chishm’s source for the NDS loader, but crawling the forum did. One of the nice things chishm does in his loader is to reuse the DLDI driver of the current binary to patch the loader (and the program to be loaded). Let’s see how it works.

pDH = (data_t*)(((u32*)(&_io_dldi)) -24);
pAH = &(binData[patchOffset]);

The first entry in the IOinterfaces table is reserved for DLDI devices. Note that the DLDI patcher will *keep* this “placeholder” interface so that, once patched, the driver’s description is still at _io_dldi ^_^. Moreover, right before the actual ioInterface structure, we can find a placeholder for the DLDI header, including code/data sizes, and location of the Global Offset Table required for patching.

if (*((u32*)(pDH + DO_ioType)) == DEVICE_TYPE_DLDI) {
// No DLDI patch
return false;
}

One of the tricks involved is that, if no DLDI driver is installed, the ioInterface’s “type” is set at compile-time to the “DLDI” string. Once patched, it gets replaced with the vendor/product mini-id (e.g. SCSD for Supercard, securedigital or MPCF for “media player, compactflash”, etc).

The rest is just going smoothly. I initially feared that the restriction of 16-bits access to the VRAM would doom the entire loading process, but obviously, it does not apply when VRAM is mapped as “LCD” (plain CPU access, offscreen). That’s nice.

3 thoughts on “dldi – chishm & stub

  1. ARM9: FIFO InitARM7: BootingARM7: ReadyARM9: FAT InitGuru Meditation Error!data abort!pc: 0ffffffc addr: 0ffffffcr0: 04000200r1 06865960r2 0000e000r3 0000e880r4 023f001cr5 06820000r6 00000000r7 00000000r8: 00000000r9 00000000r10 00000000r11 00000000r12 0b0bb910sp 0b003cc8lr 06861174pc 10000004stack : 0 06865298 0 06820000 0 0 0 0 0 6860e64 0B000000 0 0 0680164 0*

    Like

  2. >_< i just managed to get the patched exec_stub.arm9 dumped to a file... all the edited areas are garbage :Pe.g. i have text_start = 0x0b0bb2c0 while i’d have expected 0x6865900 (from manually patched stub)…

    Like

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.