| View previous topic :: View next topic |
| Author |
Message |
johnmph
Joined: 23 Jul 2005 Posts: 119
|
Posted: Fri Mar 24, 2006 7:22 am Post subject: sceKernelCanReleaseLibrary code |
|
|
I tried some reverse engineering with sceKernelCanReleaseLibrary function.
Here what i found :
Structures (temporary name) :
| Code: |
typedef struct ModuleLibRelease // Module Library Release
{
u32 unk1; // ?
struct ModuleLibRelease *next; // Next structure
u32 unk2; // ?
u16 unk3; // ?
u16 unk4; // sceKernelCanReleaseLibrary verification (unk4 & 0x8)
} ModuleLibRelease;
typedef struct ModuleLib // Module Library
{
struct ModuleLib *next; // Next structure
u32 unk1[4];
SceLibraryEntryTable *lib; // Library pointer
ModuleLibRelease *release; // ModuleLibRelease pointer
} ModuleLib;
|
Functions :
mfic, mtic opcode informations based on http://forums.ps2dev.org/viewtopic.php?t=4598 post
| Code: |
u32 sceKernelSuspendInterrupts (void)
{
u32 i;
asm(
"mfic %0, $0\n"
"mtic $0, $0\n"
"nop\n" // For uncached (7 nop)
"nop\n"
"nop\n"
"nop\n"
"nop\n"
"nop\n"
"nop\n"
: "=r"(i)
);
return i;
}
void sceKernelResumeInterrupts (u32 i)
{
u32 temp;
asm(
"mtic %1, $0\n"
"nop\n" // For uncached (7 nop)
"nop\n"
"nop\n"
"nop\n"
"nop\n"
"nop\n"
"nop\n"
: "=r"(temp)
: "r"(i)
);
}
u32 sceKernelCanReleaseLibrary (SceLibraryEntryTable *lib)
// Reverse engineering of sceKernelCanReleaseLibrary function
// Return 0x0 if library lib can be release else error code
{
ModuleLib *modLib;
ModuleLibRelease *release;
u32 i;
// Suspend interrupts
i = sceKernelSuspendInterrupts();
modLib = (ModuleLib *) 0x8801AF40; // Address of first structure in 1.50 version
// Browse array
while (modLib)
{
if (modLib->lib == lib) break; // If library found, break
modLib = modLib->next; // Next structure
}
// If not found, exit
if (!(modLib))
{
// Resume interrupts
sceKernelResumeInterrupts(i);
// OK
return 0;
}
// Get the "release array"
release = modLib->release;
// Browse the array
while (release)
{
if (!(release->unk4 & 0x8)) // Error, exit with error message and kprintf
{
kprintf("sceKernelCanReleaseLibrary : %s ...",lib->libname);
// Resume interrupts
sceKernelResumeInterrupts(i);
return 0x8002013E;
}
release = release->next; // Next structure
}
// Resume interrupts
sceKernelResumeInterrupts(i);
// OK
return 0;
}
|
If you want unload a module which normally can not be unloaded, set modLib->release to NULL (for each library in module).
After you will be able to release the module (stop and unload). |
|
| Back to top |
|
 |
hubevolution
Joined: 17 Mar 2004 Posts: 32
|
Posted: Fri Mar 24, 2006 5:08 pm Post subject: |
|
|
| this will allow module unloading without patching it even if the module has the no_stop flag set on ? |
|
| Back to top |
|
 |
johnmph
Joined: 23 Jul 2005 Posts: 119
|
Posted: Fri Mar 24, 2006 8:27 pm Post subject: |
|
|
| hubevolution wrote: | | this will allow module unloading without patching it even if the module has the no_stop flag set on ? |
Yes you can but you must also patch the flag, this is a small function to unload a module :
| Code: |
u32 modulePatchLibraryForRelease (SceLibraryEntryTable *lib)
{
ModuleLib *modLib;
u32 i;
// Suspend interrups
i = sceKernelSuspendInterrupts();
modLib = (ModuleLib *) 0x8801AF40; // Address of first structure in 1.50 version
// Browse array
while (modLib)
{
if (modLib->lib == lib) break; // If library found, break
modLib = modLib->next; // Next structure
}
// If found, patch release pointer
if (modLib) modLib->release = NULL;
// Resume interrupts
sceKernelResumeInterrupts(i);
// OK
return 0;
}
u32 modulePatchForRelease (const char *name)
{
SceModule *mod;
SceLibraryEntryTable *entryTable, *entryEnd;
// Find module address
mod = sceKernelFindModuleByName(name);
// If bad module
if ((((long) mod) & 0xFF000000) != 0x88000000) return 1;
if ((mod->stub_top - mod->ent_top) < 40) return 1;
// Patch attributes
mod->attribute = 0x1006;
// Find entry table info
entryTable = (SceLibraryEntryTable *) ((u32 *) mod->ent_top);
entryEnd = (SceLibraryEntryTable *) (((u8 *) mod->ent_top) + mod->ent_size);
// Entry loop
while (entryTable < entryEnd)
{
if (entryTable->libname)
{
// Patch library for release
modulePatchLibraryForRelease(entryTable);
}
// Next entry
entryTable = (SceLibraryEntryTable *) (((u32 *) entryTable) + entryTable->len);
}
return 0;
}
u32 moduleUnload (const char *name)
{
SceModule *mod;
SceUID modid;
u32 ret;
// Patch module
modulePatchForRelease(name);
// Find module address
mod = sceKernelFindModuleByName(name);
// If not found, exit
if (!(mod)) return SCE_KERNEL_ERROR_UNKNOWN_MODULE;
// Stop module
modid = mod->modid;
ret = sceKernelStopModule(modid,0,NULL,NULL,NULL);
if (!(ret & 0x80000000)) ret = sceKernelUnloadModule(modid);
return ret;
}
|
I tried with sceVaudio_driver module and it works. |
|
| Back to top |
|
 |
hubevolution
Joined: 17 Mar 2004 Posts: 32
|
Posted: Fri Mar 24, 2006 9:01 pm Post subject: |
|
|
| well great work at least a clean method to unload modules ! |
|
| Back to top |
|
 |
hubevolution
Joined: 17 Mar 2004 Posts: 32
|
Posted: Mon Mar 27, 2006 3:54 pm Post subject: |
|
|
| I tried to unload sysmem.prx (sceSystemMemoryManager) but when I realod it from a simulated flash0: (mounted on the memstick) psp crashes ... I can unload and reload many other modules but sysmem.prx seems that cannot be unloaded ... even tried to do the unload/reload between disabling/reenabling interrupts but no way ... any clue ? |
|
| Back to top |
|
 |
Fanjita
Joined: 28 Sep 2005 Posts: 217
|
Posted: Mon Mar 27, 2006 7:55 pm Post subject: |
|
|
| hubevolution wrote: | | I tried to unload sysmem.prx (sceSystemMemoryManager) but when I realod it from a simulated flash0: (mounted on the memstick) psp crashes ... I can unload and reload many other modules but sysmem.prx seems that cannot be unloaded ... even tried to do the unload/reload between disabling/reenabling interrupts but no way ... any clue ? |
PResumably that module holds some state info about the memory allocation in the system, and you'd need to find some way to save / reinject that state into the new module? _________________ Got a v2.0-v2.80 firmware PSP? Download the eLoader here to run homebrew on it!
The PSP Homebrew Database needs you! |
|
| Back to top |
|
 |
hubevolution
Joined: 17 Mar 2004 Posts: 32
|
Posted: Mon Mar 27, 2006 8:04 pm Post subject: |
|
|
| that means that unloading the module will cause the previous memory allocation "tables/infos" to be lost ... and when reloading the module it will start from scratch without knowing that there was previously allocated memory corrupting it and failing access to that when requested ... that sounds realistic ! |
|
| Back to top |
|
 |
Mirko-psp
Joined: 14 Mar 2006 Posts: 6
|
Posted: Tue Mar 28, 2006 5:18 am Post subject: |
|
|
hey hube ;)
MPH you have load the sysmem.prx on mph gameloader??? |
|
| Back to top |
|
 |
|