-fixed BASIC(!) channel launching, currently only booting

channels from real nand works here, also return to wiiflow
seems to be broken, but its a start
This commit is contained in:
fix94.1 2012-05-20 12:34:48 +00:00
parent bdfe989462
commit 0c32d1b0c1
6 changed files with 92 additions and 64 deletions

View File

@ -20,6 +20,7 @@ void __Disc_SetLowMem(void);
void __Disc_SetVMode(void); void __Disc_SetVMode(void);
void __Disc_SetTime(void); void __Disc_SetTime(void);
void _unstub_start(); void _unstub_start();
u32 entryPoint;
extern void __exception_closeall(); extern void __exception_closeall();
@ -35,15 +36,10 @@ typedef struct _dolheader{
u32 padding[7]; u32 padding[7];
} __attribute__((packed)) dolheader; } __attribute__((packed)) dolheader;
u32 entryPoint; s32 BootChannel(u32 entry, u64 chantitle, u32 ios, u8 vidMode, bool vipatch, bool countryString, u8 patchVidMode, int aspectRatio)
s32 BootChannel(u8 *data, u64 chantitle, u8 vidMode, bool vipatch, bool countryString, u8 patchVidMode, bool disableIOSreload, int aspectRatio)
{ {
u32 ios; gprintf("Loading Channel...\n");
Identify(chantitle, &ios); entryPoint = entry;
entryPoint = LoadChannel(data);
MEM2_free(data);
/* Select an appropriate video mode */ /* Select an appropriate video mode */
GXRModeObj * vmode = __Disc_SelectVMode(vidMode, chantitle); GXRModeObj * vmode = __Disc_SelectVMode(vidMode, chantitle);
@ -61,11 +57,6 @@ s32 BootChannel(u8 *data, u64 chantitle, u8 vidMode, bool vipatch, bool countryS
entrypoint appJump = (entrypoint)entryPoint; entrypoint appJump = (entrypoint)entryPoint;
if (disableIOSreload)
IOSReloadBlock(IOS_GetVersion(), false);
else
IOSReloadBlock(IOS_GetVersion(), true);
/* Set an appropriate video mode */ /* Set an appropriate video mode */
__Disc_SetVMode(); __Disc_SetVMode();
@ -79,15 +70,20 @@ s32 BootChannel(u8 *data, u64 chantitle, u8 vidMode, bool vipatch, bool countryS
memset((void *)0x80000000, 0, 6); memset((void *)0x80000000, 0, 6);
*(vu32 *)0x80000000 = TITLE_LOWER(chantitle); *(vu32 *)0x80000000 = TITLE_LOWER(chantitle);
DCFlushRange((void *)0x80000000, 6); DCFlushRange((void *)0x80000000, 6);
/* Shutdown IOS subsystems */
SYS_ResetSystem(SYS_SHUTDOWN, 0, 0);
gprintf("Jumping to entrypoint %08x\n", entryPoint); gprintf("Jumping to entrypoint %08x\n", entryPoint);
/* Shutdown IOS subsystems */
u32 level = IRQ_Disable();
__IOS_ShutdownSubsystems();
__exception_closeall();
/* Originally from tueidj - taken from NeoGamma (thx) */
*(vu32*)0xCC003024 = 1;
if (entryPoint != 0x3400) if (entryPoint != 0x3400)
{ {
if (hooktype != 0) if(hooktype != 0)
{ {
__asm__( __asm__(
"lis %r3, entryPoint@h\n" "lis %r3, entryPoint@h\n"
@ -101,9 +97,10 @@ s32 BootChannel(u8 *data, u64 chantitle, u8 vidMode, bool vipatch, bool countryS
"bctr\n" "bctr\n"
); );
} }
else appJump(); else
appJump();
} }
else if (hooktype != 0) else if(hooktype != 0)
{ {
__asm__( __asm__(
"lis %r3, returnpoint@h\n" "lis %r3, returnpoint@h\n"
@ -126,7 +123,10 @@ s32 BootChannel(u8 *data, u64 chantitle, u8 vidMode, bool vipatch, bool countryS
"rfi\n" "rfi\n"
); );
} }
else _unstub_start(); else
_unstub_start();
IRQ_Restore(level);
return 0; return 0;
} }
@ -140,30 +140,30 @@ u32 LoadChannel(u8 *buffer)
dolchunkcount = 0; dolchunkcount = 0;
dolheader *dolfile = (dolheader *)buffer; dolheader *dolfile = (dolheader *)buffer;
if(dolfile->bss_start) if(dolfile->bss_start)
{ {
if(!(dolfile->bss_start & 0x80000000)) if(!(dolfile->bss_start & 0x80000000))
dolfile->bss_start |= 0x80000000; dolfile->bss_start |= 0x80000000;
ICInvalidateRange((void *)dolfile->bss_start, dolfile->bss_size); memset((void *)dolfile->bss_start, 0, dolfile->bss_size);
memset((void *)dolfile->bss_start, 0, dolfile->bss_size); DCFlushRange((void *)dolfile->bss_start, dolfile->bss_size);
DCFlushRange((void *)dolfile->bss_start, dolfile->bss_size); ICInvalidateRange((void *)dolfile->bss_start, dolfile->bss_size);
} }
int i; int i;
for(i = 0; i < 18; i++) for(i = 0; i < 18; i++)
{ {
if (!dolfile->section_size[i]) continue; if(!dolfile->section_size[i]) continue;
if (dolfile->section_pos[i] < sizeof(dolheader)) continue; if(dolfile->section_pos[i] < sizeof(dolheader)) continue;
if(!(dolfile->section_start[i] & 0x80000000)) dolfile->section_start[i] |= 0x80000000; if(!(dolfile->section_start[i] & 0x80000000)) dolfile->section_start[i] |= 0x80000000;
dolchunkoffset[dolchunkcount] = (void *)dolfile->section_start[i]; dolchunkoffset[dolchunkcount] = (void *)dolfile->section_start[i];
dolchunksize[dolchunkcount] = dolfile->section_size[i]; dolchunksize[dolchunkcount] = dolfile->section_size[i];
gprintf("Moving section %u from offset %08x to %08x-%08x...\n", i, dolfile->section_pos[i], dolchunkoffset[dolchunkcount], dolchunkoffset[dolchunkcount]+dolchunksize[dolchunkcount]); gprintf("Moving section %u from offset %08x to %08x-%08x...\n", i, dolfile->section_pos[i], dolchunkoffset[dolchunkcount], dolchunkoffset[dolchunkcount]+dolchunksize[dolchunkcount]);
ICInvalidateRange(dolchunkoffset[dolchunkcount], dolchunksize[dolchunkcount]); memmove(dolchunkoffset[dolchunkcount], buffer + dolfile->section_pos[i], dolchunksize[dolchunkcount]);
memmove (dolchunkoffset[dolchunkcount], buffer + dolfile->section_pos[i], dolchunksize[dolchunkcount]);
DCFlushRange(dolchunkoffset[dolchunkcount], dolchunksize[dolchunkcount]); DCFlushRange(dolchunkoffset[dolchunkcount], dolchunksize[dolchunkcount]);
ICInvalidateRange(dolchunkoffset[dolchunkcount], dolchunksize[dolchunkcount]);
dolchunkcount++; dolchunkcount++;
} }
@ -216,38 +216,45 @@ bool Identify_GenerateTik(signed_blob **outbuf, u32 *outlen)
bool Identify(u64 titleid, u32 *ios) bool Identify(u64 titleid, u32 *ios)
{ {
char filepath[ISFS_MAXPATH] ATTRIBUTE_ALIGN(32); char filepath[ISFS_MAXPATH] ATTRIBUTE_ALIGN(32);
gprintf("Reading TMD...");
sprintf(filepath, "/title/%08x/%08x/content/title.tmd", TITLE_UPPER(titleid), TITLE_LOWER(titleid)); sprintf(filepath, "/title/%08x/%08x/content/title.tmd", TITLE_UPPER(titleid), TITLE_LOWER(titleid));
u32 tmdSize; u32 tmdSize;
u8 *tmdBuffer = ISFS_GetFile((u8 *) &filepath, &tmdSize, -1); u8 *tmdBuffer = ISFS_GetFile((u8 *) &filepath, &tmdSize, -1);
if (tmdBuffer == NULL || tmdSize == 0) if (tmdBuffer == NULL || tmdSize == 0)
{ {
gprintf("Reading TMD...Failed!\n"); gprintf("Failed!\n");
return false; return false;
} }
gprintf("Success!\n");
*ios = (u32)(tmdBuffer[0x18b]); *ios = (u32)(tmdBuffer[0x18b]);
u32 tikSize; u32 tikSize;
signed_blob *tikBuffer = NULL; signed_blob *tikBuffer = NULL;
gprintf("Generating fake ticket...");
if(!Identify_GenerateTik(&tikBuffer,&tikSize)) if(!Identify_GenerateTik(&tikBuffer,&tikSize))
{ {
gprintf("Generating fake ticket...Failed!\n"); gprintf("Failed!\n");
return false; return false;
} }
gprintf("Success!\n");
gprintf("Reading certs...");
sprintf(filepath, "/sys/cert.sys"); sprintf(filepath, "/sys/cert.sys");
u32 certSize; u32 certSize;
u8 *certBuffer = ISFS_GetFile((u8 *) &filepath, &certSize, -1); u8 *certBuffer = ISFS_GetFile((u8 *) &filepath, &certSize, -1);
if (certBuffer == NULL || certSize == 0) if (certBuffer == NULL || certSize == 0)
{ {
gprintf("Reading certs...Failed!\n"); gprintf("Failed!\n");
MEM2_free(tmdBuffer); MEM2_free(tmdBuffer);
MEM2_free(tikBuffer); MEM2_free(tikBuffer);
return false; return false;
} }
gprintf("Success!\n");
gprintf("ES_Identify\n");
s32 ret = ES_Identify((signed_blob*)certBuffer, certSize, (signed_blob*)tmdBuffer, tmdSize, tikBuffer, tikSize, NULL); s32 ret = ES_Identify((signed_blob*)certBuffer, certSize, (signed_blob*)tmdBuffer, tmdSize, tikBuffer, tikSize, NULL);
if (ret < 0) if (ret < 0)
{ {

View File

@ -8,7 +8,7 @@ extern "C" {
#include <gctypes.h> #include <gctypes.h>
#include <gccore.h> #include <gccore.h>
s32 BootChannel(u8 *data, u64 chantitle, u8 vidMode, bool vipatch, bool countryString, u8 patchVidMode, bool disableIOSreload, int aspectRatio); s32 BootChannel(u32 entry, u64 chantitle, u32 ios, u8 vidMode, bool vipatch, bool countryString, u8 patchVidMode, int aspectRatio);
u32 LoadChannel(u8 *buffer); u32 LoadChannel(u8 *buffer);
void PatchChannel(u8 vidMode, GXRModeObj *vmode, bool vipatch, bool countryString, u8 patchVidModes, int aspectRatio); void PatchChannel(u8 vidMode, GXRModeObj *vmode, bool vipatch, bool countryString, u8 patchVidModes, int aspectRatio);

View File

@ -73,15 +73,22 @@ Channels::~Channels()
{ {
} }
u8 * Channels::Load(u64 title) u32 Channels::Load(u64 title, u32 *ios)
{ {
char app[ISFS_MAXPATH] ATTRIBUTE_ALIGN(32); char app[ISFS_MAXPATH] ATTRIBUTE_ALIGN(32);
u32 bootcontent; u32 bootcontent;
u32 entry = 0;
if(!GetAppNameFromTmd(title, app, true, &bootcontent)) if(!GetAppNameFromTmd(title, app, true, &bootcontent))
return NULL; return entry;
return GetDol(title, bootcontent); u8* data = GetDol(title, bootcontent);
Identify(title, ios);
entry = LoadChannel(data);
free(data);
return entry;
} }
u8 Channels::GetRequestedIOS(u64 title) u8 Channels::GetRequestedIOS(u64 title)
@ -104,11 +111,6 @@ u8 Channels::GetRequestedIOS(u64 title)
return IOS; return IOS;
} }
bool Channels::Launch(u8 *data, u64 chantitle, u8 vidMode, bool vipatch, bool countryString, u8 patchVidMode, bool disableIOSreload, int aspectRatio)
{
return BootChannel(data, chantitle, vidMode, vipatch, countryString, patchVidMode, disableIOSreload, aspectRatio);
}
u64* Channels::GetChannelList(u32* count) u64* Channels::GetChannelList(u32* count)
{ {
u32 countall; u32 countall;

View File

@ -54,10 +54,9 @@ class Channels
void Init(u32 channelType, string lang, bool reload = false); void Init(u32 channelType, string lang, bool reload = false);
u8 * Load(u64 title); u32 Load(u64 title, u32 *ios);
u8 GetRequestedIOS(u64 title); u8 GetRequestedIOS(u64 title);
bool Launch(u8 *data, u64 chantitle, u8 vidMode, bool vipatch, bool countryString, u8 patchVidMode, bool disableIOSreload, int aspectRatio);
int Count(); int Count();
wchar_t *GetName(int index); wchar_t *GetName(int index);
char *GetId(int index); char *GetId(int index);

View File

@ -81,8 +81,14 @@ void Nand::Init(string path, u32 partition, bool disable)
s32 Nand::Nand_Mount(NandDevice *Device) s32 Nand::Nand_Mount(NandDevice *Device)
{ {
gprintf("Device: %s\n", Device->Name);
s32 fd = IOS_Open("fat", 0); s32 fd = IOS_Open("fat", 0);
if (fd < 0) return fd; if(fd < 0)
{
gprintf("Mount Fail 1\n");
return fd;
}
static ioctlv vector[1] ATTRIBUTE_ALIGN(32); static ioctlv vector[1] ATTRIBUTE_ALIGN(32);
@ -145,17 +151,28 @@ s32 Nand::Nand_Disable(void)
s32 Nand::Enable_Emu() s32 Nand::Enable_Emu()
{ {
if(MountedDevice == EmuDevice || Disabled) if(MountedDevice == EmuDevice || Disabled)
{
gprintf("Fail 1\n");
return 0; return 0;
}
Disable_Emu(); Disable_Emu();
NandDevice *Device = &NandDeviceList[EmuDevice]; NandDevice *Device = &NandDeviceList[EmuDevice];
s32 ret = Nand_Mount(Device); s32 ret = Nand_Mount(Device);
if (ret < 0) return ret; if(ret < 0)
{
gprintf("Fail 2\n");
return ret;
}
ret = Nand_Enable(Device); ret = Nand_Enable(Device);
if (ret < 0) return ret; if(ret < 0)
{
gprintf("Fail 3\n");
return ret;
}
MountedDevice = EmuDevice; MountedDevice = EmuDevice;

View File

@ -872,8 +872,10 @@ static const char systems[11] = { 'C', 'E', 'F', 'J', 'L', 'M', 'N', 'P', 'Q', '
void CMenu::_launchChannel(dir_discHdr *hdr) void CMenu::_launchChannel(dir_discHdr *hdr)
{ {
Channels channel; Channels channel;
u8 *data = NULL; u32 ios = 0;
u32 entry = 0;
MEM1_wrap(0);
string id = string((const char *) hdr->hdr.id); string id = string((const char *) hdr->hdr.id);
bool forwarder = true; bool forwarder = true;
@ -887,14 +889,10 @@ void CMenu::_launchChannel(dir_discHdr *hdr)
} }
forwarder = m_gcfg2.getBool(id, "custom", forwarder) || strncmp(id.c_str(), "WIMC", 4) == 0; forwarder = m_gcfg2.getBool(id, "custom", forwarder) || strncmp(id.c_str(), "WIMC", 4) == 0;
if(!forwarder) if(!forwarder)
data = channel.Load(hdr->hdr.chantitle); entry = channel.Load(hdr->hdr.chantitle, &ios);
Nand::Instance()->Disable_Emu(); Nand::Instance()->Disable_Emu();
if(!forwarder && data == NULL) return;
bool vipatch = m_gcfg2.testOptBool(id, "vipatch", m_cfg.getBool("GENERAL", "vipatch", false)); bool vipatch = m_gcfg2.testOptBool(id, "vipatch", m_cfg.getBool("GENERAL", "vipatch", false));
bool cheat = m_gcfg2.testOptBool(id, "cheat", m_cfg.getBool("NAND", "cheat", false)); bool cheat = m_gcfg2.testOptBool(id, "cheat", m_cfg.getBool("NAND", "cheat", false));
bool countryPatch = m_gcfg2.testOptBool(id, "country_patch", m_cfg.getBool("GENERAL", "country_patch", false)); bool countryPatch = m_gcfg2.testOptBool(id, "country_patch", m_cfg.getBool("GENERAL", "country_patch", false));
@ -986,7 +984,12 @@ void CMenu::_launchChannel(dir_discHdr *hdr)
gprintf("Return to channel %s. Using new d2x way\n", IOS_Ioctlv(ESHandle, 0xA1, 1, 0, vector) != -101 ? "Succeeded" : "Failed!" ); gprintf("Return to channel %s. Using new d2x way\n", IOS_Ioctlv(ESHandle, 0xA1, 1, 0, vector) != -101 ? "Succeeded" : "Failed!" );
IOS_Close(ESHandle); IOS_Close(ESHandle);
} }
if (disableIOSreload)
IOSReloadBlock(IOS_GetVersion(), false);
else
IOSReloadBlock(IOS_GetVersion(), true);
CheckGameSoundThread(); CheckGameSoundThread();
cleanup(); cleanup();
Close_Inputs(); Close_Inputs();
@ -1000,7 +1003,7 @@ void CMenu::_launchChannel(dir_discHdr *hdr)
if (WII_LaunchTitle(hdr->hdr.chantitle) < 0) if (WII_LaunchTitle(hdr->hdr.chantitle) < 0)
Sys_LoadMenu(); Sys_LoadMenu();
} }
else if(!channel.Launch(data, hdr->hdr.chantitle, videoMode, vipatch, countryPatch, patchVidMode, disableIOSreload, aspectRatio)) else if(!BootChannel(entry, hdr->hdr.chantitle, ios, videoMode, vipatch, countryPatch, patchVidMode, aspectRatio))
Sys_LoadMenu(); Sys_LoadMenu();
} }