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 

[solved] sceKernelLoadModule in kernel mode

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



Joined: 26 Mar 2009
Posts: 33
Location: holland

PostPosted: Wed May 20, 2009 4:55 am    Post subject: [solved] sceKernelLoadModule in kernel mode Reply with quote

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



Joined: 28 May 2008
Posts: 842

PostPosted: Wed May 20, 2009 11:17 pm    Post subject: Reply with quote

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



Joined: 26 Mar 2009
Posts: 33
Location: holland

PostPosted: Thu May 21, 2009 5:15 am    Post subject: Reply with quote

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



Joined: 26 Mar 2009
Posts: 33
Location: holland

PostPosted: Thu May 21, 2009 7:13 am    Post subject: Reply with quote

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



Joined: 28 May 2008
Posts: 842

PostPosted: Thu May 21, 2009 6:22 pm    Post subject: Reply with quote

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



Joined: 26 Mar 2009
Posts: 33
Location: holland

PostPosted: Thu May 21, 2009 7:14 pm    Post subject: Reply with quote

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
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