TyRaNiD and I have worked out a way to load modules from user mode and have them resolve to syscalls - the caveat is that your initial program thread still must start in kernel mode.
The PSP's module loader looks at the calling thread's attributes to figure out what type of API the thread came from. If the thread attribute is 0x80000000 it knows it came from a user mode thread, if it's 0xc0000000 it knows it came from a VSH thread, and if it's 0xa0000000 it knows it came from a USB/WLAN API thread.
There's a ModuleMgr user library call named sceKernelLoadModuleBufferUsbWlan(), that will load a module from a buffer:
Code: Select all
SceUID sceKernelLoadModuleBufferUsbWlan(SceSize len, void *buf, int flags, SceKernelLMOption *option);
...
SceKernelLMOption option;
memset(&option, 0, sizeof(option));
option.size = sizeof(option);
option.mpidtext = mpid;
option.mpiddata = mpid;
option.position = 0;
option.access = 1;
return sceKernelLoadModuleBufferUsbWlan(size, modbuf, flags, &option); // option can be NULL
When we tested this (I tested with usbstor.prx) our user mode library stubs resolved to syscalls :). Unfortunately, in TyRaNiD's tests pspnet.prx crapped out SCE_KERNEL_ERROR_UNSUPPORTED_PRX_TYPE, but more testing is probably needed.
We're still working on a way to do all of this without ever needing kernel mode, but it's possible that you can only force that thread attribute if you're already in kernel mode (not confirmed yet). However it's a good start and we're looking at doing our own "bridge" module that can provide some kernel services from user mode.