| View previous topic :: View next topic |
| Author |
Message |
Hellcat
Joined: 24 Jan 2007 Posts: 84
|
Posted: Tue Sep 11, 2007 1:20 pm Post subject: Now that PSP Slim CFW is out.... devin' on it.... |
|
|
So, how about devving on the 3.60 Slim CFW?
As there's no 1.50 kernel anymore, there's some changes now, aren't there?
Are there already specs on new "guidelines" how to make HB for the new 3.60 CFW? |
|
| Back to top |
|
 |
jimparis
Joined: 10 Jun 2005 Posts: 1179 Location: Boston
|
Posted: Tue Sep 11, 2007 2:10 pm Post subject: |
|
|
| Development for the Slim and 3.60 is largely the same. Since it's not 1.50 anymore, you'll want to set BUILD_PRX=1 and PSP_FW_VERSION=360 in your Makefile. Since the executable is now a PRX, the default heap size will be only 64kb and you'll want something like PSP_HEAP_SIZE_KB(25000) in your C file to give malloc() a bigger pool. The extra memory is located in a different partition as described here, which newlib isn't set up to use at the moment. |
|
| Back to top |
|
 |
kururin
Joined: 05 Jul 2006 Posts: 36
|
Posted: Tue Sep 11, 2007 7:19 pm Post subject: |
|
|
You can use static elf in user mode too.
Some hoembrew with those characteristics work fine. |
|
| Back to top |
|
 |
e_boris
Joined: 19 May 2007 Posts: 25
|
Posted: Wed Sep 12, 2007 1:17 am Post subject: |
|
|
I am using “make kxploit” to build my PSP application before. So it is supposed to be for FW1.50. Now I am shifting to PSP slim.
jimparis: Have you just tried your configuation yet? Does it work? I found it doesn't.Is there anything I missed?
I change the header of main.cpp to:
| Code: |
/* Define the module info section */
PSP_MODULE_INFO("CodeLib_PSP", PSP_MODULE_KERNEL, 1, 0);
PSP_MAIN_THREAD_ATTR(0);
PSP_HEAP_SIZE_KB(25000);
...
|
and change the makefile to:
| Code: |
....
INCDIR = ../CrystalWings_Lib
CFLAGS = -G0 -Wall -O2 -D_DEBUG -DPSPDevkit -DPSP_FW_VERSION=360 -DBUILD_PRX=1
CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti
ASFLAGS = $(CFLAGS)
....
|
Then I copy the compiled eboot.pbp to PSP\GAME360\XXXX\eboot.pbp
But it failed to launch in XMB with error code 80020148 |
|
| Back to top |
|
 |
weltall
Joined: 20 Feb 2004 Posts: 310
|
Posted: Wed Sep 12, 2007 2:26 am Post subject: |
|
|
build prx doesn't go as a c flags but just as
BUILD_PRX=1 in the prx wherever you want in the makefile |
|
| Back to top |
|
 |
kururin
Joined: 05 Jul 2006 Posts: 36
|
Posted: Wed Sep 12, 2007 2:44 am Post subject: |
|
|
| e_boris wrote: | I am using “make kxploit” to build my PSP application before. So it is supposed to be for FW1.50. Now I am shifting to PSP slim.
jimparis: Have you just tried your configuation yet? Does it work? I found it doesn't.Is there anything I missed?
I change the header of main.cpp to:
| Code: |
/* Define the module info section */
PSP_MODULE_INFO("CodeLib_PSP", PSP_MODULE_KERNEL, 1, 0);
PSP_MAIN_THREAD_ATTR(0);
PSP_HEAP_SIZE_KB(25000);
...
|
and change the makefile to:
| Code: |
....
INCDIR = ../CrystalWings_Lib
CFLAGS = -G0 -Wall -O2 -D_DEBUG -DPSPDevkit -DPSP_FW_VERSION=360 -DBUILD_PRX=1
CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti
ASFLAGS = $(CFLAGS)
....
|
Then I copy the compiled eboot.pbp to PSP\GAME360\XXXX\eboot.pbp
But it failed to launch in XMB with error code 80020148 |
The eboot.pbp has to be user mode. Then, you can load kernel prx's with it, but they have to be free of user imports. Here, it is when a remodelation of the sdk would come handy, because using only kernel libraries you can't use for example pspDebugScreenPrintf... |
|
| Back to top |
|
 |
J.F.
Joined: 22 Feb 2004 Posts: 2906
|
Posted: Wed Sep 12, 2007 4:14 am Post subject: |
|
|
| kururin wrote: |
The eboot.pbp has to be user mode. Then, you can load kernel prx's with it, but they have to be free of user imports. Here, it is when a remodelation of the sdk would come handy, because using only kernel libraries you can't use for example pspDebugScreenPrintf... |
Hmm - the latest KeyCleaner works on the slim, and it uses libpng as well as the kernel IdStorage routines and pspDebugScreenPrintf. They all work fine in it. |
|
| Back to top |
|
 |
e_boris
Joined: 19 May 2007 Posts: 25
|
Posted: Wed Sep 12, 2007 4:34 am Post subject: |
|
|
Then? What is the conclusion? I am confused.
hi, J.F. , Can you tell me the version of KeyCleaner? I am seeking for its source.
hi, kururin, can you just explain more about "you can load kernel prx's with it". Are you saying start the app in user mode. and then make kernel calling via some customized prx?
Thanks a lot for you help!! |
|
| Back to top |
|
 |
cory1492
Joined: 10 Dec 2004 Posts: 216
|
Posted: Wed Sep 12, 2007 8:03 am Post subject: |
|
|
| Chilly Willy's keycleaner is an excellent example of moving the kernel stuff into a separate prx, Google turned up this link quite quickly and which includes source. |
|
| Back to top |
|
 |
J.F.
Joined: 22 Feb 2004 Posts: 2906
|
Posted: Wed Sep 12, 2007 10:25 am Post subject: |
|
|
Chilly has a google page where the latest is always posted.
http://groups.google.com/group/chilly-willys-ice-flow/?hl=en
The latest is 1.3. I've used it to dump the keys on my slim to see how they compare to my old PSP. Just don't try to use it to "fix" the keys as it's clearly designed for the 82/86, with some 79/81 support.
At this point, none of the keys are being modified, so messing with the keys is more a curiosity than a necessity.
If you compare the KeyCleaner source to the 3.xx HEN examples, you'll see it pretty much the same.
I suppose the way to express 3.xx programming is keep the main part of the app all in userland, and stuff any specific kernel calls into an external prx that you load and call like the 3.xx HEN examples (or KeyCleaner). |
|
| Back to top |
|
 |
Raphael

Joined: 17 Jan 2006 Posts: 646 Location: Germany
|
Posted: Wed Sep 12, 2007 11:28 am Post subject: |
|
|
In fact all libraries with function names starting with "psp" rather than "sce" are not a problem to the user/kernel mode seperation problem.
Those are all libraries completely written by the PSPSDK devs, so they run exactly as your own code in the mode you load your executable in.
The sce functions on the other hand are just imports from the appropriate prxes that run in background, hence why those run either in user or kernel mode, depending on the library you link to.
So if you want to use kernel mode functions, link the *_driver library, and (if required, because you want to use functions that are exclusive to the kernel mode library) include the *_kernel.h header file additionally to the normal header.
I second J.F. with the explicit extraction of kernel mode functionality into a seperate prx. _________________ <Don't push the river, it flows.>
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki
Alexander Berl |
|
| Back to top |
|
 |
kururin
Joined: 05 Jul 2006 Posts: 36
|
Posted: Wed Sep 12, 2007 5:02 pm Post subject: |
|
|
| Raphael wrote: | | In fact all libraries with function names starting with "psp" rather than "sce" are not a problem to the user/kernel mode seperation problem. |
well some of the psp ones may use user specific functions, like that one that gets max free mem size. |
|
| Back to top |
|
 |
e_boris
Joined: 19 May 2007 Posts: 25
|
Posted: Wed Sep 12, 2007 5:30 pm Post subject: |
|
|
Thanks all, but wrap kernel callings to a customized prx is the only way? Is it possible to launch Homebrew in 3.xx/kernel mode?
Also, Did anyone get the source code of "PSP WiFile Transfer".
http://dl.qj.net/PSP-WiFile-Transfer-v0.01-PSP-Homebrew-Applications/pg/12/fid/12382/catid/151
It works well on 3.xx mode. I am not sure it is started in user mode or kernel mode. But definitely it made some kernel calls (initialize connection to AP). But you can not find any customized prx along with the its eboot.pbp.
How can he made it??? |
|
| Back to top |
|
 |
Fanjita
Joined: 28 Sep 2005 Posts: 217
|
Posted: Wed Sep 12, 2007 6:42 pm Post subject: |
|
|
There are user-mode funcs to initialize the network, ever since something like FW v2.00. _________________ Got a v2.0-v2.80 firmware PSP? Download the eLoader here to run homebrew on it!
The PSP Homebrew Database needs you! |
|
| Back to top |
|
 |
Hellcat
Joined: 24 Jan 2007 Posts: 84
|
Posted: Wed Sep 12, 2007 8:38 pm Post subject: |
|
|
Wow, time I get a Slim already....
Sadly they only have black ones in Germany at the moment.... Icey Silver is scheduled to be available ob the 20th.... I hope they are, I'll get one those ASAP.
Wanna try doing something on the Slim :) |
|
| Back to top |
|
 |
e_boris
Joined: 19 May 2007 Posts: 25
|
Posted: Wed Sep 12, 2007 10:30 pm Post subject: |
|
|
Fanjita:
Can network initialization done with all user mode functions? My calling sequence is like:
| Code: |
....
//Kernel Mode Initialization calling in kernel thread
pspKernelSetKernelPC();
pspSdkInstallNoDeviceCheckPatch();
pspSdkInstallNoPlainModuleCheckPatch();
pspSdkInstallKernelLoadModulePatch();
....
//calling in kernel thread (I found this call fails in user mode thread)
pspSdkLoadInetModules
....
//then call in user mode thread (this must be in user mode to avoid dynamic IP configuation problem)
if(0==pspSdkInetInit())
{
if(sceNetApctlConnect(*((int*)argp))==0)
{
int timeout = ((int*)argp)[1];
int state=0;
while(timeout > 100)
{
if(0!=sceNetApctlGetState(&state))
{ _CheckPoint;
break;
}
if(state==4)
return 1;
rts::Sleep(100);
timeout-=100;
}
}
else _CheckPoint;
}
else _CheckPoint;
.....
// Then go socket codes
.....
|
Is there any other alternative calling sequence using user mode functions only??? |
|
| Back to top |
|
 |
kururin
Joined: 05 Jul 2006 Posts: 36
|
Posted: Thu Sep 13, 2007 2:56 am Post subject: |
|
|
| e_boris wrote: | Fanjita:
Can network initialization done with all user mode functions? My calling sequence is like:
| Code: |
....
//Kernel Mode Initialization calling in kernel thread
pspKernelSetKernelPC();
pspSdkInstallNoDeviceCheckPatch();
pspSdkInstallNoPlainModuleCheckPatch();
pspSdkInstallKernelLoadModulePatch();
....
//calling in kernel thread (I found this call fails in user mode thread)
pspSdkLoadInetModules
....
//then call in user mode thread (this must be in user mode to avoid dynamic IP configuation problem)
if(0==pspSdkInetInit())
{
if(sceNetApctlConnect(*((int*)argp))==0)
{
int timeout = ((int*)argp)[1];
int state=0;
while(timeout > 100)
{
if(0!=sceNetApctlGetState(&state))
{ _CheckPoint;
break;
}
if(state==4)
return 1;
rts::Sleep(100);
timeout-=100;
}
}
else _CheckPoint;
}
else _CheckPoint;
.....
// Then go socket codes
.....
|
Is there any other alternative calling sequence using user mode functions only??? |
DO NOT USE the module patch functions in 3.XX. |
|
| Back to top |
|
 |
e_boris
Joined: 19 May 2007 Posts: 25
|
Posted: Fri Sep 14, 2007 8:17 am Post subject: |
|
|
Hi, kururin:
If not using module patch functions, then how to load modules??
I found the USB Mass Storage code fails if just remove calls to module patch functions.
| Code: |
pspSdkLoadStartModule("flash0:/kd/semawm.prx", PSP_MEMORY_PARTITION_KERNEL);
pspSdkLoadStartModule("flash0:/kd/usbstor.prx", PSP_MEMORY_PARTITION_KERNEL);
pspSdkLoadStartModule("flash0:/kd/usbstormgr.prx", PSP_MEMORY_PARTITION_KERNEL);
pspSdkLoadStartModule("flash0:/kd/usbstorms.prx", PSP_MEMORY_PARTITION_KERNEL);
pspSdkLoadStartModule("flash0:/kd/usbstorboot.prx", PSP_MEMORY_PARTITION_KERNEL);
//setup USB drivers
if( sceUsbStart(PSP_USBBUS_DRIVERNAME, 0, 0)==0 &&
sceUsbStart(PSP_USBSTOR_DRIVERNAME, 0, 0)==0 )
{
sceUsbstorBootSetCapacity(0x800000);
m_bIsInitialized = true;
}
else
{
m_bIsInitialized = false;
_CheckPoint;
}
sceUsbActivate(0x1c8);
|
The USB is not activated. But if I keep calling to module patch functions, the XMB failed to launch it with error code 8002013C. |
|
| Back to top |
|
 |
e_boris
Joined: 19 May 2007 Posts: 25
|
Posted: Fri Sep 14, 2007 6:30 pm Post subject: |
|
|
I just digged into my code. I find pspSdkLoadStartModule returns 8002013C (library not found) when loading usbstorms.prx and usbstorboot.prx. But I checked the f0:, they exist.
And even in this way. both sceUsbStart call returned succeeded. and also does sceUsbActivate(0x1c8);
However, USB Mass stroage device does not detected by Windows. Nothing happens.
Can anyone helps me???
Thanks in advance. |
|
| Back to top |
|
 |
kururin
Joined: 05 Jul 2006 Posts: 36
|
Posted: Fri Sep 14, 2007 7:40 pm Post subject: |
|
|
| e_boris wrote: | I just digged into my code. I find pspSdkLoadStartModule returns 8002013C (library not found) when loading usbstorms.prx and usbstorboot.prx. But I checked the f0:, they exist.
And even in this way. both sceUsbStart call returned succeeded. and also does sceUsbActivate(0x1c8);
However, USB Mass stroage device does not detected by Windows. Nothing happens.
Can anyone helps me???
Thanks in advance. |
The slim usb mass storage pid is 0x2d2, not 0x1C8 (use slim conditional code with the GetModel function).
Use the kuKernelLoadModule from cfw SDK for loading flash modules. User modules have problems loading some modules from flash, but that function will call loadmodule with kernel privileges. |
|
| Back to top |
|
 |
e_boris
Joined: 19 May 2007 Posts: 25
|
Posted: Fri Sep 14, 2007 10:47 pm Post subject: |
|
|
Thanks kururin.
Currently I am testing on a PSP1006 (the Fat one) with CFW3.52M33-4. So the usb mass storage pid may not be the problem.
So what is CFW SDK? is it included in PSPSDK? I can not found the GetModel function or kuKernelLoadModule by search the PSPSDK header files.
Or, I need my PSPSDK package to be updated? |
|
| Back to top |
|
 |
kururin
Joined: 05 Jul 2006 Posts: 36
|
Posted: Sat Sep 15, 2007 1:21 am Post subject: |
|
|
| e_boris wrote: | Thanks kururin.
Currently I am testing on a PSP1006 (the Fat one) with CFW3.52M33-4. So the usb mass storage pid may not be the problem.
So what is CFW SDK? is it included in PSPSDK? I can not found the GetModel function or kuKernelLoadModule by search the PSPSDK header files.
Or, I need my PSPSDK package to be updated? |
Download 3.60 SDK cfw, and there you have it. It is a set of includes and libs with some functions that may be interesting to develop in 3.XX, although the function that lets to get the model (fat or slim) from user mode is only included since 3.60. |
|
| Back to top |
|
 |
e_boris
Joined: 19 May 2007 Posts: 25
|
Posted: Sun Sep 16, 2007 12:43 am Post subject: |
|
|
| Quote: | | Download 3.60 SDK cfw |
where can I find this? Guess what does google tells me of this keywords, it is this page.
Also,
I am trying the way like KeyCleaner does, I am wondering how to generate the file "IdStorage.S"? I succeeded in compiling the "idstorage.prx", but find no IdStorage.S is generated. (I deleted the IdStorage.S before).
If I create the prx of my own, Can I generate the *.S file based on *.exp or I have to manually filll up these entrypoint addresses? |
|
| Back to top |
|
 |
gambiting
Joined: 17 Aug 2006 Posts: 154
|
Posted: Sun Sep 16, 2007 3:56 am Post subject: |
|
|
| I have PSP Slim now,and my homebrew works without ANY changes in the code or makefile.Strange? |
|
| Back to top |
|
 |
J.F.
Joined: 22 Feb 2004 Posts: 2906
|
Posted: Sun Sep 16, 2007 7:22 am Post subject: |
|
|
| e_boris wrote: | | Quote: | | Download 3.60 SDK cfw |
where can I find this? Guess what does google tells me of this keywords, it is this page. |
It's in the 3.60 M33 installer package.
http://m-33.narod.ru/
| Quote: | Also,
I am trying the way like KeyCleaner does, I am wondering how to generate the file "IdStorage.S"? I succeeded in compiling the "idstorage.prx", but find no IdStorage.S is generated. (I deleted the IdStorage.S before).
If I create the prx of my own, Can I generate the *.S file based on *.exp or I have to manually filll up these entrypoint addresses? |
"psp-build-exports -s myprxname.exp" |
|
| Back to top |
|
 |
e_boris
Joined: 19 May 2007 Posts: 25
|
Posted: Mon Sep 17, 2007 11:41 pm Post subject: |
|
|
Thanks J.F. psp-build-exports is pretty cool.
The USB problem is fixed by copy usbstorms.prx and usbstorboot.prx to memory stick so that I can load and start it on MS. and I found both 0x1c8 and 0x2d2 can be used to active the USB mass storage connection. I did not found any difference. |
|
| Back to top |
|
 |
e_boris
Joined: 19 May 2007 Posts: 25
|
Posted: Mon Sep 17, 2007 11:54 pm Post subject: pspDebugInstallErrorHandler problem pops |
|
|
I found linking pspDebugInstallErrorHandler will also cause PBP to be refused by XMB for lanuch in 3.xx mode.
I try to move pspDebugInstallErrorHandler to the kernel PRX. But PRX failed in compiling:
| Code: | d:/psp_dev/PSPSDK/pspdev/psp/sdk/lib\libpspdebug.a(pspDebugScreenInit.o): In function `pspDebugScreenInitEx':
/home/psptoolchain/build/pspsdk/src/debug/scr_printf.c(138) : undefined reference to `sceGeEdramGetAddr'
d:/psp_dev/PSPSDK/pspdev/psp/sdk/lib\libpspdebug.a(pspDebugScreenPrintf.o): In function `pspDebugScreenPrintf':
/home/psptoolchain/build/pspsdk/src/debug/scr_printf.c(389) : undefined reference to `vsnprintf'
|
Then I tried remove USE_KERNEL_LIBC=1 and USE_KERNEL_LIBS=1 in PRX'ss makefile. It make compile satisified. But makes pspSdkLoadStartModule("kernel_functions_wrapper.prx", PSP_MEMORY_PARTITION_KERNEL) failed.
Finally, I wrap sceKernelRegisterDefaultExceptionHandler directly in PRX and call it in the main PBP. The psp stoned after I making some exception. Yes, I noticed the sceKernelRegisterDefaultExceptionHandler requires a difference type of callback function.
I make exception by mis-aligned pointer access like:
| Code: | char a[8];
*((DWORD*)&a[1]) = 0;
|
in FW150, the exception can be catched by pspDebugInstallErrorHandler.
Is there any other way to setup exception handler on FW3.xx?? |
|
| Back to top |
|
 |
psp.padawan
Joined: 12 Nov 2007 Posts: 10
|
Posted: Wed Nov 14, 2007 9:59 pm Post subject: |
|
|
| kururin wrote: | | e_boris wrote: | Fanjita:
Can network initialization done with all user mode functions? My calling sequence is like:
| Code: |
....
//Kernel Mode Initialization calling in kernel thread
pspKernelSetKernelPC();
pspSdkInstallNoDeviceCheckPatch();
pspSdkInstallNoPlainModuleCheckPatch();
pspSdkInstallKernelLoadModulePatch();
....
//calling in kernel thread (I found this call fails in user mode thread)
pspSdkLoadInetModules
....
//then call in user mode thread (this must be in user mode to avoid dynamic IP configuation problem)
if(0==pspSdkInetInit())
{
if(sceNetApctlConnect(*((int*)argp))==0)
{
int timeout = ((int*)argp)[1];
int state=0;
while(timeout > 100)
{
if(0!=sceNetApctlGetState(&state))
{ _CheckPoint;
break;
}
if(state==4)
return 1;
rts::Sleep(100);
timeout-=100;
}
}
else _CheckPoint;
}
else _CheckPoint;
.....
// Then go socket codes
.....
|
Is there any other alternative calling sequence using user mode functions only??? |
DO NOT USE the module patch functions in 3.XX. |
Hello, can I ask what effect the module patch functions have on 3xx kernel PRXs? |
|
| Back to top |
|
 |
J.F.
Joined: 22 Feb 2004 Posts: 2906
|
Posted: Fri Dec 07, 2007 8:12 pm Post subject: Re: pspDebugInstallErrorHandler problem pops |
|
|
| e_boris wrote: | I found linking pspDebugInstallErrorHandler will also cause PBP to be refused by XMB for lanuch in 3.xx mode.
I try to move pspDebugInstallErrorHandler to the kernel PRX. But PRX failed in compiling:
| Code: | d:/psp_dev/PSPSDK/pspdev/psp/sdk/lib\libpspdebug.a(pspDebugScreenInit.o): In function `pspDebugScreenInitEx':
/home/psptoolchain/build/pspsdk/src/debug/scr_printf.c(138) : undefined reference to `sceGeEdramGetAddr'
d:/psp_dev/PSPSDK/pspdev/psp/sdk/lib\libpspdebug.a(pspDebugScreenPrintf.o): In function `pspDebugScreenPrintf':
/home/psptoolchain/build/pspsdk/src/debug/scr_printf.c(389) : undefined reference to `vsnprintf'
|
Then I tried remove USE_KERNEL_LIBC=1 and USE_KERNEL_LIBS=1 in PRX'ss makefile. It make compile satisified. But makes pspSdkLoadStartModule("kernel_functions_wrapper.prx", PSP_MEMORY_PARTITION_KERNEL) failed.
Finally, I wrap sceKernelRegisterDefaultExceptionHandler directly in PRX and call it in the main PBP. The psp stoned after I making some exception. Yes, I noticed the sceKernelRegisterDefaultExceptionHandler requires a difference type of callback function.
I make exception by mis-aligned pointer access like:
| Code: | char a[8];
*((DWORD*)&a[1]) = 0;
|
in FW150, the exception can be catched by pspDebugInstallErrorHandler.
Is there any other way to setup exception handler on FW3.xx?? |
Has anything been found on this? |
|
| Back to top |
|
 |
moonlight
Joined: 26 Oct 2005 Posts: 567
|
Posted: Fri Dec 07, 2007 9:08 pm Post subject: |
|
|
| psp.padawan wrote: | | kururin wrote: | | e_boris wrote: | Fanjita:
Can network initialization done with all user mode functions? My calling sequence is like:
| Code: |
....
//Kernel Mode Initialization calling in kernel thread
pspKernelSetKernelPC();
pspSdkInstallNoDeviceCheckPatch();
pspSdkInstallNoPlainModuleCheckPatch();
pspSdkInstallKernelLoadModulePatch();
....
//calling in kernel thread (I found this call fails in user mode thread)
pspSdkLoadInetModules
....
//then call in user mode thread (this must be in user mode to avoid dynamic IP configuation problem)
if(0==pspSdkInetInit())
{
if(sceNetApctlConnect(*((int*)argp))==0)
{
int timeout = ((int*)argp)[1];
int state=0;
while(timeout > 100)
{
if(0!=sceNetApctlGetState(&state))
{ _CheckPoint;
break;
}
if(state==4)
return 1;
rts::Sleep(100);
timeout-=100;
}
}
else _CheckPoint;
}
else _CheckPoint;
.....
// Then go socket codes
.....
|
Is there any other alternative calling sequence using user mode functions only??? |
DO NOT USE the module patch functions in 3.XX. |
Hello, can I ask what effect the module patch functions have on 3xx kernel PRXs? |
You may ending destroying instructions that shouldn't be destroyed.
Doing the patch itself is also stupid, as it is not needed. |
|
| Back to top |
|
 |
|