掌叔
2009-02-10 10:22:02
摘自:[url]http://www.iacger.com[/url]
作者:newcreat
3.xx固件要求你的自制软件以prx格式运行。要得到这种格式,需要如下基本步骤:
1. 修改你的Makefile - 你需要添加如下语句至Makefile以编译prx(在 include $(PSPSDK)/lib/build.mak 这一行前):
引用:
BUILD_PRX = 1
PSP_FW_VERSION = 371
2. 设置你的软件为用户模式 - 自制软件需以用户模式启动。要达此目的,将PSP_MODULE_INFO 中的第2个参数改为 0。大多数软件还需要增加堆栈(heap)大小。堆栈大小是指malloc可用的内存量。我自己设为20mb。以下代码应置于你自己的源代码之前(通常是 main.c):
引用:
PSP_MODULE_INFO("My Homebrew", 0, 1, 0);
PSP_HEAP_SIZE_KB(20480);
或者你可以用PSP_HEAP_SIZE_MAX();前提是你用的toolchain是在2007年9月30日以后编译的(修订号2321)。它将尽可能分配最大的堆栈。请注意要使用此方法你需要重新编译整个toolchain(或者至少pspsdk和newlib),否则你的软件会因Exception - Bus错误(数据)崩溃。
3. 尝试运行你的程序 - 你现在应该能够以通常方式编译程序并覆盖原有的eboot.pbp。3.xx固件不适用kxploit或者%文件夹。如果你从psplink运行你的程序,你需要运行prx文件而不是elf文件,否则无法运行。到了这一步你的自制软件应能正常运行,除非你的代码有核心模式的调用。如果代码有核心调用,启动程序会导致0x8002013C错误。别慌,看第4步。如果你的程序运行没问题,那好,跳过第4步。
4. 找到并处理的你的核心调用 - 你需要了解什么是核心调用,什么不是。你可用 prxtool -f
引用:
$ prxtool -f project.prx
... output left out (it's a lot of output) ...
Import 9, Name UtilsForUser, Functions 1, Variables 0, flags 40010000
Functions:
0x79D1C3FA [0x0008CF34] - UtilsForUser_79D1C3FA
Import 10, Name LoadExecForUser, Functions 2, Variables 0, flags 40010000
Functions:
0x05572A5F [0x0008CF3C] - LoadExecForUser_05572A5F
0x4AC57943 [0x0008CF44] - LoadExecForUser_4AC57943
Import 11, Name IoFileMgrForKernel, Functions 1, Variables 0, flags 00010000
Functions:
0x411106BA [0x0008CF4C] - IoFileMgrForKernel_411106BA
Done
查看上述输出你会发现有一个导入称为 IoFileMgrForKernel。该导入有一个函数。参考下页:
[url]http://silverspring.lan.st/1.5x/kd/.[/url]
在该页搜索你会发现0x411106BA匹配函数sceIoGetThreadCwd。你现在可以搜索该函数并有两个选项:
(a) 使用用户模式代码替换核心调用,或者
(b) 将核心调用移入一个核心模式的prx并在程序中载入该核心模式prx。
选项A是我推荐的方案,除非你必须使用核心调用。
b. 出现0x8002013C的解决方式,出现这个问题是因为用户态程序调用了核心函数,解决这个的办法是采用m33sdk,众所周之3.71版后的自制系统都提供了m33sdk,里面有函数可以加载核心的prx来解决。
首先确认上面的函数在哪个prx里,用下面的方式加载那个prx即可。下面是核心调用的速查
[url]http://www.iacger.com/topoc/pspdoc/psplibdoc.xml[/url]
SceUID kuKernelLoadModule(const char *path, int flags, SceKernelLMOption *option);
sceKernelStartModule(kuKernelLoadModule("xxx.prx", 0, 0), 0, 0, 0 0);
附:401M33 SDK下载