prx bug

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

Moderators: cheriff, TyRaNiD

Post Reply
User avatar
hotter
Posts: 53
Joined: Sun Dec 07, 2008 8:49 pm

prx bug

Post by hotter »

I am making a prx in kernel mode and I use it as plugin. After functions such as sin(), cos() or read directory from memory stick, web browser doesnt work, and if I push on XMB videos, then psp hangs (well the wait icon is blinking and thats all, I can still use my prx... just XMB menu hangs). What could be wrong? maybe someone had such bug?
Pragramming with:
Microsoft Visual C 2008 + pspsdk MINPSPW 0.8.10
TyRaNiD
Posts: 907
Joined: Sun Jan 18, 2004 12:23 am

Post by TyRaNiD »

Perhaps blowing away all your memory in kernel space.
User avatar
hotter
Posts: 53
Joined: Sun Dec 07, 2008 8:49 pm

Post by hotter »

Might be. And how I should avoid this?
Pragramming with:
Microsoft Visual C 2008 + pspsdk MINPSPW 0.8.10
User avatar
Torch
Posts: 825
Joined: Wed May 28, 2008 2:50 am

Post by Torch »

Learn how to program. You're kernel plugin should avoid allocating any extra memory if possible. If you do don't exceed more than 100 or so KiB.
TyRaNiD
Posts: 907
Joined: Sun Jan 18, 2004 12:23 am

Post by TyRaNiD »

A touch harsh :)

Try running the command 'psp-size your.prx' and see what its total memory footprint is. Don't allocate large global buffers, don't create many threads with large stack sizes, don't do allocations direct out of kernel memory, all those kinda of things. Also ideally don't use the libc, especially not newlib, you might get away with using libm (though it is probably not recommended). You can use a cut down internal libc by specifying a makefile option to reduce memory size.
User avatar
hotter
Posts: 53
Joined: Sun Dec 07, 2008 8:49 pm

Post by hotter »

This is what I get after psp-size:

Code: Select all

   text    data     bss     dec     hex filename
 109768    2360   28688  140816   22610 PSPconsole.prx
I guess it is realy big numbers for prx, yes?
well I dont use USE_KERNEL_LIBC=1 and USE_KERNEL_LIBS=1 in my make file because then such functions as time(), clock() and some other are undefined and I dont know why... And I need to use short integer array... Maybe there is other space where I could save my variables? some hint or examples would be cool....
well my programing skills is not realy high... I just know basics... :( But I am doing my best...
Last edited by hotter on Wed Jan 28, 2009 7:08 am, edited 1 time in total.
Pragramming with:
Microsoft Visual C 2008 + pspsdk MINPSPW 0.8.10
User avatar
Torch
Posts: 825
Joined: Wed May 28, 2008 2:50 am

Post by Torch »

Not using kernel libc will bloat your prx by around 84KiB.
However kernel libc is limited. You will just have to make do or write your own functions for those missing ones.

Just use the equivalent sce functions for time and stuff.
TyRaNiD
Posts: 907
Joined: Sun Jan 18, 2004 12:23 am

Post by TyRaNiD »

Yah it looks like most of your bloat is in .text which means it is primarily code. 140k is quite large for a kernel executable. You really need to set the kernel libraries only and reimplement as touch says, tbh at least clock and time are implemented by the kernel just not in the libc, do a search :)
User avatar
hotter
Posts: 53
Joined: Sun Dec 07, 2008 8:49 pm

Post by hotter »

well everything seems to work better now, I just have problems with float and double type variables, they are = 0; but when I try to print them I get letter "f". why? :( before adding thouse two lines in make file these variables worked fine....

P.S. what are pros and cons of making a prx in kernel mode, user mode or other? maybe user mode can use more memory? well I guess the first cons would be that just in kernel mode i couldnt use syscall...
Pragramming with:
Microsoft Visual C 2008 + pspsdk MINPSPW 0.8.10
TyRaNiD
Posts: 907
Joined: Sun Jan 18, 2004 12:23 am

Post by TyRaNiD »

The kernel libc's printf doesn't support printing of floats or doubles, you have to write code to convert the float yourself to a string then print that.

As for advantages/disadvantages for plugins while you have more user ram if nothing is using it games will almost always use as much as possible so you will find some games won't run if your plugin was user mode. As for syscalls except for a small set of functions all core stuff should be accessible in kernel mode directly, main think you can't as easily access is networking.
User avatar
hotter
Posts: 53
Joined: Sun Dec 07, 2008 8:49 pm

Post by hotter »

I guess user mode would be better for me because my prx is usable in XMB menu, not in games. But how to disable XMB buttons from user mode? maybe there is a way to start prx in kernel mode and after patchsyscall make it user mode something like that?
Pragramming with:
Microsoft Visual C 2008 + pspsdk MINPSPW 0.8.10
User avatar
Torch
Posts: 825
Joined: Wed May 28, 2008 2:50 am

Post by Torch »

hotter wrote:I guess user mode would be better for me because my prx is usable in XMB menu, not in games. But how to disable XMB buttons from user mode? maybe there is a way to start prx in kernel mode and after patchsyscall make it user mode something like that?
Even in the XMB, the Phat will run out of memory and crash if you consume more than 100-150KiB. On coldboot at the XMB (without opening anything) there is around 2740KiB free. This will reduce as you open stuff in the XMB.

In the Slim XMB you can simply allocate user memory with malloc or whatever and it will take it from the heap which includes the extra 32MiB without needing to do anything special.

In game mode (official games) on the Slim you need to explicitly allocate into the last 32MiB. In homebrew, depending on whether the EBOOT has used the extra memory you may not be able to allocate from it.

To disable XMB buttons you have to use a kernel prx to hook the vshCtrlReadBufferPositive and zero the SceCtrlPad.Buttons to disable them.

You can still normally call sceCtrlReadBufferPositive from your user prx.
User avatar
hotter
Posts: 53
Joined: Sun Dec 07, 2008 8:49 pm

Post by hotter »

what if I leave my prx as is in kernel mode and just add PSP_HEAP_SIZE_KB(1024); ? will there be more memory bugs with this?
Pragramming with:
Microsoft Visual C 2008 + pspsdk MINPSPW 0.8.10
User avatar
Torch
Posts: 825
Joined: Wed May 28, 2008 2:50 am

Post by Torch »

hotter wrote:what if I leave my prx as is in kernel mode and just add PSP_HEAP_SIZE_KB(1024); ? will there be more memory bugs with this?
Please DON'T allocate a big heap in kernel mode. You would just take a precious chunk out of it and leave most of it unused. Use the sceKernelAllocPartition functions to allocate the exact required amount from kernel memory.
User avatar
hotter
Posts: 53
Joined: Sun Dec 07, 2008 8:49 pm

Post by hotter »

Thx Torch, I am trying to use sceKernelAllocPartition function :)

I allocated memory for some chars..... but how to allocate memory for double array?

Code: Select all

//short int ar[60][34];
SceUID mem = sceKernelAllocPartitionMemory(2, "mem", 0, sizeof(short int) * 60 * 34, NULL); 
short int * ar = (short int *)sceKernelGetBlockHeadAddr(mem);
this doesnt work :(
Pragramming with:
Microsoft Visual C 2008 + pspsdk MINPSPW 0.8.10
User avatar
Torch
Posts: 825
Joined: Wed May 28, 2008 2:50 am

Post by Torch »

It only returns a pointer to a contiguous memory block, so i don't think you can directly call like ar[row][column] after allocation because the compiler won't know the dimensions. There's probably some macro or something to access it like a 2d array but I don't know.

Code: Select all

//short int ar[60][34]; 
SceUID mem = sceKernelAllocPartitionMemory(2, "mem", 0, sizeof(short int)*60*34, NULL); 
short int * ar = (short int *)sceKernelGetBlockHeadAddr(mem);

//access like ar[34*row + column] to get ar[row][column]
Bubbletune
Posts: 22
Joined: Sat Jan 03, 2009 6:51 am

Post by Bubbletune »

Torch wrote:There's probably some macro or something to access it like a 2d array but I don't know.

Code: Select all

short int (*ar)[60]; // note the ( and )
SceUID blockid = sceKernelAllocPartitionMemory(2, "mem", 0, sizeof(ar)*34, NULL);

if (blockid >= 0)
{
	ar = (void *)sceKernelGetBlockHeadAddr(mem);
}
Post Reply