Results 1 to 2 of 2

Thread: Error 0x8002013A SCE_KERNEL_ERROR_LIBRARY_NOT_YET_LINKED loading kernel PRX

  
  1. #1
    HyperHacker's Avatar
    HyperHacker is offline Programmer -Hacks Enthusiast
    Join Date
    Nov 2008
    Location
    Ontario
    Posts
    310
    Rep Power
    10

    Unhappy Error 0x8002013A SCE_KERNEL_ERROR_LIBRARY_NOT_YET_LINKED loading kernel PRX

    So, I've been stumped on this all night and it's really annoying. I can't get a simple kernel PRX to work. It loads and runs just fine (I can see printfs!) but calling any function from the host (user-mode) application returns 0x8002013A.

    I've boiled it down even to a simple test application:

    test.c:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <pspkernel.h>
    #include <pspdebug.h>
    #include <pspdisplay.h>
    #include <pspctrl.h>
    PSP_MODULE_INFO("Test", 0, 1, 1); //Module name, attributes, major version, minor version
    
    int main();
    int exit_callback(int arg1, int arg2, void *common);
    int CallbackThread(SceSize args, void *argp);
    int SetupCallbacks(void);
    
    //kernel module
    int testFunc(int foo);
    
    int main()
    {
    	pspDebugScreenInit();
    	SetupCallbacks();
    
    	pspDebugScreenPrintf("Now printing some text.\n");
    	printf("printf\n");
    	fprintf(stderr, "stderr\n");
    
    	int res = pspSdkLoadStartModule("testkernel.prx",
    		PSP_MEMORY_PARTITION_KERNEL);
    	if(res < 0) {
    		fprintf(stderr, "Failed to load kernel module: error 0x%08X\n", res);
    		pspDebugScreenPrintf(
    			"Failed to load kernel module: error 0x%08X\n",res);
    			sceKernelExitGame();
    	}
    	printf("Loaded kernel module\n");
    
    	res = testFunc(42);
    	printf(" *** test result: 0x%08X\n", res);
    	pspDebugScreenPrintf(" *** test result: 0x%08X\n", res);
    
    
    	int i;
    	for(i=0; i<60; i++) sceDisplayWaitVblankStart();
    	sceKernelExitGame();
    	sceKernelSleepThread(); //wait for termination
    	return 0;
    }
    
    /* Exit callback */
    int exit_callback(int arg1, int arg2, void *common)
    {
    	sceKernelExitGame();
    	return 0;
    }
    
    /* Callback thread */
    int CallbackThread(SceSize args, void *argp)
    {
    	int cbid;
    
    	cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL);
    	sceKernelRegisterExitCallback(cbid);
    	sceKernelSleepThreadCB();
    	return 0;
    }
    
    /* Sets up the callback thread and returns its thread id */
    int SetupCallbacks(void)
    {
    	int thid = 0;
    
    	thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, 0, 0);
    	if(thid >= 0) sceKernelStartThread(thid, 0, 0);
    	return thid;
    }
    Makefile:
    Code:
    TARGET = test
    OBJS = test.o testkernel.o
    
    CFLAGS = -G0 -Wall -O2
    CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti
    ASFLAGS = $(CFLAGS)
    
    LIBS = -lc -lm
    
    BUILD_PRX = 1
    PSP_FW_VERSION = 500
    EXTRA_TARGETS = EBOOT.PBP
    PSP_EBOOT_TITLE = Test Program
    
    PSPSDK=$(shell psp-config --pspsdk-path)
    include $(PSPSDK)/lib/build.mak
    kernel/main.c:
    Code:
    #include <pspkernel.h>
    #include <stdio.h>
    
    PSP_MODULE_INFO("testkernel", PSP_MODULE_KERNEL, 1, 0);
    PSP_NO_CREATE_MAIN_THREAD();
    
    int module_start(SceSize args, void *argp) {
    	printf("Kernel module loaded.\n");
    	return 0;
    }
    
    int module_stop(SceSize args, void *argp) {
    	return 0;
    }
    
    /* Exported function returns the address of module_info */
    void* getModuleInfo(void) {
    	return (void *)&module_info;
    }
    
    
    int testFunc(int foo) {
    	printf(" *** testFunc(%d)\n", foo);
    	return 27;
    }
    kernel/Makefile:
    Code:
    APP_NAME = testkernel
    TARGET = testkernel
    OBJS = main.o
    LIBS = -lpspkernel
    
    BUILD_PRX=1
    PSP_FW_VERSION = 500
    PRX_EXPORTS=exports.exp
    
    #USE_PSPSDK_LIBC=1
    USE_KERNEL_LIBS=1
    
    INCDIR =
    CFLAGS = -O2 -G0 -Wall
    CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti
    ASFLAGS = $(CFLAGS)
    LDFLAGS =
    
    LIBDIR =
    
    all: $(TARGET).prx release
    
    clean-exports:
    	rm -f $(APP_NAME).S
    
    clean: clean-exports
    
    release: stub
    	cp $(APP_NAME).S ../$(APP_NAME).S
    	cp $(TARGET).prx ../$(TARGET).prx
    
    PSPSDK=$(shell psp-config --pspsdk-path)
    include $(PSPSDK)/lib/build_prx.mak
    
    stub: exports.exp
    	psp-build-exports --build-stubs -s $<
    #	psp-build-exports --build-stubs -k $<
    kernel/exports.exp:
    Code:
    PSP_BEGIN_EXPORTS
    
    # These four lines are mandatory (although you can add other functions like module_stop)
    # syslib is a psynonym for the single mandatory export.
    PSP_EXPORT_START(syslib, 0, 0x8000)
    PSP_EXPORT_FUNC_HASH(module_start)
    PSP_EXPORT_FUNC_HASH(module_stop)
    PSP_EXPORT_VAR_HASH(module_info)
    PSP_EXPORT_END
    
    # Export our functions
    PSP_EXPORT_START(testkernel, 0, 0x4001)
    PSP_EXPORT_FUNC(getModuleInfo)
    PSP_EXPORT_FUNC(testFunc)
    PSP_EXPORT_END
    
    PSP_END_EXPORTS
    Everything compiles fine and when I run the test.prx in psplink I see printf output from both the usermode app and the kernel module:
    Code:
    host0:/> ./test.prx
    Load/Start host0:/test.prx UID: 0x0466EC21 Name: Test
    host0:/> printf
    stderr
    Kernel module loaded.Loaded kernel module
     *** test result: 0x8002013A
    You can see the "Kernel module loaded" message (for some reason printf() from kernel ignores the line break?) but testFunc() never gets called and returns this error. I completely don't understand why it's not working. Even a few years ago I had done the exact same thing (on the same PSP, firmware, etc) and it worked fine, so why not now? Some change in PSPSDK?

    >> PSP-2001 running 5.00m33-6, 4GB Lexar memory stick

  2. #2
    HyperHacker's Avatar
    HyperHacker is offline Programmer -Hacks Enthusiast
    Join Date
    Nov 2008
    Location
    Ontario
    Posts
    310
    Rep Power
    10

    Default

    Well I still have no idea what the problem was, but I upgraded to PRO-C2 6.60 and made some changes to the makefile (pretty much copied the systimer example) and now it seems to be working.

    test.c:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <pspkernel.h>
    #include <pspdebug.h>
    #include <pspdisplay.h>
    #include <pspctrl.h>
    PSP_MODULE_INFO("Test", 0, 1, 1); //Module name, attributes, major version, minor version
    PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER | THREAD_ATTR_VFPU);
    PSP_HEAP_SIZE_KB(-256);
    
    int main();
    int exit_callback(int arg1, int arg2, void *common);
    int CallbackThread(SceSize args, void *argp);
    int SetupCallbacks(void);
    
    //kernel module
    int testFunc(int foo);
    
    int main()
    {
    	pspDebugScreenInit();
    	SetupCallbacks();
    
    	pspDebugScreenPrintf("Now printing some text.\n");
    	printf("printf\n");
    	fprintf(stderr, "stderr\n");
    
    	int res = pspSdkLoadStartModule("testkernel.prx",
    		PSP_MEMORY_PARTITION_KERNEL);
    	if(res < 0) {
    		fprintf(stderr, "Failed to load kernel module: error 0x%08X\n", res);
    		pspDebugScreenPrintf(
    			"Failed to load kernel module: error 0x%08X\n",res);
    			sceKernelExitGame();
    	}
    	fflush(stdout);
    	sceDisplayWaitVblank();
    	sceDisplayWaitVblank();
    	printf("Loaded kernel module\n");
    	fflush(stdout);
    
    	//pspSdkFixupImports(res);
    
    	res = testFunc(42);
    	printf(" *** test result: 0x%08X\n", res);
    	pspDebugScreenPrintf(" *** test result: 0x%08X\n", res);
    	fflush(stdout);
    
    
    	int i;
    	for(i=0; i<60; i++) sceDisplayWaitVblankStart();
    	sceKernelExitGame();
    	sceKernelSleepThread(); //wait for termination
    	return 0;
    }
    
    /* Exit callback */
    int exit_callback(int arg1, int arg2, void *common)
    {
    	sceKernelExitGame();
    	return 0;
    }
    
    /* Callback thread */
    int CallbackThread(SceSize args, void *argp)
    {
    	int cbid;
    
    	cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL);
    	sceKernelRegisterExitCallback(cbid);
    	sceKernelSleepThreadCB();
    	return 0;
    }
    
    /* Sets up the callback thread and returns its thread id */
    int SetupCallbacks(void)
    {
    	int thid = 0;
    
    	thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, 0, 0);
    	if(thid >= 0) sceKernelStartThread(thid, 0, 0);
    	return thid;
    }
    Makefile:
    Code:
    TARGET = test
    OBJS = test.o testkernel.o
    
    CFLAGS = -G0 -Wall -O2
    CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti
    ASFLAGS = $(CFLAGS)
    
    LIBS = -lc -lm -lpspsdk
    
    BUILD_PRX = 1
    PSP_FW_VERSION = 371
    EXTRA_TARGETS = EBOOT.PBP
    PSP_EBOOT_TITLE = Test Program
    
    PSPSDK=$(shell psp-config --pspsdk-path)
    include $(PSPSDK)/lib/build.mak
    kernel/main.c:
    Code:
    #include <pspsdk.h>
    #include <pspkernel.h>
    #include <pspdebug.h>
    #include <pspdisplay.h>
    //#include <pspctrl.h>
    //#include <pspsystimer.h>
    
    PSP_MODULE_INFO("testkernel", PSP_MODULE_KERNEL, 1, 0);
    PSP_NO_CREATE_MAIN_THREAD();
    
    int module_start(SceSize args, void *argp) {
    	printf("Kernel module loaded.\n");
    	return 0;
    }
    
    int module_stop(SceSize args, void *argp) {
    	return 0;
    }
    
    /* Exported function returns the address of module_info */
    void* getModuleInfo(void) {
    	return (void *)&module_info;
    }
    
    
    int testFunc(int foo) {
    	printf(" *** testFunc(%d)\n", foo);
    	return 27;
    }
    kernel/Makefile:
    Code:
    TARGET = testkernel
    OBJS = main.o
    
    INCDIR =
    CFLAGS = -O2 -G0 -Wall
    CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti
    ASFLAGS = $(CFLAGS)
    
    BUILD_PRX = 1
    PRX_EXPORTS = exports.exp
    
    USE_KERNEL_LIBC = 1
    USE_KERNEL_LIBS = 1
    
    LIBDIR =
    LDFLAGS = -mno-crt0 -nostartfiles
    #LIBS = -lpsppower_driver -lpspsystemctrl_kernel
    LIBS = #-lpsppower_driver
    
    PSPSDK = $(shell psp-config --pspsdk-path)
    include $(PSPSDK)/lib/build.mak
    kernel/exports.exp:
    Code:
    PSP_BEGIN_EXPORTS
    
    # These four lines are mandatory (although you can add other functions like module_stop)
    # syslib is a psynonym for the single mandatory export.
    PSP_EXPORT_START(syslib, 0, 0x8000)
    PSP_EXPORT_FUNC_HASH(module_start)
    PSP_EXPORT_FUNC_HASH(module_stop)
    PSP_EXPORT_VAR_HASH(module_info)
    PSP_EXPORT_END
    
    # Export our functions
    PSP_EXPORT_START(testkernel, 0, 0x4001)
    PSP_EXPORT_FUNC(getModuleInfo)
    PSP_EXPORT_FUNC(testFunc)
    PSP_EXPORT_END
    
    PSP_END_EXPORTS
    (those makefiles aren't very good; you have to build the kernel PRX and usermode app separately; in kernel directory, do:
    Code:
    psp-build-exports -s exports.exp
    cp testkernel.prx ..
    cp testkernel.S ..
    - you must do this before trying to compile the usermode app. But anyway, it successfully loads and displays the expected output.)

    Still the printf glitch remains (the "loaded kernel module" line gets output without a line break, and the "testFunc" line doesn't appear at all); I tried fflush() but I'm always getting undefined reference errors when compiling the kernel prx with that. Oh well, it loads and runs now anyway...

    [EDIT] oh my god.

    Code:
     < include $(PSPSDK)/lib/build_prx.mak
    > include $(PSPSDK)/lib/build.mak
    I bet that was the entire problem...
    Last edited by HyperHacker; 10-20-2014 at 10:58 PM.
    >> PSP-2001 running 5.00m33-6, 4GB Lexar memory stick

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •