安全出口 → http://www.playstation.jp/psp/

 非常出口 → http://www.playstation.jp/psp/

 To sacrifice yourself. Experimental. Extremely dangerous.
 No warranty. Use on your own risk and responsibility.
 Anything may happen. We recommend you to avoid seeing/downloading/using this.
 Emergency exit -> http://www.playstation.jp/psp/
 * this CAUTION copy from SEC(nem) :p

groepaz wrote:
there is no "mix". its just about programming the 1.0 ipl into another firmware, which is pretty much pointless other than for seeing it actually works (or not). merely an interisting experiment for people who know what they are doing.
if you dont know exactly what it does and what you could use it for by looking at the posted code, forget it. you dont need it at all.

Don't use "IPL Data" from "ridge racers's kbooti.bin", it will brick your PSP !!!

// most of code from moonlight & PspPet

#include <pspkernel.h>
#include <psptypes.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <pspdebug.h>

PSP_MODULE_INFO("FW100_ipl_update", 0x1000, 1, 1);



#define printf pspDebugScreenPrintf

int (* sceIplUpdateClearIpl)(void);
int (* sceIplUpdateSetIpl)(void);

/*** This function from PspPet PSARDUMPER ***/
static u32 FindProc(const char* szMod, const char* szLib, u32 nid)
    SceModule* modP = sceKernelFindModuleByName(szMod);
    if (modP == NULL)
        printf("Failed to find mod '%s'\n", szMod);
        return 0;
    SceLibraryEntryTable* entP = (SceLibraryEntryTable*)modP->ent_top;
    while ((u32)entP < ((u32)modP->ent_top + modP->ent_size))
        if (entP->libname != NULL && strcmp(entP->libname, szLib) == 0)
            // found lib
            int i;
            int count = entP->stubcount + entP->vstubcount;
            u32* nidtable = (u32*)entP->entrytable;
            for (i = 0; i < count; i++)
                if (nidtable[i] == nid)
                    u32 procAddr = nidtable[count+i];
                    printf("entry found: '%s' '%s' = $%x\n", szMod, szLib, (int)procAddr);
                    return procAddr;
            printf("Found mod '%s' and lib '%s' but not nid=$%x\n", szMod, szLib, nid);
            return 0;
    printf("Found mod '%s' but not lib '%s'\n", szMod, szLib);
    return 0;

void ErrorExit(char *error)
    printf("%s\n", error);
    sceKernelDelayThread(30 * 1000 * 1000);

int main()

    SceKernelModuleInfo modinfo;
    u32 base;
    SceUID fd;
    SceUID mod;

    mod = sceKernelLoadModule("ms0:/UPDATE/FW150_ipl_update.prx", 0, NULL);
    if (mod < 0)
        ErrorExit("Error loading update module.\n");

    if (sceKernelQueryModuleInfo(mod, &modinfo) < 0)
        ErrorExit("Cannot query module info.\n");

    base = modinfo.text_addr;
    printf("modinfo.text_addr : %.8X\n", modinfo.text_addr);

        fd = sceIoOpen("ms0:/UPDATE/FW100_ipl.bin", PSP_O_RDONLY, 0777);
        if (fd < 0)
            ErrorExit("Cannot read IPL Data\n");
        printf("Reading IPL Data...\n\n");
        sceIoRead(fd, (void *)(base+0x900), 0x37000);

        fd = sceIoOpen("ms0:/UPDATE/FW100_ipl_update.elf", PSP_O_WRONLY | PSP_O_CREAT | PSP_O_TRUNC, 0777);
        if (fd < 0)
            ErrorExit("Cannot save ELF\n");
        printf("Writing ELF...\n\n");
        sceIoWrite(fd, (void *)(base), 0x40000);

    mod = sceKernelStartModule(mod, 0, NULL, NULL, NULL);
    if (mod < 0)
        ErrorExit("Error Start update module.\n");
    sceIplUpdateClearIpl = (void *)FindProc("IplUpdater", "sceIplUpdate_driver", 0x26093B04);
    sceIplUpdateSetIpl = (void *)FindProc("IplUpdater", "sceIplUpdate_driver", 0xEE7EB563);

    printf("start sceIplUpdateClearIpl & sceIplUpdateSetIpl\n");

    ErrorExit("Finished. Exiting in 30 seconds\n");

    return 0;

i test it with my FW1.50PSP, it's work
& find 1.00IPL can work with FW1.50 :D
now my psp is FW1.50 + 1.00IPL :P

more information
About the 1.00 downgrade idea

moonlight wrote:
Also, the 1.50 updater call to these functions from iplupdate.prx:

sceIplUpdateClearIpl() -- no parameters, it erases the blocks of the ipl.

sceIplUpdateSetIpl() -- no parameters. it writes the 1.50 ipl which is embedded in the own iplupdater.prx (contrary to the +2.00 updaters, where the ipl is in the psar)

The iplupdater also exports sceIplUpdateUpdateIpl, but the updater doesn't import it, and it seems that it's not called, it doesn't seem to be an export available for vsh mode. (maybe it's called inside the iplupdater, but i haven't seen that call). Looking at the dissasembly, that function doesn't write to the flash, not at least using the sceNand functions.

Another difference between the 1.50 updater and the 2.XX updaters, is that the iplupdater from 1.50 doesn't use any verification function from sceNand, like sceNandVerifyEcc, etc. (I don't know if it does another kind of verification).

In theory, and only in theory, we can use the following procedure for a 1.00 downgrader:

- Extract iplupdater.prx and flashfmt.prx from the 1.50 update.
- Load them, and hack in ram the iplupdater.prx writing the 1.00 ipl on its "iplbuffer", which is easy to locate looking at the disassembly.
- call sceLflashFatfmtStartFatfmt
- Write the flash0 files of an 1.00 dump using sceIo
- call sceIplUpdateClearIpl
- call sceIplUpdateSetIpl

Using sony code to write the ipl and formatting the flash prior to writing the files should be safer, but it won't be me who tries it :)


Post a Comment

<< Home