 |
forums.ps2dev.org Homebrew PS2, PSP & PS3 Development Discussions
|
| View previous topic :: View next topic |
| Author |
Message |
Beuc
Joined: 26 Mar 2009 Posts: 33 Location: holland
|
Posted: Wed May 20, 2009 4:55 am Post subject: [solved] sceKernelLoadModule in kernel mode |
|
|
Hi,
I'm trying to load a module from within a kernel module.
When I use:
| Code: | | SceUID modid = sceKernelLoadModule("hello.prx", 0, &option); |
from the kernel module, it returns 0x80020149 (SCE_KERNEL_ERROR_ILLEGAL_PERM_CALL).
I tried using USE_KERNEL_LIBS=1 to allow the kernel to use user-mode (as per I read at http://forums.ps2dev.org/viewtopic.php?p=66785), but that doesn't seem to work. pspSdkSetK1(0) doesn't help either.
How should I use sceKernelLoadModule in kernel mode?
Last edited by Beuc on Thu May 21, 2009 7:15 pm; edited 1 time in total |
|
| Back to top |
|
 |
Torch

Joined: 28 May 2008 Posts: 842
|
Posted: Wed May 20, 2009 11:17 pm Post subject: |
|
|
First of all when making a kernel module always use USE_KERNEL_LIBS=1 and USE_KERNEL_LIBC=1 or you'll end up with bloated code like 100KiB for a kernel module which would normally be 2KiB. And you're ideally not supposed to use user functions from kernel mode either. Find a way without the user functions.
Regarding your problem:
The cwd may not be set. Give the full path for hello.prx
The &options struct may not be set properly. Anyway it's not necessary for simple loading so make it NULL..
It may not work from inside module_start and some non-thread contexts. Make sure you are calling it from a thread. |
|
| Back to top |
|
 |
Beuc
Joined: 26 Mar 2009 Posts: 33 Location: holland
|
Posted: Thu May 21, 2009 5:15 am Post subject: |
|
|
Thanks Torch.
Here's the code, I'm trying to follow your advice:
| Code: |
#include <pspsdk.h>
#include <pspkernel.h>
#include <string.h>
#include <stdio.h>
PSP_MODULE_INFO("nanofe", 0x1007, 1, 0);
PSP_MAIN_THREAD_ATTR(PSP_THREAD_ATTR_USER);
int plugin_thread (SceSize argc, void* argp)
{
char buf[100];
SceUID fd = sceIoOpen ("host0:/plugin_pspain.dat",
PSP_O_WRONLY | PSP_O_CREAT | PSP_O_TRUNC, 0777);
if (fd < 0)
return -1;
SceKernelLMOption option;
memset(&option, 0, sizeof(option));
option.size = sizeof(option);
option.mpidtext = 2;
option.mpiddata = 2;
option.position = 0;
option.access = 1;
char args[2048];
u32 k1 = pspSdkSetK1(0);
//SceUID (* sceKernelLoadModule_k)(const char *path, int flags, SceKernelLMOption *option);
//sceKernelLoadModule_k = (void *)FindProc("sceModuleManager", "ModuleMgrForKernel", 0x977de386);
sceKernelDelayThread(1000 * 1000);
while(!sceKernelFindModuleByName("sceKernelLibrary")) sceKernelDelayThread(100 * 1000);
SceUID modid = sceKernelLoadModule("ms0:/PSP/GAME/meminfo-prx-large/hello.prx", 0, NULL);
sceIoWrite (fd, "modid=", 7);
sprintf(buf, "%p\n", modid);
sceIoWrite (fd, buf, 100);
int mresult;
sceKernelStartModule(modid, 0, args, &mresult, NULL);
sceIoWrite (fd, "end\n", 4);
pspSdkSetK1(k1);
sceIoClose (fd);
// Completely free all memory
sceKernelSelfStopUnloadModule(1, 0, NULL);
return 0;
}
int
module_start (SceSize argc, void* argp)
{
u32 func = 0x80000000 | (u32)plugin_thread;
SceUID thread = sceKernelCreateThread("plugin_thread",
(void*)func, 0x30, 0x10000, 0, NULL);
if (thread >= 0) {
sceKernelStartThread (thread, argc, argp);
}
return 0;
}
|
and Makefile:
| Code: |
PSP_LARGE_MEMORY=1
TARGET = plugin
OBJS = module.o
CFLAGS = -O2 -G0 -Wall
CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti
ASFLAGS = $(CFLAGS)
LDFLAGS += -mno-crt0 -nostartfiles
BUILD_PRX=1
PSP_FW_VERSION=303
#USE_PSPSDK_LIBC=1
USE_KERNEL_LIBC=1
USE_KERNEL_LIBS=1
EXTRA_TARGETS = EBOOT.PBP
PSP_EBOOT_TITLE = plugin
PSPSDK=$(shell psp-config --pspsdk-path)
include $(PSPSDK)/lib/build.mak
|
| Torch wrote: | First of all when making a kernel module always use USE_KERNEL_LIBS=1 and USE_KERNEL_LIBC=1 or you'll end up with bloated code like 100KiB for a kernel module which would normally be 2KiB.
|
Hmm, I get a 72kB .prx.
| Torch wrote: | And you're ideally not supposed to use user functions from kernel mode either. Find a way without the user functions.
|
Well I don't have a clue about loading the module otherwise. Any lead?
| Torch wrote: |
Regarding your problem:
The cwd may not be set. Give the full path for hello.prx
|
It doesn't help, but in fact even specifying "blah" will return 0x80020149.
| Quote: | | The &options struct may not be set properly. Anyway it's not necessary for simple loading so make it NULL.. |
Neither :/
| Quote: | | It may not work from inside module_start and some non-thread contexts. Make sure you are calling it from a thread. |
It's in a thread already. |
|
| Back to top |
|
 |
Beuc
Joined: 26 Mar 2009 Posts: 33 Location: holland
|
Posted: Thu May 21, 2009 7:13 am Post subject: |
|
|
| Beuc wrote: |
| Code: |
USE_KERNEL_LIBC=1
USE_KERNEL_LIBS=1
|
|
Hmmm, it doesn't show on the forum but did you know that a trailing space in 'USE_KERNEL_LIBC=1 ' can seriously mess you build? Just learnt about it XD
Arrrrrrrrrrrrrrrrrrrrrrrrrrgh!!! |
|
| Back to top |
|
 |
Torch

Joined: 28 May 2008 Posts: 842
|
Posted: Thu May 21, 2009 6:22 pm Post subject: |
|
|
Lot of unnecessary crap in your code. And yes the trailing spaces in the makefile lines screw things up.
Not tested, but this should be enough.
| Code: | #include <pspsdk.h>
#include <pspkernel.h>
#include <string.h>
#include <stdio.h>
PSP_MODULE_INFO("nanofe", 0x1000, 1, 0); //0x1007 cannot be stopped and unloaded
PSP_MAIN_THREAD_ATTR(0); //0 for kernel thread
int plugin_thread (SceSize argc, void* argp)
{
sceIoChdir(argp); //Might need to append trailing / here.
char buf[100];
SceUID fd = sceIoOpen ("host0:/plugin_pspain.dat",
PSP_O_WRONLY | PSP_O_CREAT | PSP_O_TRUNC, 0777);
if (fd < 0)
return -1;
SceUID modid = sceKernelLoadModule("ms0:/PSP/GAME/meminfo-prx-large/hello.prx", 0, NULL);
sceIoWrite (fd, "modid=", 7);
sprintf(buf, "%p\n", modid);
sceIoWrite (fd, buf, 100);
int mresult;
sceKernelStartModule(modid, 0, NULL, &mresult, NULL); //why args for 0 length. pass NULL instead?
sceIoWrite (fd, "end\n", 4);
sceIoClose (fd);
// Completely free all memory
sceKernelSelfStopUnloadModule(1, 0, NULL);
return 0;
}
int module_start (SceSize argc, void* argp)
{
SceUID thread = sceKernelCreateThread("plugin_thread",
plugin_thread, 0x30, 0x10000, 0, NULL); //this is enough
if (thread >= 0) {
sceKernelStartThread (thread, argc, argp);
}
return 0;
} |
|
|
| Back to top |
|
 |
Beuc
Joined: 26 Mar 2009 Posts: 33 Location: holland
|
Posted: Thu May 21, 2009 7:14 pm Post subject: |
|
|
Thanks for your answer.
| Torch wrote: | | Lot of unnecessary crap in your code. And yes the trailing spaces in the makefile lines screw things up. |
Yes, the code was as-is, since I was aiming at getting something that worked before trying to trim it.
I wasn't clear, but actually the Makefile bug was the only thing to fix :]
| Code: |
sceIoChdir(argp); //Might need to append trailing / here.
|
I'd say we need to remove the file part, as argp is normally the path to the current executable. To make things simple I built full paths (getcwd() + "stuff.prx") from the SDL front-end.
For reference, here's the code:
| Code: |
#include <pspsdk.h>
#include <pspkernel.h>
#include <string.h>
PSP_MODULE_INFO("klauncher", 0x1000, 1, 0);
PSP_MAIN_THREAD_ATTR(0); // kernel thread
int klauncher_thread (SceSize args, char* argp)
{
SceUID modid = sceKernelLoadModule(argp, 0, NULL);
if (modid > 0)
{
int ignored_mresult;
sceKernelStartModule(modid, args, argp, &ignored_mresult, NULL);
}
// Completely free all memory
sceKernelSelfStopUnloadModule(1, 0, NULL);
return 0;
}
int
module_start (SceSize args, char* argp)
{
/* We need to run sceKernelLoadModule from a thread */
SceUID thread = sceKernelCreateThread("klauncher_thread",
(void*)klauncher_thread, 0x30, 0x10000, 0, NULL);
if (thread >= 0) {
/* Drop first argument (path to current module) */
int i = 0;
while(argp[i] != '\0') i++;
i++;
sceKernelStartThread (thread, args-i, argp+i);
}
return 0;
}
|
and Makefile:
| Code: |
TARGET = klauncher
OBJS = klauncher.o
CFLAGS = -O2 -G0 -Wall
CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti
LDFLAGS += -mno-crt0 -nostartfiles
BUILD_PRX=1
#PSP_FW_VERSION=303
EXTRA_TARGETS = EBOOT.PBP
PSP_EBOOT_TITLE = klauncher
PSP_LARGE_MEMORY=1
USE_KERNEL_LIBC=1
USE_KERNEL_LIBS=1
PSPSDK=$(shell psp-config --pspsdk-path)
include $(PSPSDK)/lib/build.mak
|
|
|
| Back to top |
|
 |
|
|
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
|