Help on a prx in kernel mode which runs in user mode

Discuss the development of new homebrew software, tools and libraries.

Moderators: cheriff, TyRaNiD

Post Reply
pspZorba
Posts: 156
Joined: Sat Sep 22, 2007 11:45 am
Location: NY

Help on a prx in kernel mode which runs in user mode

Post by pspZorba »

Hi all,

I am doing some exercises with prx and kernel mode and I am stuck on on the following issue:

I want to read the name of all the files and directories in flash0: and writes them in a file (dir.txt) which is on ms0:.
a) If I run the eboot in user mode I can't see what is in kd/ etc .. (which is normal, I guess, due to firmware protection)
b) If I run the eboot in kernel mode I can see everything,

But setting the eboot in kernel mode is not very elegant. So I decided to put the functions that should run in kernel mode in a prx (in kernel mode) and call them from my eboot which is in user mode.
It runs, I can have my dir.txt but it acts as if I were in case a), I can't see what's in kd/...
I probably missing something which is evident ....
Any help would be appreciated.

Here are my files:

the prx part:

main.c :

Code: Select all

#include <pspkernel.h>
#include <pspmodulemgr_kernel.h>
#include <pspsdk.h>

#include <pspiofilemgr.h>
#include <pspiofilemgr_dirent.h>

#include <string.h>

/* Define the module info section */
#define MY_HOMEBREW_MAJOR_VERSION  0
#define MY_HOMEBREW_MINOR_VERSION  42 


PSP_MODULE_INFO&#40;"myprx", PSP_MODULE_KERNEL, MY_HOMEBREW_MAJOR_VERSION, MY_HOMEBREW_MINOR_VERSION&#41;;
PSP_MAIN_THREAD_ATTR&#40;0&#41;;


//those two functions are madatory !
int module_start&#40;SceSize args, void *argp&#41;
&#123;
   return 0;
&#125;

int module_stop&#40;&#41;
&#123;
   return 0;
&#125;

//the functions i want to run in kernel mode
SceUID EXTsceIoDopen&#40; const char * name&#41;
&#123;
	SceUID ret;
 	u32 k1;
	k1 = pspSdkSetK1&#40;0&#41;; 
	
	ret =  sceIoDopen&#40;name&#41;; 

	pspSdkSetK1&#40;k1&#41;;	
	return ret; 
&#125;

int EXTsceIoDread&#40;SceUID uid, SceIoDirent *pDirEnt&#41;
&#123;
	SceUID ret;
 	u32 k1;
    k1 = pspSdkSetK1&#40;0&#41;; 
	
	ret =  sceIoDread&#40;uid, pDirEnt&#41;;

	pspSdkSetK1&#40;k1&#41;;	
	return ret; 
&#125;

int EXTsceIoGetstat&#40; const char *name, SceIoStat *pD_stat&#41;
&#123;
	SceUID ret;
 	u32 k1;
	k1 = pspSdkSetK1&#40;0&#41;; 
	
	ret = sceIoGetstat&#40; name, pD_stat&#41;;

	pspSdkSetK1&#40;k1&#41;;	
	return ret; 
&#125;

int EXTsceIoDclose&#40; SceUID uid&#41;
&#123;
	SceUID ret;
 	u32 k1;
	k1 = pspSdkSetK1&#40;0&#41;; 
	
	ret =  sceIoDclose&#40;uid&#41;; 

	pspSdkSetK1&#40;k1&#41;;	
	return ret; 
&#125;

prx makefile :

Code: Select all

TARGET = myprx
OBJS = main.o 

INCDIR =
CFLAGS = -O2 -G0 -Wall
CXXFLAGS = $&#40;CFLAGS&#41; -fno-exceptions -fno-rtti
ASFLAGS = $&#40;CFLAGS&#41;

PSP_FW_VERSION=371

BUILD_PRX = 1
PRX_EXPORTS = myprx.exp

USE_KERNEL_LIBC=1
USE_KERNEL_LIBS=1

LIBDIR =
LDFLAGS = -mno-crt0 -nostartfiles
LIBS = 


PSPSDK=$&#40;shell psp-config --pspsdk-path&#41;
include $&#40;PSPSDK&#41;/lib/build.mak

(export file) myprx.exp:

Code: Select all

# Define the exports for the prx
PSP_BEGIN_EXPORTS

# These four lines are mandatory &#40;although you can add other functions like module_stop&#41;
# syslib is a psynonym for the single mandatory export.
PSP_EXPORT_START&#40;syslib, 0, 0x8000&#41;
PSP_EXPORT_FUNC_HASH&#40;module_start&#41;
PSP_EXPORT_VAR_HASH&#40;module_info&#41;
PSP_EXPORT_END

PSP_EXPORT_START&#40;myprx, 0, 0x4001&#41;
PSP_EXPORT_FUNC&#40;EXTsceIoDopen&#41;
PSP_EXPORT_FUNC&#40;EXTsceIoDread&#41;
PSP_EXPORT_FUNC&#40;EXTsceIoGetstat&#41;
PSP_EXPORT_FUNC&#40;EXTsceIoDclose&#41;
PSP_EXPORT_END

PSP_END_EXPORTS




the loader part

main.c:

Code: Select all

#include <pspkernel.h>
#include <pspdebug.h>
#include <stdlib.h>
#include <string.h>
#include <pspsdk.h>


/* Define the module info section */
#define MY_HOMEBREW_MAJOR_VERSION  0
#define MY_HOMEBREW_MINOR_VERSION  42 

PSP_MODULE_INFO&#40;"myEBOOT", PSP_MODULE_USER, MY_HOMEBREW_MAJOR_VERSION, MY_HOMEBREW_MINOR_VERSION&#41;;
//PSP_HEAP_SIZE_MAX&#40;&#41;;
PSP_HEAP_SIZE_KB&#40; 8192&#41;;

/* Define the main thread's attribute value &#40;optional&#41; */
PSP_MAIN_THREAD_ATTR&#40;PSP_THREAD_ATTR_USER&#41;;
int sceInit&#40;void&#41;;  


/* here are the functions that have been put in the prx*/
SceUID EXTsceIoDopen&#40; const char * name&#41;;
int EXTsceIoDread&#40;SceUID uid, SceIoDirent *pDirEnt&#41;;
int EXTsceIoGetstat&#40; const char *name, SceIoStat *pD_stat&#41;;
int EXTsceIoDclose&#40; SceUID uid&#41;;



/* the real main function &#40;recursive&#41; which loads the files and directories name then write them it a file*/
void printDirectory&#40; const char *name,  SceUID hdDir&#41;
&#123;
 	SceUID uid; 
	struct SceIoDirent dirEnt;
	SceIoStat d_stat;
	char fullname&#91;512&#93;;
	
	//we open the "directory"
 	uid = EXTsceIoDopen&#40;name&#41;; 

	dirEnt.d_private=NULL; //if not done the at the first use of dirEnt in sceIoDread => crash
			//2&#41; for all the enties 
	while&#40;EXTsceIoDread&#40;uid, &dirEnt&#41;>0&#41;
	&#123;
		//create the full name &#40;tha absolute name&#41;
		strcpy&#40; fullname,  name&#41;; 
		strcat&#40; fullname,"/"&#41;; 
		strcat&#40; fullname, dirEnt.d_name&#41;;

		//we write the name of the entry in the file 
		sceIoWrite&#40; hdDir, fullname, strlen&#40; fullname&#41;&#41;;
		sceIoWrite&#40; hdDir,"\r\n", 2&#41;; //to be able to read the file on windows

		//we laod the info on the file, to check if it's a directory, if so we do a recursive call to printDirectory
		//in order to explore the directory
		EXTsceIoGetstat&#40; fullname, &d_stat&#41;;//we load the file information
		if&#40; &#40;FIO_S_IFDIR & d_stat.st_mode&#41; && &#40;strcmp&#40;dirEnt.d_name,"."&#41;!=0&#41;&& &#40;strcmp&#40;dirEnt.d_name,".."&#41;!=0&#41;&#41;
		&#123;
			printDirectory&#40; fullname, hdDir&#41;; //recursive call
		&#125;
		
	&#125;
		//we close the  directory
	EXTsceIoDclose&#40;uid&#41;; 

&#125;


int main&#40; void&#41;  
&#123;
	//System initilization
	sceInit&#40;&#41;;  //set exit callback 
	pspDebugScreenInit&#40;&#41;;  //init the screen in a special mode that allow us to print on it easily

	//reset the screen
	pspDebugScreenClear&#40;&#41;;

    SceUID mod = pspSdkLoadStartModule&#40;"myprx.prx", PSP_MEMORY_PARTITION_KERNEL&#41;;

    if &#40;mod < 0&#41;
    &#123;
    	pspDebugScreenPrintf&#40;"Error 0x%08X loading/starting myprx.prx.\n", mod&#41;;
    &#125;
    else
    &#123;
		//we open &#40;create&#41; the file dir.txt, that will contain the list of the dirs and files of flash0
		SceUID hdDir = sceIoOpen&#40;"ms0&#58;/PSP/GAME/test/dir.txt", PSP_O_RDWR | PSP_O_CREAT| PSP_O_TRUNC, 0777&#41;;  
		if&#40;hdDir <=0&#41;
		&#123;
		  pspDebugScreenPuts&#40;"Can't create ms0&#58;/PSP/GAME/test/dir.txt"&#41;;
		&#125;
		else
		&#123;
			//Prints the name of all files and directories located at the root of flash0&#58;
			printDirectory&#40;"flash0&#58;/", hdDir&#41;; 
		
			sceIoClose&#40;hdDir&#41;; 
		&#125;
		
		 pspDebugScreenPuts&#40;"End !!"&#41;;
    &#125;
	sceKernelSleepThread&#40;&#41;;  //suspend the system, waiting for the user to press "home" key
	
return 0;
&#125;
  
 
 


/* Exit callback */
int exit_callback&#40;int arg1, int arg2, void *common&#41;
&#123;
        sceKernelExitGame&#40;&#41;;
        return &#40;int&#41;0;
&#125;

/* Callback thread */
int CallbackThread&#40;SceSize args, void *argp&#41;
&#123;
        int cbid;

        cbid = sceKernelCreateCallback&#40;"Exit Callback", exit_callback, NULL&#41;;
        sceKernelRegisterExitCallback&#40;cbid&#41;;

        sceKernelSleepThreadCB&#40;&#41;;

        return 0; 
&#125;

int sceInit&#40;void&#41; 
&#123;
       int thid = 0;

        thid = sceKernelCreateThread&#40;"update_thread", CallbackThread, 0x11, 0xFA0, 0, 0&#41;;
        if&#40;thid >= 0&#41;
        &#123;
                sceKernelStartThread&#40;thid, 0, 0&#41;;
        &#125;

        return thid;
&#125;



(I generated the myprx.S and copied it the same directory as my loader sources)

makefile:

Code: Select all

TARGET = myEBOOT

PSP_FW_VERSION = 371


OBJS = myprx.o main.o 
    
       
INCDIR =
CFLAGS = -O2 -G0 -Wall
CXXFLAGS = $&#40;CFLAGS&#41; -fno-exceptions -fno-rtti
ASFLAGS = $&#40;CFLAGS&#41;

BUILD_PRX = 1

LIBDIR =
LIBS = 
LDFLAGS = 


EXTRA_TARGETS = EBOOT.PBP
PSP_EBOOT_TITLE = "TEST"
PSP_EBOOT_ICON=NULL
PSP_EBOOT_UNKPNG=NULL
PSP_EBOOT_PIC1=NULL
PSP_EBOOT_SND0=NULL 

PSPSDK=$&#40;shell psp-config --pspsdk-path&#41;
include $&#40;PSPSDK&#41;/lib/build.mak
Post Reply