forums.ps2dev.org Forum Index forums.ps2dev.org
Homebrew PS2, PSP & PS3 Development Discussions
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

sceKernelCanReleaseLibrary code

 
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development
View previous topic :: View next topic  
Author Message
johnmph



Joined: 23 Jul 2005
Posts: 119

PostPosted: Fri Mar 24, 2006 7:22 am    Post subject: sceKernelCanReleaseLibrary code Reply with quote

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
View user's profile Send private message
hubevolution



Joined: 17 Mar 2004
Posts: 32

PostPosted: Fri Mar 24, 2006 5:08 pm    Post subject: Reply with quote

this will allow module unloading without patching it even if the module has the no_stop flag set on ?
Back to top
View user's profile Send private message
johnmph



Joined: 23 Jul 2005
Posts: 119

PostPosted: Fri Mar 24, 2006 8:27 pm    Post subject: Reply with quote

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
View user's profile Send private message
hubevolution



Joined: 17 Mar 2004
Posts: 32

PostPosted: Fri Mar 24, 2006 9:01 pm    Post subject: Reply with quote

well great work at least a clean method to unload modules !
Back to top
View user's profile Send private message
hubevolution



Joined: 17 Mar 2004
Posts: 32

PostPosted: Mon Mar 27, 2006 3:54 pm    Post subject: Reply with quote

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
View user's profile Send private message
Fanjita



Joined: 28 Sep 2005
Posts: 217

PostPosted: Mon Mar 27, 2006 7:55 pm    Post subject: Reply with quote

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
View user's profile Send private message
hubevolution



Joined: 17 Mar 2004
Posts: 32

PostPosted: Mon Mar 27, 2006 8:04 pm    Post subject: Reply with quote

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
View user's profile Send private message
Mirko-psp



Joined: 14 Mar 2006
Posts: 6

PostPosted: Tue Mar 28, 2006 5:18 am    Post subject: Reply with quote

hey hube ;)

MPH you have load the sysmem.prx on mph gameloader???
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development All times are GMT + 10 Hours
Page 1 of 1

 
Jump to:  
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 vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group