Homebrew Menu: Difference between revisions

From devkitPro
Jump to navigation Jump to search
(New page: ==Introduction== Unfortunately the vast majority of the cards we use to run homebrew applications are heavily biased towards commercial game piracy which means that we suffer from the fall...)
 
No edit summary
Line 43: Line 43:
==Exit to Menu Protocol==
==Exit to Menu Protocol==


From devkitARM r28 & libnds 1.4.1 nds applications can exit to the menu simply by returning from main or calling exit(0) but this also depends on support from the launcher. We reserve 48k at the top of main ram for code which the launcher can use to reload the menu - with hbmenu this is done by simply copying it's own dldi patched launcher to the appropriate area with a small stub to copy it to VRAM and reboot the arm7. There's a structure defined in libnds for use by launchers.
From devkitARM r28 & libnds 1.4.1 nds applications can exit to the menu simply by returning from main or calling exit(0) but this also depends on support from the launcher. We reserve 48k at the top of main ram, 4K of system memory, leaving 44K for code which the launcher can use to reload the menu - with hbmenu this is done by simply copying it's own dldi patched launcher to the appropriate area with a small stub to copy it to VRAM and reboot the arm7. There's a structure defined in libnds for use by launchers.


<pre>
<pre>

Revision as of 23:30, 7 March 2010

Introduction

Unfortunately the vast majority of the cards we use to run homebrew applications are heavily biased towards commercial game piracy which means that we suffer from the fallout when Nintendo block these cards and have them removed from sale due to the focus on copyright infringement. In recent months Nintendo's anti-piracy tactics have become more aggressive resulting in custodial sentences for several suppliers of DS flashcards.

The Homebrew Menu is a simple launcher intended to support DS homebrew developers and their users which has no means to run commercial games. This takes the focus away from copyright infringement and into the legal protection of reverse engineering for interoperability purposes provided by the DMCA and EUCD. Currently devkitPro is researching the feasibility of a branded flashcard without piracy features which should hopefully preserve our ability to create and share homebrew. This menu also supports two features thus far ignored by the pirate carts, argv support and a standard exit to menu method.

Some cards appear to have built their dldi code using arm946e-s specific code and unfortunately these cards will fail since hbmenu runs the nds launching code on the arm7. We do this to make sure that we can load and launch an nds file which uses all available memory on both processors - cards which don't will place unnecessary limits on the size of homebrew applications.

Binaries

The current binaries, which include bootstrap code that can be used to completely replace the menu on R4, ezflash V and AceKard 2(i), can be downloaded from the devkitPro file repository on Sourceforge. http://sourceforge.net/projects/devkitpro/files/hbmenu/

Source Code

For users interested in how this works and card manufacturers who wish to support homebrew,the source may be obtained from the devkitPro subversion repository.

svn co https://devkitpro.svn.sourceforge.net/svnroot/devkitpro/trunk/projects/nds/HomebrewMenu hbmenu

ARGV Protocol

All nds applications compiled with devkitARM r27+ will obtain an argv array from a supporting launcher which places the necessary values in an unused section of the DS header. A structure is provided for this in libnds, the launcher only needs to fill in argvMagic, command and length, all other values are generated internally during startup. The command line is a set of null terminated strings which is parsed and copied to the heap by the startup code.

// argv struct magic number
#define ARGV_MAGIC 0x5f617267

//!	argv structure
/*!	\struct __argv

	structure used to set up argc/argv on the DS

*/
struct __argv {
	int argvMagic;		//!< argv magic number, set to 0x5f617267 ('_arg') if valid 
	char *commandLine;	//!< base address of command line, set of null terminated strings
	int length;		//!< total length of command line
	int argc;		//!< internal use, number of arguments
	char **argv;		//!< internal use, argv pointer
};

//!	Default location for the libnds argv structure.
#define __system_argv		((struct __argv *)0x02FFFE70)


Exit to Menu Protocol

From devkitARM r28 & libnds 1.4.1 nds applications can exit to the menu simply by returning from main or calling exit(0) but this also depends on support from the launcher. We reserve 48k at the top of main ram, 4K of system memory, leaving 44K for code which the launcher can use to reload the menu - with hbmenu this is done by simply copying it's own dldi patched launcher to the appropriate area with a small stub to copy it to VRAM and reboot the arm7. There's a structure defined in libnds for use by launchers.


#define BOOTSIG	0x62757473746F6F62ULL

struct __bootstub {
	u64	bootsig;
	VoidFn arm9reboot;
	VoidFn arm7reboot;
	u32 bootsize;
};


Finding this structure in memory is done from the pointer to the end of RAM used to support newlib's malloc.

	extern char *fake_heap_end;
	struct __bootstub *bootcode = (struct __bootstub *)fake_heap_end;

	bootcode->bootsig = BOOTSIG;
	bootcode->arm9reboot = <function to reboot from arm9>
	bootcode->arm7reboot = <function to reboot from arm7>

The functions should be placed in the 44K reserved region pointed to by fake_heap_end. Note: This address will be different depending on the DS version - DS Phat/Lite, DS debug version and DSi so use the pointer.