├── tff ├── diskio.c ├── readme.txt ├── integer.h └── diskio.h ├── IPL_SDK ├── psp_uart.c ├── lcdc.h ├── kprintf.h ├── cache.h ├── kirk.h ├── interrupt.h ├── sysreg.h ├── memstk.h ├── psp_uart.h ├── psp_nand.h ├── preipl.h ├── interrupt.c ├── sysreg.c ├── cache.c ├── patch.h ├── kirk.c ├── crt0_bin.S ├── build_bin.mak ├── crt0_exp.S ├── lcdc.c ├── crt0_ipl.S ├── crt0_ms.S ├── crt0_nand.S ├── psp_nand.c ├── kprintf.c ├── syscon.c ├── memstkro.c ├── fatload.c └── pspipl.x ├── MS_NORMAL ├── memstk.h ├── config.h ├── preipl.h ├── Makefile ├── readme.txt ├── iplboot.c ├── memstk.c └── ipl_ms.x ├── LIBC ├── memset.c ├── memcmp.c └── memcpy.c ├── ML_DDRDUMPER ├── fatload.h ├── Makefile ├── main.c └── fatload.c ├── ML_BIOS_DUMPER ├── fatload.h ├── Makefile ├── main.c ├── iplload.c └── fatload.c ├── MS_BIOS_DUMPER ├── fatload.h ├── Makefile ├── main.c ├── iplload.c └── fatload.c ├── ML_MAIN_BIN_DUMPER ├── fatload.h ├── readme.txt ├── Makefile ├── iplload.c ├── main.c └── fatload.c ├── ML_RECOVERY_LOADER ├── fatload.h ├── readme.txt ├── Makefile ├── main.c ├── fatload.c └── payloadipl.x ├── MS_MULTI_LOADER ├── fatload.h ├── config.h ├── preipl.h ├── Makefile ├── readme.txt ├── iplboot.c ├── fatload.c └── ipl_mload.x ├── ML_FLASH_LED ├── Makefile ├── main.c └── payloadipl.x ├── readme.txt └── PANDORA └── readme.txt /tff/diskio.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathieulh/PSP_IPL_SDK/HEAD/tff/diskio.c -------------------------------------------------------------------------------- /IPL_SDK/psp_uart.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathieulh/PSP_IPL_SDK/HEAD/IPL_SDK/psp_uart.c -------------------------------------------------------------------------------- /MS_NORMAL/memstk.h: -------------------------------------------------------------------------------- 1 | int pspMsInit(void); 2 | int pspMsReadSector(int sector, void *addr); 3 | -------------------------------------------------------------------------------- /IPL_SDK/lcdc.h: -------------------------------------------------------------------------------- 1 | #ifndef __SYSREG_H__ 2 | #define __SYSREG_H__ 3 | 4 | u32 pspLcdcInit(void *frame_buffer); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /IPL_SDK/kprintf.h: -------------------------------------------------------------------------------- 1 | #ifndef __KPRINTF_H__ 2 | #define __KPRINTF_H__ 3 | 4 | void Kprintf(const char *text,...); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /IPL_SDK/cache.h: -------------------------------------------------------------------------------- 1 | #ifndef __PSP_CACHE_H__ 2 | #define __PSP_CACHE_H__ 3 | 4 | void pspClearIcache(void); 5 | void pspClearDcache(void); 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /IPL_SDK/kirk.h: -------------------------------------------------------------------------------- 1 | #ifndef __PSP_KIRK_H__ 2 | #define __PSP_KIRK_H__ 3 | 4 | int pspKirkProc(void *dst,u32 dsize,void *src,u32 ssize,u32 cmd); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /IPL_SDK/interrupt.h: -------------------------------------------------------------------------------- 1 | #ifndef __PSP_INTERRUPT_H__ 2 | #define __PSP_INTERRUPT_H__ 3 | 4 | u32 irq_disable(void); 5 | void irq_resume(u32 intval); 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /IPL_SDK/sysreg.h: -------------------------------------------------------------------------------- 1 | #ifndef __SYSREG_H__ 2 | #define __SYSREG_H__ 3 | u32 sceSysregSpiClkSelect(int a1,int a2); 4 | u32 sceSysregSpiClkEnable(u32 bit); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /LIBC/memset.c: -------------------------------------------------------------------------------- 1 | void *memset(void *dst,int code,int size) 2 | { 3 | unsigned char *p1 = (unsigned char *)dst; 4 | while(size--) 5 | { 6 | *p1++ = code; 7 | } 8 | return p1; 9 | } 10 | -------------------------------------------------------------------------------- /IPL_SDK/memstk.h: -------------------------------------------------------------------------------- 1 | #ifndef __PSP_MS__ 2 | #define __PSP_MS__ 3 | 4 | int pspMsInit(void); 5 | int pspMsReadSector(int sector, void *addr); 6 | int pspMsWriteSector(int sector, void *addr); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /LIBC/memcmp.c: -------------------------------------------------------------------------------- 1 | int memcmp(const char *p1,const char *p2,int size) 2 | { 3 | char diff; 4 | while(size--) 5 | { 6 | diff = *p1++ - *p2++; 7 | if(diff) return diff; 8 | } 9 | return 0; 10 | } 11 | -------------------------------------------------------------------------------- /tff/readme.txt: -------------------------------------------------------------------------------- 1 | ChaN's open source FAT File System Module. 2 | 3 | http://elm-chan.org/ 4 | http://elm-chan.org/fsw/ff/00index_e.html 5 | 6 | The FAT32 are supported,but long filename are not supported. 7 | 8 | -------------------------------------------------------------------------------- /ML_DDRDUMPER/fatload.h: -------------------------------------------------------------------------------- 1 | int ms_load_file(const char *path,void *top_addr); 2 | int ms_save_file(const char *path,const void *data,int size); 3 | void *ms_load_ipl(const char *path); 4 | 5 | int ms_fat_init(void); 6 | 7 | -------------------------------------------------------------------------------- /IPL_SDK/psp_uart.h: -------------------------------------------------------------------------------- 1 | #ifndef __PSP_UART_H__ 2 | #define __PSP_UART_H__ 3 | 4 | void psp_uart_init(int bps); 5 | void psp_uart_putc(int txd); 6 | int psp_uart_getc(void); 7 | void uart_dbg_putc(int arg1,int code); 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /IPL_SDK/psp_nand.h: -------------------------------------------------------------------------------- 1 | #ifndef __PSP_NAND_H__ 2 | #define __PSP_NAND_H__ 3 | 4 | int pspNandReadSector(int sector,u32 *databuf,u32 *extrabuf); 5 | int pspNandReadIPLFat(void); 6 | int pspNandReadIPLBlock(int block,u32 *databuf); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /LIBC/memcpy.c: -------------------------------------------------------------------------------- 1 | void *memcpy(void *dst,void *src,int size) 2 | { 3 | unsigned char *p1 = (unsigned char *)dst; 4 | unsigned char *p2 = (unsigned char *)src; 5 | while(size--) 6 | { 7 | *p1++ = *p2++; 8 | } 9 | return p1; 10 | } 11 | -------------------------------------------------------------------------------- /ML_BIOS_DUMPER/fatload.h: -------------------------------------------------------------------------------- 1 | int ms_load_file(const char *path,void *top_addr,int maxsize); 2 | int ms_save_file(const char *path,const void *data,int size); 3 | 4 | void *ms_load_ipl(const char *path); 5 | void *ms_load_bootloader(const char *path); 6 | 7 | int ms_fat_init(void); 8 | 9 | -------------------------------------------------------------------------------- /MS_BIOS_DUMPER/fatload.h: -------------------------------------------------------------------------------- 1 | int ms_load_file(const char *path,void *top_addr,int maxsize); 2 | int ms_save_file(const char *path,const void *data,int size); 3 | 4 | void *ms_load_ipl(const char *path); 5 | void *ms_load_bootloader(const char *path); 6 | 7 | int ms_fat_init(void); 8 | 9 | -------------------------------------------------------------------------------- /ML_MAIN_BIN_DUMPER/fatload.h: -------------------------------------------------------------------------------- 1 | int ms_load_file(const char *path,void *top_addr,int maxsize); 2 | int ms_save_file(const char *path,const void *data,int size); 3 | 4 | void *ms_load_ipl(const char *path); 5 | void *ms_load_bootloader(const char *path); 6 | 7 | int ms_fat_init(void); 8 | 9 | -------------------------------------------------------------------------------- /ML_RECOVERY_LOADER/fatload.h: -------------------------------------------------------------------------------- 1 | int ms_load_file(const char *path,void *top_addr,int maxsize); 2 | int ms_save_file(const char *path,const void *data,int size); 3 | 4 | void *ms_load_ipl(const char *path); 5 | void *ms_load_bootloader(const char *path); 6 | 7 | int ms_fat_init(void); 8 | 9 | -------------------------------------------------------------------------------- /MS_MULTI_LOADER/fatload.h: -------------------------------------------------------------------------------- 1 | int ms_load_file(const char *path,void *top_addr,int maxsize); 2 | int ms_save_file(const char *path,const void *data,int size); 3 | 4 | void *ms_load_ipl(const char *path); 5 | void *ms_load_bootloader(const char *path); 6 | 7 | int ms_fat_init(void); 8 | 9 | -------------------------------------------------------------------------------- /MS_NORMAL/config.h: -------------------------------------------------------------------------------- 1 | #ifndef __CONFIG_H__ 2 | #define __CONFIG_H__ 3 | /* 4 | IPL exploit BOOT LOADER (MS test ver) 5 | */ 6 | 7 | /**************************************************************************** 8 | CONFIGRATION 9 | ****************************************************************************/ 10 | 11 | // function switch 12 | #define UART_MESSAGE 1 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /MS_MULTI_LOADER/config.h: -------------------------------------------------------------------------------- 1 | #ifndef __CONFIG_H__ 2 | #define __CONFIG_H__ 3 | /* 4 | IPL exploit BOOT LOADER (MS test ver) 5 | */ 6 | 7 | /**************************************************************************** 8 | CONFIGRATION 9 | ****************************************************************************/ 10 | 11 | // function switch 12 | #define UART_MESSAGE 1 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /ML_MAIN_BIN_DUMPER/readme.txt: -------------------------------------------------------------------------------- 1 | main.bin dumper. 2 | 3 | 1.copy raw 'encrypted' IPL file to "ms0:./ipl.bin" 4 | 2.copy "pspboot.bin" to "ms0:/ipl/ipl_up.bin" 5 | 3.install "ipl_ms.bin" multi IPL loader in PSP_IPL_SDK_04 6 | 4.hold LTRG+UP and power on from pandora's battery. 7 | 8 | tested psp_ipl.bin(150) and nandipl_psp1000.bin(371) on PSP-1000. 9 | nandipl_psp2000.bin(371) can't work on PSP-1000. 10 | 11 | -------------------------------------------------------------------------------- /MS_NORMAL/preipl.h: -------------------------------------------------------------------------------- 1 | 2 | // PRE-IPL routine 3 | void (* piplEntry)(void) = (void *)0x80010000; 4 | 5 | void (* piplDcache)(void) = (void *)0x800102d8; 6 | void (* piplIcache)(void) = (void *)0x800102a0; 7 | 8 | int (* piplNandRead)(u32 ppn, void *buf, void *extra) = (void *)0x80010334; 9 | 10 | int (* piplMsInit)(void) = (void *)0x80010240; 11 | int (* piplMsReadIplBlock)(int block, void *addr) = (void *)0x80010248; 12 | 13 | int (* piplDecryptIplBLock)(void *dst,void *src) = (void *)0x80010620; 14 | 15 | -------------------------------------------------------------------------------- /ML_FLASH_LED/Makefile: -------------------------------------------------------------------------------- 1 | TARGET = pspboot 2 | OBJS = \ 3 | ../IPL_SDK/crt0_ipl.o \ 4 | main.c \ 5 | \ 6 | ../IPL_SDK/sysreg.o \ 7 | ../IPL_SDK/syscon.o \ 8 | \ 9 | 10 | INCDIR = ../IPL_SDK ../tff 11 | CFLAGS = -G0 -Wall 12 | CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti 13 | ASFLAGS = $(CFLAGS) 14 | 15 | LIBS = 16 | LIBDIR = 17 | LDFLAGS = -nostartfiles -T payloadipl.x -nostdlib 18 | 19 | PSPSDK=$(shell psp-config --pspsdk-path) 20 | #include $(PSPSDK)/lib/build.mak 21 | include ../IPL_SDK/build_bin.mak 22 | -------------------------------------------------------------------------------- /MS_MULTI_LOADER/preipl.h: -------------------------------------------------------------------------------- 1 | 2 | // PRE-IPL routine 3 | void (* piplEntry)(void) = (void *)0x80010000; 4 | 5 | void (* piplDcache)(void) = (void *)0x800102d8; 6 | void (* piplIcache)(void) = (void *)0x800102a0; 7 | 8 | int (* piplNandRead)(u32 ppn, void *buf, void *extra) = (void *)0x80010334; 9 | 10 | int (* piplMsInit)(void) = (void *)0x80010240; 11 | int (* piplMsReadIplBlock)(int block, void *addr) = (void *)0x80010248; 12 | 13 | int (* piplDecryptIplBLock)(void *dst,void *src) = (void *)0x80010620; 14 | 15 | -------------------------------------------------------------------------------- /IPL_SDK/preipl.h: -------------------------------------------------------------------------------- 1 | #ifndef __PRE_IPL__ 2 | #define __PRE_IPL__ 3 | 4 | // PRE-IPL (BIOS ROM in PSP) routine 5 | void (* piplEntry)(void) = (void *)0x80010000; 6 | 7 | void (* piplDcache)(void) = (void *)0x800102d8; 8 | void (* piplIcache)(void) = (void *)0x800102a0; 9 | 10 | int (* piplNandRead)(u32 ppn, void *buf, void *extra) = (void *)0x80010334; 11 | 12 | int (* piplMsInit)(void) = (void *)0x80010240; 13 | int (* piplMsReadIplBlock)(int block, void *addr) = (void *)0x80010248; 14 | 15 | int (* piplDecryptIplBLock)(void *dst,void *src) = (void *)0x80010620; 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /MS_NORMAL/Makefile: -------------------------------------------------------------------------------- 1 | TARGET = ipl_ms 2 | OBJS = \ 3 | ../IPL_SDK/crt0_ms.o \ 4 | iplboot.o \ 5 | \ 6 | ../IPL_SDK/sysreg.o \ 7 | ../IPL_SDK/syscon.o \ 8 | \ 9 | 10 | # ../IPL_SDK/psp_uart.o \ 11 | # ../IPL_SDK/kprintf.o \ 12 | #\ 13 | 14 | INCDIR = ../IPL_SDK ../tff 15 | CFLAGS = -G0 -Wall 16 | CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti 17 | ASFLAGS = $(CFLAGS) 18 | 19 | LIBS = 20 | LIBDIR = 21 | LDFLAGS = -nostartfiles -T ipl_ms.x -nostdlib 22 | 23 | PSPSDK=$(shell psp-config --pspsdk-path) 24 | #include $(PSPSDK)/lib/build.mak 25 | include ../IPL_SDK/build_bin.mak 26 | -------------------------------------------------------------------------------- /tff/integer.h: -------------------------------------------------------------------------------- 1 | #ifndef _INTEGER 2 | 3 | typedef signed int INT; 4 | typedef unsigned int UINT; 5 | 6 | /* These types are assumed as 8-bit integer */ 7 | typedef signed char CHAR; 8 | typedef unsigned char UCHAR; 9 | typedef unsigned char BYTE; 10 | 11 | /* These types are assumed as 16-bit integer */ 12 | typedef signed short SHORT; 13 | typedef unsigned short USHORT; 14 | typedef unsigned short WORD; 15 | 16 | /* These types are assumed as 32-bit integer */ 17 | typedef signed long LONG; 18 | typedef unsigned long ULONG; 19 | typedef unsigned long DWORD; 20 | 21 | /* Boolean type */ 22 | typedef enum { FALSE = 0, TRUE } BOOL; 23 | 24 | #define _INTEGER 25 | #endif 26 | -------------------------------------------------------------------------------- /IPL_SDK/interrupt.c: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | PSP IPL interrupt controll 3 | ****************************************************************************/ 4 | #include 5 | 6 | u32 irq_disable(void) 7 | { 8 | asm("\n\ 9 | .word 0x70020024;\n\ 10 | .word 0x70000026;\n\ 11 | nop;\n\ 12 | nop;\n\ 13 | nop;\n\ 14 | nop;\n\ 15 | nop;\n\ 16 | nop;\n\ 17 | nop;\n\ 18 | "::); 19 | } 20 | 21 | void irq_resume(u32 intval) 22 | { 23 | asm("\n\ 24 | sync;\n\ 25 | nop;\n\ 26 | sync;\n\ 27 | nop;\n\ 28 | .word 0x70040026;\n\ 29 | nop;\n\ 30 | nop;\n\ 31 | nop;\n\ 32 | nop;\n\ 33 | nop;\n\ 34 | nop;\n\ 35 | nop;\n\ 36 | "::); 37 | } 38 | 39 | -------------------------------------------------------------------------------- /ML_RECOVERY_LOADER/readme.txt: -------------------------------------------------------------------------------- 1 | Pandora's Recovery Menu boot loader for MS MultiLoader 2 | 3 | How to install. 4 | 5 | 0.Do not need re-format and mspformat to normaly case. 6 | 1.insrall recovery firmware by "pandora's Battery Firm. Installer". 7 | 2.move and rename "ms0:/ms_ipl.bin"(padnora's) to "ms0:/ipl/150ex.bin" 8 | 3.copy "pspboot.bin" to "ms0:/ipl/ipl.bin" 9 | 4.install "ms_ipl.bin"(multiLoader) with msinst.exe 10 | 11 | How to use. 12 | 13 | 1.power off the PSP. 14 | 2.Hold LTRG. 15 | 3.insert pandora's battery to boot pandora's recovery menu. 16 | (LTRG off then normal boot) 17 | 18 | Note. 19 | 20 | This tools uses the IPL exploit block of the PANDORA'S BATTERY. 21 | Please check the license and credits in readme of PANDORA'S BATTERY. 22 | 23 | -------------------------------------------------------------------------------- /ML_BIOS_DUMPER/Makefile: -------------------------------------------------------------------------------- 1 | TARGET = pspboot 2 | OBJS = \ 3 | ../IPL_SDK/crt0_ipl.o \ 4 | \ 5 | main.o \ 6 | fatload.o \ 7 | \ 8 | ../IPL_SDK/cache.o \ 9 | ../IPL_SDK/psp_uart.o \ 10 | ../IPL_SDK/sysreg.o \ 11 | ../IPL_SDK/syscon.o \ 12 | ../IPL_SDK/memstk.o \ 13 | ../IPL_SDK/kirk.o \ 14 | ../IPL_SDK/interrupt.o \ 15 | ../IPL_SDK/kprintf.o \ 16 | \ 17 | ../LIBC/memcmp.o \ 18 | ../LIBC/memcpy.o \ 19 | ../LIBC/memset.o \ 20 | \ 21 | ../tff/diskio.o \ 22 | ../tff/tff.o \ 23 | 24 | INCDIR = ../IPL_SDK ../tff 25 | CFLAGS = -G0 -Wall 26 | CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti 27 | ASFLAGS = $(CFLAGS) 28 | 29 | LIBS = 30 | LIBDIR = 31 | LDFLAGS = -nostartfiles -T ../IPL_SDK/pspipl.x -nostdlib 32 | 33 | PSPSDK=$(shell psp-config --pspsdk-path) 34 | #include $(PSPSDK)/lib/build.mak 35 | include ../IPL_SDK/build_bin.mak 36 | -------------------------------------------------------------------------------- /ML_DDRDUMPER/Makefile: -------------------------------------------------------------------------------- 1 | TARGET = pspboot 2 | OBJS = \ 3 | ../IPL_SDK/crt0_ipl.o \ 4 | \ 5 | main.o \ 6 | fatload.o \ 7 | \ 8 | ../IPL_SDK/cache.o \ 9 | ../IPL_SDK/psp_uart.o \ 10 | ../IPL_SDK/sysreg.o \ 11 | ../IPL_SDK/syscon.o \ 12 | ../IPL_SDK/memstk.o \ 13 | ../IPL_SDK/kprintf.o \ 14 | ../IPL_SDK/interrupt.o \ 15 | ../IPL_SDK/kirk.o \ 16 | \ 17 | ../LIBC/memcmp.o \ 18 | ../LIBC/memcpy.o \ 19 | ../LIBC/memset.o \ 20 | \ 21 | ../tff/diskio.o \ 22 | ../tff/tff.o \ 23 | 24 | INCDIR = ../IPL_SDK ../tff 25 | CFLAGS = -G0 -Wall 26 | CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti 27 | ASFLAGS = $(CFLAGS) 28 | 29 | LIBS = 30 | LIBDIR = 31 | LDFLAGS = -nostartfiles -T ../IPL_SDK/pspipl.x -nostdlib 32 | 33 | PSPSDK=$(shell psp-config --pspsdk-path) 34 | #include $(PSPSDK)/lib/build.mak 35 | include ../IPL_SDK/build_bin.mak 36 | -------------------------------------------------------------------------------- /MS_BIOS_DUMPER/Makefile: -------------------------------------------------------------------------------- 1 | TARGET = ipl_ms 2 | OBJS = \ 3 | ../IPL_SDK/crt0_ms.o \ 4 | \ 5 | main.o \ 6 | fatload.o \ 7 | \ 8 | ../IPL_SDK/cache.o \ 9 | ../IPL_SDK/psp_uart.o \ 10 | ../IPL_SDK/sysreg.o \ 11 | ../IPL_SDK/syscon.o \ 12 | ../IPL_SDK/memstk.o \ 13 | ../IPL_SDK/kirk.o \ 14 | ../IPL_SDK/interrupt.o \ 15 | ../IPL_SDK/kprintf.o \ 16 | \ 17 | ../LIBC/memcmp.o \ 18 | ../LIBC/memcpy.o \ 19 | ../LIBC/memset.o \ 20 | \ 21 | ../tff/diskio.o \ 22 | ../tff/tff.o \ 23 | 24 | INCDIR = ../IPL_SDK ../tff 25 | CFLAGS = -O2 -G0 -Wall 26 | CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti 27 | ASFLAGS = $(CFLAGS) 28 | 29 | LIBS = 30 | LIBDIR = 31 | LDFLAGS = -nostartfiles -T ../IPL_SDK/pspipl.x -nostdlib 32 | 33 | PSPSDK=$(shell psp-config --pspsdk-path) 34 | #include $(PSPSDK)/lib/build.mak 35 | include ../IPL_SDK/build_bin.mak 36 | -------------------------------------------------------------------------------- /MS_MULTI_LOADER/Makefile: -------------------------------------------------------------------------------- 1 | TARGET = ipl_ms 2 | OBJS = \ 3 | ../IPL_SDK/crt0_ms.o \ 4 | \ 5 | iplboot.o \ 6 | fatload.o \ 7 | \ 8 | ../IPL_SDK/cache.o \ 9 | ../IPL_SDK/psp_uart.o \ 10 | ../IPL_SDK/sysreg.o \ 11 | ../IPL_SDK/syscon.o \ 12 | ../IPL_SDK/memstkro.o \ 13 | ../IPL_SDK/kprintf.o \ 14 | ../IPL_SDK/kirk.o \ 15 | ../IPL_SDK/interrupt.o \ 16 | \ 17 | ../LIBC/memcmp.o \ 18 | ../LIBC/memcpy.o \ 19 | ../LIBC/memset.o \ 20 | ../tff/diskio.o \ 21 | ../tff/tff.o \ 22 | 23 | INCDIR = ../IPL_SDK ../tff_min ../tff 24 | CFLAGS = -G0 -Wall 25 | CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti 26 | ASFLAGS = $(CFLAGS) 27 | 28 | LIBS = 29 | LIBDIR = 30 | LDFLAGS = -nostartfiles -T ipl_mload.x -nostdlib 31 | 32 | PSPSDK=$(shell psp-config --pspsdk-path) 33 | #include $(PSPSDK)/lib/build.mak 34 | include ../IPL_SDK/build_bin.mak 35 | -------------------------------------------------------------------------------- /ML_RECOVERY_LOADER/Makefile: -------------------------------------------------------------------------------- 1 | TARGET = pspboot 2 | OBJS = \ 3 | ../IPL_SDK/crt0_ipl.o \ 4 | \ 5 | main.o \ 6 | fatload.o \ 7 | \ 8 | ../IPL_SDK/cache.o \ 9 | ../IPL_SDK/psp_uart.o \ 10 | ../IPL_SDK/sysreg.o \ 11 | ../IPL_SDK/syscon.o \ 12 | ../IPL_SDK/memstkro.o \ 13 | ../IPL_SDK/kprintf.o \ 14 | ../IPL_SDK/interrupt.o \ 15 | ../IPL_SDK/kirk.o \ 16 | ../IPL_SDK/psp_nand.o \ 17 | \ 18 | ../LIBC/memcmp.o \ 19 | ../LIBC/memcpy.o \ 20 | ../LIBC/memset.o \ 21 | \ 22 | ../tff/diskio.o \ 23 | ../tff/tff.o \ 24 | 25 | INCDIR = ../IPL_SDK ../tff 26 | CFLAGS = -G0 -Wall 27 | CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti 28 | ASFLAGS = $(CFLAGS) 29 | 30 | LIBS = 31 | LIBDIR = 32 | LDFLAGS = -nostartfiles -T payloadipl.x -nostdlib 33 | 34 | PSPSDK=$(shell psp-config --pspsdk-path) 35 | #include $(PSPSDK)/lib/build.mak 36 | include ../IPL_SDK/build_bin.mak 37 | -------------------------------------------------------------------------------- /IPL_SDK/sysreg.c: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | PSP IPL SYSREG Driver 3 | ****************************************************************************/ 4 | #include 5 | #include "kprintf.h" 6 | 7 | #define REG32(ADDR) (*(vu32*)(ADDR)) 8 | #define SYNC() asm(" sync; nop"::) 9 | 10 | u32 sceSysregSpiClkSelect(int a1,int a2) 11 | { 12 | u32 shift; 13 | u32 in,out; 14 | 15 | shift = a1<<2; 16 | 17 | in = REG32(0xbc100064); 18 | out = in & ~(7<shift) & 7; 22 | } 23 | 24 | u32 sceSysregSpiClkEnable(u32 bit) 25 | { 26 | u32 in , out; 27 | u32 mask = (1< 6 | 7 | #include "syscon.h" 8 | #include "patch.h" 9 | 10 | /**************************************************************************** 11 | title message for header 12 | ****************************************************************************/ 13 | const char __title__[] __attribute__ (( section (".init"))) = "MS-MultiLoader Example"; 14 | 15 | /**************************************************************************** 16 | entry point 17 | ****************************************************************************/ 18 | int main(void) 19 | { 20 | u32 sts; 21 | 22 | // init I/O 23 | pspSyscon_init(); 24 | pspSysconCtrlLED(0,1); 25 | pspSysconCtrlLED(1,1); 26 | pspSysconCtrlMsPower(1); 27 | 28 | // flash LED 29 | sts=pspSysconNop(); 30 | while(1) 31 | { 32 | // both LED flash 33 | REG32(0xbe24000c) = 0xC0; 34 | Syscon_wait(250000/4); 35 | REG32(0xbe240008) = 0xC0; 36 | Syscon_wait(250000/4); 37 | 38 | // POWER SW sense 39 | if( !(sts&SYSCON_STS_POWER_SW_ON) && ((sts=pspSysconNop()) & SYSCON_STS_POWER_SW_ON) ) 40 | { 41 | // power off 42 | pspSysconPowerStandby(); 43 | } 44 | } 45 | 46 | return 0; 47 | } 48 | -------------------------------------------------------------------------------- /IPL_SDK/patch.h: -------------------------------------------------------------------------------- 1 | #ifndef __PSP_PATCH_H__ 2 | #define __PSP_PATCH_H__ 3 | 4 | #define REG32(ADDR) (*(vu32*)(ADDR)) 5 | 6 | #define MIPS_LUI(R,IMM) 0x3c000000|(R<<16)|((unsigned int)(IMM)&0xffff) 7 | 8 | #define MIPS_ADDI(RT,RS,IMM) (0x20000000|(RS<<21)|(RT<<16)|((unsigned int)(IMM)&0xffff)) 9 | #define MIPS_ADDIU(RT,RS,IMM) (0x24000000|(RS<<21)|(RT<<16)|((unsigned int)(IMM)&0xffff)) 10 | #define MIPS_ANDI(RT,RS,IMM) (0x30000000|(RS<<21)|(RT<<16)|((unsigned int)(IMM)&0xffff)) 11 | #define MIPS_ORI(RT,RS,IMM) (0x34000000|(RS<<21)|(RT<<16)|((unsigned int)(IMM)&0xffff)) 12 | #define MIPS_NOP 0x00000000 13 | #define MIPS_J(ADDR) (0x08000000 + ((((unsigned int)(ADDR))&0x0ffffffc)>>2)) 14 | #define MIPS_JR(R) (0x00000008 + ((R)<<21)) 15 | #define MIPS_JAL(ADDR) (0x0c000000 + (((unsigned int)(ADDR)>>2)&0x03ffffff)) 16 | #define MIPS_SYSCALL(NUM) (0x0000000C+((NUM)<<6)) 17 | 18 | #define MIPS_AND(RD,RS,RT) (0x00000024|(RD<<11)|(RT<<16)|(RS<<21)) 19 | #define MIPS_ADD(RD,RS,RT) (0x00000020|(RD<<11)|(RT<<16)|(RS<<21)) 20 | #define MIPS_ADDU(RD,RS,RT) (0x00000021|(RD<<11)|(RT<<16)|(RS<<21)) 21 | 22 | #define MIPS_SW(RT,BASE,OFFSET) (0xac000000|(BASE<<21)|(RT<<16)|(OFFSET&0xFFFF)) 23 | #define MIPS_SH(RT,BASE,OFFSET) (0xa4000000|(BASE<<21)|(RT<<16)|(OFFSET&0xFFFF)) 24 | 25 | #define SYNC() asm(" sync; nop"::) 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /MS_BIOS_DUMPER/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | PSP IPL main.bin dumper 3 | */ 4 | 5 | #include 6 | 7 | #include "psp_uart.h" 8 | #include "kprintf.h" 9 | #include "patch.h" 10 | #include "syscon.h" 11 | #include "cache.h" 12 | 13 | #include "memstk.h" 14 | #include "tff.h" /* Tiny-FatFs declarations */ 15 | #include "fatload.h" 16 | 17 | #define BIOS_FILE_NAME "/psp_bios.bin" 18 | 19 | /**************************************************************************** 20 | title message for header 21 | ****************************************************************************/ 22 | //const char __title__[] __attribute__ (( section (".init"))) = "PSP BIOS DUMPER"; 23 | 24 | /**************************************************************************** 25 | reset PSP 26 | ****************************************************************************/ 27 | void entry(void) 28 | { 29 | // reset reboot 30 | Kprintf("Reset PSP\n\n"); 31 | pspSysconResetDevice(1); 32 | while(1); 33 | } 34 | 35 | /**************************************************************************** 36 | entry point 37 | ****************************************************************************/ 38 | int main(void) 39 | { 40 | //Kprintf("ENTER:%s\n",__title__); 41 | 42 | // init I/O 43 | pspSyscon_init(); 44 | pspSysconCtrlLED(0,1); 45 | pspSysconCtrlLED(1,1); 46 | pspSysconCtrlMsPower(1); 47 | 48 | // MS/FAT system 49 | ms_fat_init(); 50 | 51 | ms_save_file(BIOS_FILE_NAME,(void *)0xbfc00000,0x1000); 52 | 53 | // reset reboot 54 | entry(); 55 | 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /ML_BIOS_DUMPER/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | PSP IPL main.bin dumper 3 | */ 4 | 5 | #include 6 | 7 | #include "psp_uart.h" 8 | #include "kprintf.h" 9 | #include "patch.h" 10 | #include "syscon.h" 11 | #include "cache.h" 12 | 13 | #include "memstk.h" 14 | #include "tff.h" /* Tiny-FatFs declarations */ 15 | #include "fatload.h" 16 | 17 | #define BIOS_FILE_NAME "/psp_bios.bin" 18 | 19 | /**************************************************************************** 20 | title message for header 21 | ****************************************************************************/ 22 | const char __title__[] __attribute__ (( section (".init"))) = "PSP BIOS DUMPER"; 23 | 24 | /**************************************************************************** 25 | reset PSP 26 | ****************************************************************************/ 27 | void reboot_psp(void) 28 | { 29 | // reset reboot 30 | Kprintf("Reset PSP\n\n"); 31 | pspSysconResetDevice(1); 32 | while(1); 33 | } 34 | 35 | /**************************************************************************** 36 | entry point 37 | ****************************************************************************/ 38 | int main(void) 39 | { 40 | Kprintf("ENTER:%s\n",__title__); 41 | 42 | // init I/O 43 | pspSyscon_init(); 44 | pspSysconCtrlLED(0,1); 45 | pspSysconCtrlLED(1,1); 46 | pspSysconCtrlMsPower(1); 47 | 48 | // MS/FAT system 49 | ms_fat_init(); 50 | 51 | ms_save_file(BIOS_FILE_NAME,(void *)0xbfc00000,0x1000); 52 | 53 | // reset reboot 54 | reboot_psp(); 55 | 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /MS_NORMAL/iplboot.c: -------------------------------------------------------------------------------- 1 | /* 2 | IPL exploit BOOT LOADER (MS to normal NAND boot) 3 | */ 4 | 5 | #include 6 | 7 | #include "psp_uart.h" 8 | #include "kprintf.h" 9 | #include "patch.h" 10 | #include "syscon.h" 11 | #include "lcdc.h" 12 | #include "cache.h" 13 | 14 | #define UART_MESSAGE 0 15 | 16 | const char title[] = "PSP NORMAL BOOT LOADER for pandora's battery"; 17 | 18 | /**************************************************************************** 19 | IPL exploit entry point 20 | ****************************************************************************/ 21 | void entry(void) 22 | { 23 | #if UART_MESSAGE 24 | // SYNC UART 25 | psp_uart_init(115200); 26 | Kprintf("MS BOOT PROGRAM\n"); 27 | #endif 28 | 29 | #if 1 30 | // SYSCON SPI,GPIO & I/O enable 31 | REG32(0xbc100058) |= 0x00800002; 32 | REG32(0xbc10007c) |= (1<<26) | 0xc8; 33 | REG32(0xbe240000) |= 0xc8; 34 | REG32(0xbc100050) |= 0x0000608E; 35 | REG32(0xbc10004c) &= 0xFFFFFBF7; 36 | REG32(0xbc100078) &= 0x00000002; 37 | #endif 38 | 39 | // SYSCON initialize 40 | pspSyscon_init(); 41 | #if 0 42 | // power control 43 | pspSysconCtrlLED(0,1); 44 | pspSysconCtrlLED(1,1); 45 | pspSysconCtrlHRPower(1); 46 | pspSysconCtrlMsPower(1); 47 | #endif 48 | 49 | // reset reboot 50 | #if UART_MESSAGE 51 | Kprintf("Reset for NAND Flash BOOT\n\n "); 52 | #endif 53 | // RE-RESET to boot NAND Flash ROM 54 | pspSysconResetDevice(1); 55 | 56 | #if UART_MESSAGE 57 | Kprintf("MS LOAD/BOOT ERROR\n"); 58 | #endif 59 | 60 | #if UART_MESSAGE 61 | // message to UART when boot error 62 | Kprintf("Power OFF\n\n "); 63 | #endif 64 | // power down 65 | while(1) 66 | pspSysconPowerStandby(); 67 | } 68 | -------------------------------------------------------------------------------- /tff/diskio.h: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------- 2 | / Low level disk interface modlue include file R0.04a (C)ChaN, 2007 3 | /-----------------------------------------------------------------------*/ 4 | 5 | #ifndef _DISKIO 6 | 7 | #define _READONLY 0 /* 1: Read-only mode */ 8 | 9 | #include "integer.h" 10 | 11 | 12 | /* Status of Disk Functions */ 13 | typedef BYTE DSTATUS; 14 | 15 | /* Results of Disk Functions */ 16 | typedef enum { 17 | RES_OK = 0, /* 0: Successful */ 18 | RES_ERROR, /* 1: R/W Error */ 19 | RES_WRPRT, /* 2: Write Protected */ 20 | RES_NOTRDY, /* 3: Not Ready */ 21 | RES_PARERR /* 4: Invalid Parameter */ 22 | } DRESULT; 23 | 24 | 25 | /*---------------------------------------*/ 26 | /* Prototypes for disk control functions */ 27 | 28 | DSTATUS disk_initialize (BYTE); 29 | DSTATUS disk_status (BYTE); 30 | DRESULT disk_read (BYTE, BYTE*, DWORD, BYTE); 31 | #if _READONLY == 0 32 | DRESULT disk_write (BYTE, const BYTE*, DWORD, BYTE); 33 | #endif 34 | DRESULT disk_ioctl (BYTE, BYTE, void*); 35 | void disk_timerproc (void); 36 | 37 | 38 | 39 | 40 | /* Disk Status Bits (DSTATUS) */ 41 | 42 | #define STA_NOINIT 0x01 /* Drive not initialized */ 43 | #define STA_NODISK 0x02 /* No medium in the drive */ 44 | #define STA_PROTECT 0x04 /* Write protected */ 45 | 46 | 47 | /* Command code for disk_ioctrl() */ 48 | 49 | #define GET_SECTOR_COUNT 1 50 | #define GET_SECTOR_SIZE 2 51 | #define CTRL_SYNC 3 52 | #define CTRL_POWER 4 53 | #define CTRL_LOCK 5 54 | #define CTRL_EJECT 6 55 | #define MMC_GET_CSD 10 56 | #define MMC_GET_CID 11 57 | #define MMC_GET_OCR 12 58 | #define ATA_GET_REV 20 59 | #define ATA_GET_MODEL 21 60 | #define ATA_GET_SN 22 61 | 62 | 63 | #define _DISKIO 64 | #endif 65 | -------------------------------------------------------------------------------- /ML_RECOVERY_LOADER/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | PSP IPL patch & boot 3 | 4 | supported FW is **unknown** 5 | */ 6 | 7 | #include 8 | 9 | #include "psp_uart.h" 10 | #include "kprintf.h" 11 | #include "patch.h" 12 | #include "syscon.h" 13 | #include "cache.h" 14 | 15 | #include "memstk.h" 16 | #include "tff.h" /* Tiny-FatFs declarations */ 17 | #include "fatload.h" 18 | 19 | // path of PANDORA'S IPL CODE with patcher 20 | #define LOAD_IPL_FILE_NAME "/ipl/150ex.bin" 21 | 22 | /**************************************************************************** 23 | title message for header 24 | ****************************************************************************/ 25 | const char __title__[] __attribute__ (( section (".init"))) = "Pandora's Recovery Menu LOADER for MS-Multi Loader"; 26 | 27 | /**************************************************************************** 28 | entry point 29 | ****************************************************************************/ 30 | int main(void) 31 | { 32 | void (*ipl_bin_entry)(void); 33 | u32 *patch_point; 34 | 35 | Kprintf("ENTER:%s\n",__title__); 36 | 37 | // init I/O 38 | pspSyscon_init(); 39 | pspSysconCtrlLED(0,1); 40 | pspSysconCtrlLED(1,1); 41 | pspSysconCtrlMsPower(1); 42 | 43 | // MS/FAT system 44 | ms_fat_init(); 45 | 46 | // load PANDORA'S IPL from MS FAT file 47 | if(ms_load_ipl(LOAD_IPL_FILE_NAME) == NULL) 48 | { 49 | Kprintf("can't load %s\n",LOAD_IPL_FILE_NAME); 50 | while(1); 51 | } 52 | Kprintf("OK\n"); 53 | 54 | // hook jump main.bin 55 | u32 *code = (u32 *)0x040f0000; 56 | code[0xE0/4] = 0x08000000 | ( (0x040e0000)>>2); // j patch_main_bin 57 | code[0xE4/4] = 0x00000000; // nop 58 | 59 | pspClearDcache(); 60 | pspClearIcache(); 61 | 62 | // goto IPL.bin 63 | ipl_bin_entry = (void *)code; 64 | ipl_bin_entry(); 65 | 66 | return 0; 67 | } 68 | -------------------------------------------------------------------------------- /IPL_SDK/kirk.c: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | PSP IPL KIRK driver 3 | ****************************************************************************/ 4 | #include 5 | 6 | ////////////////////////////////////////////////////////////////////// 7 | // KIRK functioon 8 | ////////////////////////////////////////////////////////////////////// 9 | int pspKirkProc(void *dst,u32 dsize,void *src,u32 ssize,u32 cmd) 10 | { 11 | u32 intval; 12 | u32 sts; 13 | 14 | // enable decrypter HW 15 | intval = irq_disable(); 16 | (*(vu32 *)0xbc100050) |= 0x80; 17 | irq_resume(intval); 18 | 19 | // clear cache 20 | // sceKernelDcacheWritebackInvalidateAll(); 21 | pspClearDcache(); 22 | 23 | #if 0 24 | // memory address mask 25 | 26 | r2 = 0x1fffffff; 27 | r3 = r18 & r2; // arg1 28 | r2 = r16 & r2; // arg3 29 | #endif 30 | 31 | //Kprintf("irq_disable\n"); 32 | 33 | // intval = irq_disable(); 34 | 35 | // go KIRK 36 | *(u32 *)(0xbde00010) = (u32)cmd; 37 | *(u32 *)(0xbde0002c) = ((u32)src)&0x1fffffff; 38 | *(u32 *)(0xbde00030) = ((u32)dst)&0x1fffffff; 39 | #if 0 40 | *(u32 *)(0xbde00020) = 0x33; // for IRQ mode 41 | #endif 42 | 43 | //Kprintf("go kirk\n"); 44 | 45 | *(u32 *)(0xbde0000c) = 0x01; // EXEXUTE 46 | 47 | // irq_resume(intval); 48 | 49 | //Kprintf("wait sts\n"); 50 | 51 | do 52 | { 53 | sts = *(vu32 *)0xbde0001c; 54 | }while( (sts & 0x11)==0); 55 | 56 | 57 | *(u32 *)(0xbde00028) = sts; 58 | if(sts & 0x10) 59 | { 60 | *(u32 *)(0xbde0000c) = 0x02; 61 | do 62 | { 63 | sts = *(vu32 *)0xbde0001c; 64 | }while( (sts & 0x02)==0); 65 | *(u32 *)(0xbde00028) = sts; 66 | asm("sync"::); 67 | return -1; 68 | } 69 | #if 0 70 | // disable decrypter HW 71 | // intval = irq_disable(); 72 | (*(vu32 *)0xbc100050) &= ~0x80; 73 | // irq_resume(intval); 74 | #endif 75 | asm("sync"::); 76 | return *(u32 *)(0xbde00014); 77 | } 78 | 79 | -------------------------------------------------------------------------------- /ML_BIOS_DUMPER/iplload.c: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | PSP IPL loader from NAND Flash 3 | ****************************************************************************/ 4 | 5 | #include 6 | #include "kprintf.h" 7 | #include "cache.h" 8 | #include "kirk.h" 9 | 10 | #define READ_BUF ((volatile u32 *)0xbfd00000) 11 | 12 | /**************************************************************************** 13 | NAND transmit block 14 | ****************************************************************************/ 15 | static u32 trasnmit_iplblock(u32 *dst,u32 *src,int size) 16 | { 17 | u32 sum=0; 18 | 19 | do{ 20 | sum += *src; 21 | *dst++ = *src++; 22 | }while( (size-=4) >0); 23 | return sum; 24 | } 25 | 26 | /**************************************************************************** 27 | NAND transmit block 28 | ****************************************************************************/ 29 | void *nand_load_ipl(void) 30 | { 31 | int block; 32 | u32 *dest; 33 | u32 size; 34 | void *entry; 35 | u32 sum; 36 | 37 | Kprintf("Read NAND IPL FAT\n"); 38 | if( pspNandReadIPLFat() < 0) return 0; 39 | 40 | block = 0; 41 | sum = 0; 42 | do{ 43 | if( pspNandReadIPLBlock(block,READ_BUF) < 0) 44 | { 45 | Kprintf("pspNandReadIPLBlock error\n"); 46 | while(1); 47 | } 48 | // decrypt 1000H block 49 | if( pspKirkProc(READ_BUF,0x1000,READ_BUF,0x1000,0x01) !=0) 50 | { 51 | Kprintf("pspKirkProc error\n"); 52 | while(1); 53 | } 54 | 55 | // +000c : check sum of last block 56 | if(sum != READ_BUF[3]) 57 | { 58 | Kprintf("checksum error %08X != %08X\n",sum,READ_BUF[3]); 59 | while(1); 60 | } 61 | ; 62 | // +0000 : destination address 63 | // +0004 : block size 64 | dest = READ_BUF[0]; 65 | size = READ_BUF[1]; 66 | if(dest) 67 | { 68 | // transmit BLOCK body & calc sum32 69 | sum = trasnmit_iplblock(dest,&READ_BUF[0x10/4],size); 70 | } 71 | 72 | entry = (void *)(READ_BUF[2]); 73 | block++; 74 | }while(entry==0); 75 | 76 | pspClearIcache(); 77 | pspClearDcache(); 78 | 79 | return entry; 80 | } 81 | -------------------------------------------------------------------------------- /MS_BIOS_DUMPER/iplload.c: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | PSP IPL loader from NAND Flash 3 | ****************************************************************************/ 4 | 5 | #include 6 | #include "kprintf.h" 7 | #include "cache.h" 8 | #include "kirk.h" 9 | 10 | #define READ_BUF ((volatile u32 *)0xbfd00000) 11 | 12 | /**************************************************************************** 13 | NAND transmit block 14 | ****************************************************************************/ 15 | static u32 trasnmit_iplblock(u32 *dst,u32 *src,int size) 16 | { 17 | u32 sum=0; 18 | 19 | do{ 20 | sum += *src; 21 | *dst++ = *src++; 22 | }while( (size-=4) >0); 23 | return sum; 24 | } 25 | 26 | /**************************************************************************** 27 | NAND transmit block 28 | ****************************************************************************/ 29 | void *nand_load_ipl(void) 30 | { 31 | int block; 32 | u32 *dest; 33 | u32 size; 34 | void *entry; 35 | u32 sum; 36 | 37 | Kprintf("Read NAND IPL FAT\n"); 38 | if( pspNandReadIPLFat() < 0) return 0; 39 | 40 | block = 0; 41 | sum = 0; 42 | do{ 43 | if( pspNandReadIPLBlock(block,READ_BUF) < 0) 44 | { 45 | Kprintf("pspNandReadIPLBlock error\n"); 46 | while(1); 47 | } 48 | // decrypt 1000H block 49 | if( pspKirkProc(READ_BUF,0x1000,READ_BUF,0x1000,0x01) !=0) 50 | { 51 | Kprintf("pspKirkProc error\n"); 52 | while(1); 53 | } 54 | 55 | // +000c : check sum of last block 56 | if(sum != READ_BUF[3]) 57 | { 58 | Kprintf("checksum error %08X != %08X\n",sum,READ_BUF[3]); 59 | while(1); 60 | } 61 | ; 62 | // +0000 : destination address 63 | // +0004 : block size 64 | dest = READ_BUF[0]; 65 | size = READ_BUF[1]; 66 | if(dest) 67 | { 68 | // transmit BLOCK body & calc sum32 69 | sum = trasnmit_iplblock(dest,&READ_BUF[0x10/4],size); 70 | } 71 | 72 | entry = (void *)(READ_BUF[2]); 73 | block++; 74 | }while(entry==0); 75 | 76 | pspClearIcache(); 77 | pspClearDcache(); 78 | 79 | return entry; 80 | } 81 | -------------------------------------------------------------------------------- /ML_MAIN_BIN_DUMPER/iplload.c: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | PSP IPL loader from NAND Flash 3 | ****************************************************************************/ 4 | 5 | #include 6 | #include "kprintf.h" 7 | #include "cache.h" 8 | #include "kirk.h" 9 | 10 | #define READ_BUF ((volatile u32 *)0xbfd00000) 11 | 12 | /**************************************************************************** 13 | NAND transmit block 14 | ****************************************************************************/ 15 | static u32 trasnmit_iplblock(u32 *dst,u32 *src,int size) 16 | { 17 | u32 sum=0; 18 | 19 | do{ 20 | sum += *src; 21 | *dst++ = *src++; 22 | }while( (size-=4) >0); 23 | return sum; 24 | } 25 | 26 | /**************************************************************************** 27 | NAND transmit block 28 | ****************************************************************************/ 29 | void *nand_load_ipl(void) 30 | { 31 | int block; 32 | u32 *dest; 33 | u32 size; 34 | void *entry; 35 | u32 sum; 36 | 37 | Kprintf("Read NAND IPL FAT\n"); 38 | if( pspNandReadIPLFat() < 0) return 0; 39 | 40 | block = 0; 41 | sum = 0; 42 | do{ 43 | if( pspNandReadIPLBlock(block,READ_BUF) < 0) 44 | { 45 | Kprintf("pspNandReadIPLBlock error\n"); 46 | while(1); 47 | } 48 | // decrypt 1000H block 49 | if( pspKirkProc(READ_BUF,0x1000,READ_BUF,0x1000,0x01) !=0) 50 | { 51 | Kprintf("pspKirkProc error\n"); 52 | while(1); 53 | } 54 | 55 | // +000c : check sum of last block 56 | if(sum != READ_BUF[3]) 57 | { 58 | Kprintf("checksum error %08X != %08X\n",sum,READ_BUF[3]); 59 | while(1); 60 | } 61 | ; 62 | // +0000 : destination address 63 | // +0004 : block size 64 | dest = READ_BUF[0]; 65 | size = READ_BUF[1]; 66 | if(dest) 67 | { 68 | // transmit BLOCK body & calc sum32 69 | sum = trasnmit_iplblock(dest,&READ_BUF[0x10/4],size); 70 | } 71 | 72 | entry = (void *)(READ_BUF[2]); 73 | block++; 74 | }while(entry==0); 75 | 76 | pspClearIcache(); 77 | pspClearDcache(); 78 | 79 | return entry; 80 | } 81 | -------------------------------------------------------------------------------- /MS_MULTI_LOADER/readme.txt: -------------------------------------------------------------------------------- 1 | PSP MS MultiLoader IPL by BOOSTER. 2 | Contact: https://twitter.com/Mathieulh 3 | -------------------------------------- 4 | What is it? 5 | 6 | This is IPL to support "JigKick Battery" of PANDORA'S BATTERY. 7 | It can start up the FAT file which was chosen at the button. 8 | And , it includes a normal boot function. 9 | 10 | It will not need mspformat with most case. 11 | 12 | -------------------------------------- 13 | How to install. 14 | 15 | 1.Double click "install_psp_ms_multi_loader_ipl.cmd" on Windows2K/XP (admin). 16 | 2.Connect MsProDuo to PC via USB MemoryReaderWriter(or PSP). 17 | 3.Press 'Y' for "Are You Sure ?[Y]" message to install the IPL to MsProDuo. 18 | 19 | -------------------------------------- 20 | How to use. 21 | 22 | 1.Copy bootfile to "ms0:/ipl/ipl_xxx.bin" of MsProDuo which installed MultiLoader. 23 | (see "RECOVERY_LOADER/readme.txt" to boot padnora's "Magic Memory Stick") 24 | 25 | 2.Power off the PSP. 26 | 27 | 3.Hold LTRG and allow key to select boot file,or LTRG off to normal boot. 28 | LTRG+UP -> load/run "ms0:/ipl/ipl_up.bin" 29 | LTRG+LEFT -> load/run "ms0:/ipl/ipl_lt.bin" 30 | LTRG+RIGHT -> load/run "ms0:/ipl/ipl_rt.bin" 31 | LTRG+DOWN -> load/run "ms0:/ipl/ipl_dn.bin" 32 | LTRG -> load/run "ms0:/ipl/ipl.bin" 33 | other -> normal boot from internal NAND flash. 34 | 35 | 4.Insert "JigKick Battery". 36 | 37 | The MS and WLAN LED are flashing when boot file are missing or boot error. 38 | 39 | -------------------------------------- 40 | How to build boot file. 41 | 42 | File format are binary included 16bytes PSP IPL likely header. 43 | 44 | |offset|size| specification 45 | |+0000 | 4 | top of load address 46 | |+0004 | 4 | data size 47 | |+0008 | 4 | entry point (0x0000000 then continue to next block) 48 | |+000C | 4 | check sum of last block(0x00000000 for top block) 49 | |+0010 | ? | data body 50 | 51 | Usage space are 0x04000000 to 0x041DFFFF, 52 | because DDR-SDRAM was not initialized, 53 | and the Multi loader uses 0x041E0000 to 0x041FFFFF. 54 | 55 | Wait for PSP_IPL_SDK which will be immediately released. 56 | 57 | -------------------------------------- 58 | Note. 59 | 60 | This uses the IPL exploit block of the PANDORA'S BATTERY. 61 | Please read the readme of PANDORA'S BATTERY. 62 | 63 | -------------------------------------------------------------------------------- /IPL_SDK/crt0_bin.S: -------------------------------------------------------------------------------- 1 | # PSP Software Development Kit - http://www.pspdev.org 2 | # ----------------------------------------------------------------------- 3 | # Licensed under the BSD license, see LICENSE in PSPSDK root for details. 4 | # 5 | # crt0.S - Startup functions and definitions. Inspired by nem's helloworld. 6 | # 7 | # Copyright (c) 2005 Marcus R. Brown 8 | # Copyright (c) 2005 James Forshaw 9 | # Copyright (c) 2005 John Kelley 10 | # 11 | # $Id: crt0.S 363 2005-06-27 20:35:14Z tyranid $ 12 | 13 | .set noreorder 14 | 15 | .text 16 | 17 | .extern main 18 | 19 | #include "as_reg_compat.h" 20 | 21 | 22 | ############################################################################## 23 | 24 | # Support for _init() and _fini(). 25 | ; .global _init 26 | ; .global _fini 27 | ; .type _init, @function 28 | ; .type _fini, @function 29 | 30 | # The .weak keyword ensures there's no error if 31 | # _init/_fini aren't defined. 32 | ; .weak _init 33 | ; .weak _fini 34 | 35 | # Define the main thread attribute variable as weak 36 | ; .weak _main_thread_attr 37 | 38 | .global _start 39 | .ent _start 40 | 41 | _start: 42 | #;from loader 43 | #;save r4,r5,r2,r20 44 | jal entry 45 | nop 46 | 47 | addiu $sp, -0x20 48 | sw $2, 0($sp) 49 | sw $4, 4($sp) 50 | sw $5, 8($sp) 51 | sw $6,12($sp) 52 | sw $7,16($sp) 53 | sw $8,20($sp) 54 | sw $22,24($sp) 55 | sw $gp,28($sp) 56 | 57 | # Clear BSS 58 | # loop: 59 | # sw $0,0($t0) 60 | # sltu $v0, $t0, $t1 61 | # bne $v0, $0, loop 62 | # addiu $t0, $t0, 4 63 | la $gp, _gp 64 | #; la $t0, _init 65 | #; beqz $t0, 1f 66 | #; nop 67 | #; jalr $t0 68 | #; nop 69 | 1: 70 | # jal main 71 | nop 72 | # 73 | lw $2, 0($sp) 74 | lw $4, 4($sp) 75 | lw $5, 8($sp) 76 | lw $6,12($sp) 77 | lw $7,16($sp) 78 | lw $8,20($sp) 79 | lw $22,24($sp) 80 | lw $gp,28($sp) 81 | jr $2 82 | addu $29,$22,$0 83 | ; 84 | .end _start 85 | 86 | .global _exit 87 | .ent _exit 88 | 89 | _exit: 90 | # Exit 91 | la $t0, _fini 92 | beqz $t0, 2f 93 | nop 94 | 95 | jalr $t0 96 | nop 97 | 2: 98 | 99 | lw $ra, 0($sp) 100 | jr $ra 101 | addiu $sp, 0x10 102 | 103 | .end _exit 104 | 105 | .bss 106 | -------------------------------------------------------------------------------- /IPL_SDK/build_bin.mak: -------------------------------------------------------------------------------- 1 | # PSP Software Development Kit - http://www.pspdev.org 2 | # ----------------------------------------------------------------------- 3 | # Licensed under the BSD license, see LICENSE in PSPSDK root for details. 4 | # 5 | # build.mak - Base makefile for projects using PSPSDK. 6 | # 7 | # Copyright (c) 2005 Marcus R. Brown 8 | # Copyright (c) 2005 James Forshaw 9 | # Copyright (c) 2005 John Kelley 10 | # 11 | # $Id: build.mak 355 2005-06-27 07:38:48Z mrbrown $ 12 | 13 | # Note: The PSPSDK make variable must be defined before this file is included. 14 | ifeq ($(PSPSDK),) 15 | $(error $$(PSPSDK) is undefined. Use "PSPSDK := $$(shell psp-config --pspsdk-path)" in your Makefile) 16 | endif 17 | 18 | CC = psp-gcc 19 | CXX = psp-g++ 20 | AS = psp-gcc 21 | #LD = psp-gcc 22 | LD = psp-ld 23 | AR = psp-ar 24 | RANLIB = psp-ranlib 25 | STRIP = psp-strip 26 | 27 | # Add in PSPSDK includes and libraries. 28 | INCDIR := $(INCDIR) . $(PSPSDK)/include 29 | LIBDIR := $(LIBDIR) . $(PSPSDK)/lib 30 | 31 | CFLAGS := $(addprefix -I,$(INCDIR)) $(CFLAGS) 32 | CXXFLAGS := $(CFLAGS) $(CXXFLAGS) 33 | ASFLAGS := $(CFLAGS) $(ASFLAGS) 34 | 35 | LDFLAGS := $(addprefix -L,$(LIBDIR)) $(LDFLAGS) 36 | 37 | # Library selection. By default we link with PSPSDK's libc. Allow the 38 | # user to link with Newlib's libc if USE_NEWLIB_LIBC is set to 1. 39 | #PSPSDK_LIBC_LIB = -lpsplibc 40 | #ifeq ($(USE_NEWLIB_LIBC),1) 41 | #PSPSDK_LIBC_LIB = -lc -lpspglue 42 | #endif 43 | 44 | # Link with following default libraries. Other libraries should be specified in the $(LIBS) variable. 45 | # TODO: This library list needs to be generated at configure time. 46 | #PSPSDK_LIBS = -lpspdebug 47 | #LIBS := $(LIBS) $(PSPSDK_LIBS) $(PSPSDK_LIBC_LIB) -lpspkernel 48 | # 49 | ifneq ($(TARGET_LIB),) 50 | FINAL_TARGET = $(TARGET_LIB) 51 | else 52 | FINAL_TARGET = $(TARGET).bin 53 | endif 54 | 55 | all: $(EXTRA_TARGETS) $(FINAL_TARGET) 56 | 57 | $(TARGET).bin: $(TARGET).elf 58 | $(STRIP) -s -O binary $(TARGET).elf -o $(TARGET).bin 59 | -rm -f $(TARGET).elf 60 | 61 | $(TARGET).elf: $(OBJS) 62 | -rm -f $(TARGET).elf 63 | $(LINK.c) $^ $(LIBS) -o $(TARGET).elf 64 | 65 | $(TARGET_LIB): $(OBJS) 66 | $(AR) cru $@ $(OBJS) 67 | 68 | clean: $(EXTRA_CLEAN) 69 | -rm -f $(FINAL_TARGET) *.o $(PSP_EBOOT_SFO) $(PSP_EBOOT) 70 | -------------------------------------------------------------------------------- /IPL_SDK/crt0_exp.S: -------------------------------------------------------------------------------- 1 | # 2 | # PSP IPL Exploit Boot Loader 3 | # 4 | # crt0.S - Startup functions and definitions. Inspired by nem's helloworld. 5 | # 6 | .set noreorder 7 | 8 | .text 9 | 10 | .extern main 11 | 12 | #include "as_reg_compat.h" 13 | 14 | 15 | ############################################################################## 16 | 17 | # Support for _init() and _fini(). 18 | ; .global _init 19 | ; .global _fini 20 | ; .type _init, @function 21 | ; .type _fini, @function 22 | 23 | # The .weak keyword ensures there's no error if 24 | # _init/_fini aren't defined. 25 | ; .weak _init 26 | ; .weak _fini 27 | 28 | # Define the main thread attribute variable as weak 29 | ; .weak _main_thread_attr 30 | 31 | _data_top: 32 | # 33 | #IPL Exploit Block 34 | #Here is "PANDORA'S BATTERY" code. 35 | #check readme.txt of "PANDORA'S BATTERY" for license 36 | # 37 | .word 0x00000000,0x00000000,0xbfd00100,0x00000000 38 | .word 0x00000000,0x00000000,0x00000000,0x00000000 39 | .word 0xcd05a152,0x2859523a,0xf131d10a,0xcc2e87bd 40 | .word 0x2f02da14,0x66c78877,0xbd0732f3,0x4c9e081a 41 | .word 0x00000000,0x00000000,0x00000000,0x00000000 42 | .word 0x00000000,0x00000000,0x00000000,0x00000000 43 | .word 0x00000001,0x00000000,0x00000000,0x00000000 44 | .word 0x00000004,0x00000010,0x00000000,0x00000000 45 | .word 0x00000000,0x00000000,0x00000000,0x00000000 46 | .word 0x00000000,0x00000000,0x00000000,0x00000000 47 | .word 0x00000000,0x00000000,0x01000000,0x12745fc6 48 | # 49 | .org _data_top + 0x100 50 | # 51 | #1st entry point 52 | # 53 | #move code to real address 54 | la $t0,0xbfd00000 55 | la $t1,_data_top 56 | addi $t2,$0,0x1000 57 | reload_loop: 58 | lw $v0,0($t0) 59 | addi $t0,4 60 | sw $v0,0($t1) 61 | addi $t2,-4 62 | bne $t2, $0, reload_loop 63 | addi $t1,4 64 | # 65 | #cache clear 66 | la $t0,0x800102d8 67 | jalr $t0 68 | nop 69 | la $t0,0x800102a0 70 | jalr $t0 71 | nop 72 | # 73 | #goto real entry address 74 | la $t0,_start 75 | jr $t0 76 | nop 77 | # 78 | .global _start 79 | .ent _start 80 | # 81 | #real entry point 82 | # 83 | _start: 84 | #;from loader 85 | #;save r4,r5,r2,r20 86 | #sp = $80013ff0 87 | lui $sp, 0x040d 88 | jal entry 89 | lui $gp,0x0000 90 | #goto PRE-IPL again 91 | la $sp,0x80013ff0 92 | lui $25,0x8001 93 | j $25 94 | nop 95 | .end _start 96 | .global _exit 97 | .ent _exit 98 | 99 | _exit: 100 | # Exit 101 | .end _exit 102 | 103 | .bss 104 | -------------------------------------------------------------------------------- /IPL_SDK/lcdc.c: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | PSP IPL LCDC driver 3 | 4 | note: 5 | Work in progress. 6 | It doesn't work yet. 7 | 8 | ****************************************************************************/ 9 | #include 10 | #include "Kprintf.h" 11 | 12 | #include "patch.h" 13 | #include "syscon.h" 14 | #include "lcdc.h" 15 | 16 | #define BYPASS_ERR_CHECK 1 17 | 18 | u32 pspLcdcInit(void *frame_buffer) 19 | { 20 | // LCD POWER 21 | pspSysconCtrlPower(SYSCON_DEV_LCD|SYSCON_DEV_ON); 22 | 23 | // sceSysreg_driver_Unkonow_e88b77ed 24 | REG32(0xbc10003c) |= 0x01; 25 | 26 | //sceSysreg_driver_Unkonow_dca57573(1) 27 | //REG32(0xbc100068) |= ? 28 | 29 | // sceSysregDmacplusBusClockEnable : 00000010 30 | REG32(0xbc100050) |= 0x00000010; 31 | 32 | // sceSysregLcdcClkEnable : 00040000 33 | // sceSysregPwmClkEnable : 00080000 34 | //REG32(0xBC100058)=0x01AD2601; 35 | REG32(0xbc100058) |= 0x000c0000; 36 | 37 | // select : bit 22-20 38 | REG32(0xBC100060)=0x00030070; 39 | 40 | // sceSysregLcdcIoEnable : 00000040 41 | // sceSysregPwmIoEnable : 00002000 42 | //REG32(0xBC100078)=0x01182AFA; 43 | REG32(0xbc100078) |= 0x00002040; 44 | 45 | // GPIO.0 (LCD ON) 46 | REG32(0xbe240000) |= 0x00000001; 47 | REG32(0xbe240008) = 0x00000001; 48 | 49 | // PwmStart(0,18,19,0) 50 | REG32(0xBE300000)=0x00000018; 51 | REG32(0xBE300004)=0x00000001; 52 | REG32(0xBE300008)=0x00000000; 53 | REG32(0xBE300010)=0x00000019; 54 | REG32(0xBE300014)=0x00000000; // 6 55 | 56 | // PwmStart(1,18,19,19) 57 | REG32(0xBE300020)=0x00000018; 58 | REG32(0xBE300024)=0x00000001; 59 | REG32(0xBE300028)=0x00000000; 60 | REG32(0xBE300030)=0x00000019; 61 | REG32(0xBE300034)=0x00000019; 62 | 63 | // LCDC 64 | REG32(0xBE140000)=0x03; 65 | REG32(0xBE140004)=0; 66 | REG32(0xBE140008)=0; 67 | REG32(0xBE140010)=0x00000029; 68 | REG32(0xBE140014)=0x02; 69 | REG32(0xBE140018)=0x02; 70 | REG32(0xBE14001C)=480; // LCD X 71 | REG32(0xBE140020)=0x0A; 72 | REG32(0xBE140024)=0x02; 73 | REG32(0xBE140028)=0x02; 74 | REG32(0xBE14002C)=272; // LCD Y 75 | REG32(0xBE140040)=0x00000000; 76 | REG32(0xBE140044)=0x00000000; 77 | REG32(0xBE140048)=480; 78 | REG32(0xBE14004C)=272; 79 | REG32(0xBE140050)=0x00000001; 80 | 81 | // sceDmacplusLcdcSetBaseAddr 82 | REG32(0xBC800100)=(u32 *)frame_buffer; 83 | 84 | // sceDmacplusLcdcSetFormat 85 | REG32(0xBC800104)=0x00000000; 86 | REG32(0xBC800108)=0x000001E0; // X display 87 | REG32(0xBC80010C)=0x00000200; // X vram 88 | 89 | // sceDmacplusLcdcEnable 90 | REG32(0xBC800110)=0x00000003; 91 | 92 | // LCDC reset 93 | REG32(0xBE140000)&=~1; 94 | REG32(0xBE140000)|= 1; 95 | 96 | return 0; 97 | } 98 | -------------------------------------------------------------------------------- /IPL_SDK/crt0_ipl.S: -------------------------------------------------------------------------------- 1 | # PSP Software Development Kit - http://www.pspdev.org 2 | # ----------------------------------------------------------------------- 3 | # Licensed under the BSD license, see LICENSE in PSPSDK root for details. 4 | # 5 | # crt0.S - Startup functions and definitions. Inspired by nem's helloworld. 6 | # 7 | # Copyright (c) 2005 Marcus R. Brown 8 | # Copyright (c) 2005 James Forshaw 9 | # Copyright (c) 2005 John Kelley 10 | # 11 | # $Id: crt0.S 363 2005-06-27 20:35:14Z tyranid $ 12 | 13 | .set noreorder 14 | 15 | .text 16 | 17 | .extern main 18 | 19 | #include "as_reg_compat.h" 20 | 21 | ############################################################################## 22 | 23 | # Support for _init() and _fini(). 24 | .global _init 25 | .global _fini 26 | .type _init, @function 27 | .type _fini, @function 28 | 29 | # The .weak keyword ensures there's no error if 30 | # _init/_fini aren't defined. 31 | .weak _init 32 | .weak _fini 33 | 34 | #-------------------------------------------------------------------------------- 35 | # 00h-10h HEADER block for exploit installer 36 | #-------------------------------------------------------------------------------- 37 | .section .init 38 | .word _body # +00 load address 39 | .word __tsize # +04 program size 40 | .word _start # +08 entry address 41 | .word 0x00000000 # +0c 00000000 (sum32 of last block) 42 | _body: 43 | # comment "PSP IPL BINARY" 44 | .word 0x20505350 45 | .word 0x204C5049 46 | .word 0x414E4942 47 | .word 0x00005952 48 | 49 | .section .text 50 | #-------------------------------------------------------------------------------- 51 | # Entry point 52 | #-------------------------------------------------------------------------------- 53 | .global _start 54 | .ent _start 55 | 56 | _start: 57 | # 58 | # Clear BSS 59 | la $t0,__sbss_start 60 | la $t1,__sbss_end 61 | loop: 62 | sw $0,0($t0) 63 | sltu $v0, $t0, $t1 64 | bne $v0, $0, loop 65 | addiu $t0, $t0, 4 66 | # 67 | #call _init 68 | la $gp, _gp 69 | la $t0, _init 70 | beqz $t0, 1f 71 | nop 72 | jalr $t0 73 | nop 74 | 1: 75 | # go main 76 | addiu $a1,0 77 | addiu $a2,0 78 | jal main 79 | nop 80 | halt: 81 | j halt 82 | nop 83 | ; 84 | .end _start 85 | # 86 | # 87 | # 88 | .global _exit 89 | .ent _exit 90 | 91 | _exit: 92 | # Exit 93 | la $t0, _fini 94 | beqz $t0, 2f 95 | nop 96 | 97 | jalr $t0 98 | nop 99 | 2: 100 | 101 | lw $ra, 0($sp) 102 | jr $ra 103 | addiu $sp, 0x10 104 | 105 | .end _exit 106 | 107 | .bss 108 | -------------------------------------------------------------------------------- /IPL_SDK/crt0_ms.S: -------------------------------------------------------------------------------- 1 | # 2 | # PSP IPL Exploit Boot Loader for ms exploit boot 3 | # 4 | # crt0.S - Startup functions and definitions. Inspired by nem's helloworld. 5 | # 6 | .set noreorder 7 | 8 | .text 9 | 10 | .extern main 11 | 12 | .extern __sbss_start 13 | .extern __sbss_end 14 | 15 | #include "as_reg_compat.h" 16 | 17 | 18 | ############################################################################## 19 | 20 | # Support for _init() and _fini(). 21 | ; .global _init 22 | ; .global _fini 23 | ; .type _init, @function 24 | ; .type _fini, @function 25 | 26 | # The .weak keyword ensures there's no error if 27 | # _init/_fini aren't defined. 28 | ; .weak _init 29 | ; .weak _fini 30 | 31 | # Define the main thread attribute variable as weak 32 | ; .weak _main_thread_attr 33 | 34 | _data_top: 35 | # 36 | #IPL Exploit Block 37 | #Here is "PANDORA'S BATTERY" code. 38 | #check readme.txt of "PANDORA'S BATTERY" for license 39 | # 40 | .word 0x00000000,0x00000000,0xbfd00100,0x00000000 41 | .word 0x00000000,0x00000000,0x00000000,0x00000000 42 | .word 0xcd05a152,0x2859523a,0xf131d10a,0xcc2e87bd 43 | .word 0x2f02da14,0x66c78877,0xbd0732f3,0x4c9e081a 44 | .word 0x00000000,0x00000000,0x00000000,0x00000000 45 | .word 0x00000000,0x00000000,0x00000000,0x00000000 46 | .word 0x00000001,0x00000000,0x00000000,0x00000000 47 | .word 0x00000004,0x00000010,0x00000000,0x00000000 48 | .word 0x00000000,0x00000000,0x00000000,0x00000000 49 | .word 0x00000000,0x00000000,0x00000000,0x00000000 50 | .word 0x00000000,0x00000000,0x01000000,0x12745fc6 51 | # 52 | .org _data_top + 0x100 53 | # 54 | #1st entry point 55 | # 56 | #load body from MS 57 | # 58 | addiu $16,$0,0x10 59 | la $17,_data_top 60 | la $18,__sbss_start 61 | ms_load: 62 | la $v0,0x80010418 63 | addu $a0,$0,$16 64 | jalr $v0 65 | addu $a1,$0,$17 66 | 67 | bltz $v0,ms_load 68 | nop 69 | addiu $17,0x200 70 | sltu $t0,$17,$18 71 | bne $t0,$0,ms_load 72 | addiu $16,1 73 | #Dcache 74 | la $v0,0x800102d8 75 | jalr $v0 76 | nop 77 | #Icache 78 | la $v0,0x800102a0 79 | jalr $v0 80 | nop 81 | #RUN 82 | la $t0,_start 83 | jr $t0 84 | nop 85 | # 86 | .global _start 87 | .ent _start 88 | # 89 | #main entry point 90 | # 91 | _start: 92 | #;from loader 93 | #;save r4,r5,r2,r20 94 | #sp = $80013ff0 95 | lui $sp, 0x040d 96 | # Clear BSS 97 | la $t0, __sbss_start 98 | la $t1, __sbss_end 99 | bss_clr: 100 | sw $0,0($t0) 101 | addi $t0,2 102 | sltu $v0, $t0, $t1 103 | bne $v0, $0, bss_clr 104 | nop 105 | #Enter 106 | jal entry 107 | lui $gp,0x0000 108 | 109 | #goto PRE-IPL again 110 | la $sp,0x80013ff0 111 | lui $25,0x8001 112 | j $25 113 | nop 114 | .end _start 115 | .global _exit 116 | .ent _exit 117 | 118 | _exit: 119 | # Exit 120 | .end _exit 121 | 122 | .bss 123 | -------------------------------------------------------------------------------- /readme.txt: -------------------------------------------------------------------------------- 1 | ----------------------------------------------------------------------------- 2 | PSP-IPL-SDK Rev.0.5 (2007.10.9) by BOOSTER. 3 | Contact: https://twitter.com/Mathieulh 4 | ----------------------------------------------------------------------------- 5 | 6 | This is an open SoftwareDevelopmentKit for PSP IPL code. 7 | And example. 8 | 9 | ----------------------------------------------------------------------------- 10 | directories 11 | ----------------------------------------------------------------------------- 12 | 13 | -- driver / library -- 14 | 15 | IPL_SDK/ --- PSP driver and libs to build IPL/boot code. 16 | LIBC/ --- poor stdio libs. 17 | tff/ --- ChaN's open source FAT File System Module. 18 | PANDORA/ --- PANDORA'S BATTERY (readme.txt only) 19 | 20 | -- PSP RAW IPL code example -- 21 | 22 | MS_NORMAL/ --- Normal NAND boot for MS-IPL. 23 | MS_MULTI_LOADER/ --- MS MultiLoader for MS-IPL. 24 | 25 | -- boot code example for MS MultiLoader -- 26 | 27 | ML_FLASH_LED/ --- The simplest exsample. 28 | ML_BIOS_DUMPER/ --- 'pre-ipl' BIOS ROM dumper. 29 | ML_MAIN_BIN_DUMPER/ --- IPL "main.bin" dumper. 30 | ML_DDR_DUMPER/ --- DDR-SDRAM dumper at last power off. 31 | ML_RECOVERY_LOADER/ --- PANDORA'S BATTERY recovery menu bootloader. 32 | 33 | -- tools -- 34 | 35 | msinst/ --- MS IPL code installer for Windows PC. 36 | 37 | -- misc code / tool -- 38 | 39 | iplex/ --- 2nd IPL,"ipl.bin" loader with patch (for CFW/downgrader) 40 | installer/ --- IPL patch & boot code installer to NAND Flash (for CFW) 41 | 42 | ----------------------------------------------------------------------------- 43 | note 44 | ----------------------------------------------------------------------------- 45 | 46 | ---------------------------------------- 47 | kprintf message 48 | 49 | Connect a serial port via HPRemote with 115Kbps. 50 | The output of Kprintf() out there. 51 | Plug mini-jack because SYSCON cuts power automatically when pulling out a plug. 52 | 53 | -------------------------------------- 54 | MultiLoader file format 55 | 56 | see MS_MULTI_LOADER/readme.txt 57 | 58 | ---------------------------------------- 59 | Top address of MultiLoader bootcode 60 | 61 | "PROVIDE (__executable_start = 0x040e0000); . = 0x040e0000;" 62 | in "IPL_SDK/pspipl.x" 63 | 64 | ---------------------------------------- 65 | DDR-SDRAM 66 | 67 | The DDR-SDRAM can not use because it isn't initialized. 68 | The simple way of using SDRAM is to be in the hook after main.bin is initialized. 69 | see the "ML_DDRDUMP" example. 70 | 71 | finally,the original SDRAM driver should be made. 72 | 73 | ---------------------------------------- 74 | Changelog (2018.3.23) 75 | 76 | - Moved to GPLv2 License (some crt0 code has "PANDORA'S BATTERY" code. 77 | Check readme.txt of "PANDORA'S BATTERY" for license.) 78 | - Added compatibility to GCC newer than 4.0.2 79 | -------------------------------------------------------------------------------- /IPL_SDK/crt0_nand.S: -------------------------------------------------------------------------------- 1 | # 2 | # PSP original IPL (loaded by NAND exploit installer / boot loader) 3 | # 4 | 5 | # PSP Software Development Kit - http://www.pspdev.org 6 | # ----------------------------------------------------------------------- 7 | # Licensed under the BSD license, see LICENSE in PSPSDK root for details. 8 | # 9 | # crt0.S - Startup functions and definitions. Inspired by nem's helloworld. 10 | # 11 | # Copyright (c) 2005 Marcus R. Brown 12 | # Copyright (c) 2005 James Forshaw 13 | # Copyright (c) 2005 John Kelley 14 | # 15 | # $Id: crt0.S 363 2005-06-27 20:35:14Z tyranid $ 16 | 17 | .set noreorder 18 | 19 | .text 20 | 21 | .extern main 22 | 23 | #include "as_reg_compat.h" 24 | 25 | 26 | ############################################################################## 27 | 28 | # .extern __executable_start 29 | # .extern edata 30 | 31 | .extern __sbss_start 32 | .extern __sbss_end 33 | 34 | #-------------------------------------------------------------------------------- 35 | # +10h HEADER block for exploit installer 36 | #-------------------------------------------------------------------------------- 37 | .word _start # +00 load address 38 | .word 0x12345678 # +04 signature (replace size by installer) 39 | .word _start # +08 entry address 40 | .word 0x12345678 # +0c signature2 41 | 42 | #-------------------------------------------------------------------------------- 43 | # Entry point 44 | #-------------------------------------------------------------------------------- 45 | .global _start 46 | .ent _start 47 | _start: 48 | # Stack Pointer 49 | lui $sp, 0x040d 50 | 51 | # Clear BSS 52 | la $t0, __sbss_start 53 | la $t1, __sbss_end 54 | bss_clr: 55 | sw $0,0($t0) 56 | addi $t0,2 57 | sltu $v0, $t0, $t1 58 | bne $v0, $0, bss_clr 59 | nop 60 | #call entry 61 | jal entry 62 | la $gp, _gp 63 | # 64 | #PRE-IPL recall 65 | la $sp,0x80013ff0 66 | lui $25,0x8001 67 | j $25 68 | nop 69 | # 70 | # addiu $sp, -0x20 71 | # sw $2, 0($sp) 72 | # sw $4, 4($sp) 73 | # sw $5, 8($sp) 74 | # sw $6,12($sp) 75 | # sw $7,16($sp) 76 | # sw $8,20($sp) 77 | # sw $22,24($sp) 78 | # sw $gp,28($sp) 79 | # 80 | # Clear BSS 81 | # loop: 82 | # sw $0,0($t0) 83 | # sltu $v0, $t0, $t1 84 | # bne $v0, $0, loop 85 | # addiu $t0, $t0, 4 86 | # la $gp, _gp 87 | #; la $t0, _init 88 | #; beqz $t0, 1f 89 | #; nop 90 | #; jalr $t0 91 | #; nop 92 | #1: 93 | # jal main 94 | # nop 95 | # 96 | # lw $2, 0($sp) 97 | # lw $4, 4($sp) 98 | # lw $5, 8($sp) 99 | # lw $6,12($sp) 100 | # lw $7,16($sp) 101 | # lw $8,20($sp) 102 | # lw $22,24($sp) 103 | # lw $gp,28($sp) 104 | # jr $2 105 | # addu $29,$22,$0 106 | ; 107 | .end _start 108 | 109 | .global _exit 110 | .ent _exit 111 | 112 | _exit: 113 | # Exit 114 | j _exit 115 | nop 116 | .end _exit 117 | 118 | .bss 119 | _bss: 120 | -------------------------------------------------------------------------------- /ML_DDRDUMPER/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | PSP IPL patch & boot 3 | 4 | supported FW is **unknown** 5 | */ 6 | 7 | #include 8 | 9 | #include "psp_uart.h" 10 | #include "kprintf.h" 11 | #include "patch.h" 12 | #include "syscon.h" 13 | #include "cache.h" 14 | 15 | #include "memstk.h" 16 | #include "tff.h" /* Tiny-FatFs declarations */ 17 | #include "fatload.h" 18 | 19 | #define PSP_IPL_FILENAME "ipl/ipl150.bin" 20 | 21 | /**************************************************************************** 22 | title message for header 23 | ****************************************************************************/ 24 | const char __title__[] __attribute__ (( section (".init"))) = "DDR-SDRAM DUMPER"; 25 | 26 | /**************************************************************************** 27 | after DDR init 28 | ****************************************************************************/ 29 | void dump_mem(u32 a1,u32 a2,u32 a3,u32 a4) 30 | { 31 | #if 0 32 | Kprintf("DUMP HW Registers\n"); 33 | dump_regs(); 34 | #endif 35 | 36 | Kprintf("DUMP VECTOR RAM\n"); 37 | ms_save_file("vecmem.bin" ,(void *)0xbfc00000,0x1000); 38 | 39 | Kprintf("DUMP Kernel Memory\n"); 40 | ms_save_file("kermem.bin" ,(void *)0x88000000,4*1024*1024); 41 | 42 | #if 0 43 | Kprintf("DUMP Kernel Memory2\n"); 44 | ms_save_file("kermem2.bin",(void *)0x84000000,4*1024*1024); 45 | 46 | Kprintf("DUMP User Memory\n"); 47 | ms_save_file("usermem.bin" ,(void *)0x88800000,24*1024*1024); 48 | 49 | Kprintf("DONE\n"); 50 | 51 | // WLAN ON , MS OFF 52 | REG32(0xbe240008) = 0x80; 53 | REG32(0xbe24000c) = 0x40; 54 | #endif 55 | 56 | // reset reboot 57 | Kprintf("Reset PSP\n\n"); 58 | pspSysconResetDevice(1); 59 | 60 | while(1); 61 | } 62 | 63 | /**************************************************************************** 64 | before jump main.bin 65 | 66 | (after decrypt/loaded main.bin) 67 | ****************************************************************************/ 68 | void patch_main_bin(void) 69 | { 70 | u32 *code = (u32 *)0x04000000; 71 | 72 | Kprintf("patch_main_bin\n"); 73 | 74 | // TARP after reset DDR-SDRAM 75 | code[0x08/4] = 0x08000000 | ( ((u32)dump_mem & 0x0ffffffc)>>2); 76 | code[0x0c/4] = 0; 77 | 78 | // Change payload entrypoint to payloadex 79 | code[0xa758/4] = 0x3c198870; // entry = 88700000 80 | 81 | // Avoid TA-082 clockgen incompatibility 82 | code[0x0858/4] = 0x1000ff07; // -> beq $zero, $zero, ... 83 | 84 | pspClearDcache(); 85 | pspClearIcache(); 86 | 87 | asm("lui $25, 0x0400"); 88 | asm("lui $sp, 0x040F"); 89 | asm("jr $25"); 90 | asm("ori $sp,$sp, 0xFF00"); 91 | } 92 | 93 | /**************************************************************************** 94 | entry point 95 | ****************************************************************************/ 96 | int main(void) 97 | { 98 | void (*ipl_bin_entry)(void); 99 | 100 | Kprintf("ENTER:%s\n",__title__); 101 | 102 | // init I/O 103 | pspSyscon_init(); 104 | pspSysconCtrlLED(0,1); 105 | pspSysconCtrlLED(1,1); 106 | pspSysconCtrlMsPower(1); 107 | 108 | // MS/FAT system 109 | ms_fat_init(); 110 | 111 | // load FW1.50 IPL for initialize DDR-SDRAM controller 112 | if(ms_load_ipl(PSP_IPL_FILENAME) == NULL) 113 | { 114 | Kprintf("can't load ipl.bin\n"); 115 | while(1); 116 | } 117 | 118 | // hook jump main.bin 119 | u32 *code = (u32 *)0x040f0000; 120 | code[0xE0/4] = 0x08000000 | ( ((u32)patch_main_bin)>>2); // j patch_main_bin 121 | code[0xE4/4] = 0x00000000; // nop 122 | 123 | pspClearDcache(); 124 | pspClearIcache(); 125 | 126 | // goto IPL.bin 127 | ipl_bin_entry = (void *)code; 128 | ipl_bin_entry(); 129 | 130 | return 0; 131 | } 132 | -------------------------------------------------------------------------------- /PANDORA/readme.txt: -------------------------------------------------------------------------------- 1 | ____ __ ____ 2 | /\ _`\ /\ \ /\ _`\ 3 | \ \ \/\_\ \_\ \___\ \ \/\ \ 4 | \ \ \/_/_/\___ __\\ \ \ \ \ 5 | \ \ \L\ \/__/\ \_/ \ \ \_\ \ 6 | \ \____/ \ \_\ \ \____/ 7 | \/___/ \/_/ \/___/ 8 | 9 | PANDORA'S BATTERY 10 | ================= 11 | 12 | A universal PSP unbricker/downgrader by the Prometheus project, also 13 | known as Team C+D. 14 | 15 | REQUIREMENTS 16 | - A spare PSP Battery. Any make will do. Using a spare is best, as it 17 | will not be possible to boot the PSP in its normal state with the 18 | modified battery. 19 | - A spare Memory Stick Pro Duo of less than 4Gb. (256Mb should be 20 | enough for all applications). 21 | - A PSP with a Custom Firmware such as OE, M33 or WC, or a PSP with 22 | the 1.5 original kernel. 23 | 24 | INSTALLATION PROCEDURE 25 | - Connect the PSP to the PC with the Memory Stick inside via the USB 26 | Connection. 27 | - Format the Memory Stick using any utility. 28 | - Use mspformat to format the Memory Stick logically. 29 | - Remove the Memory Stick and disable the USB connection. 30 | - Connect the Memory Stick again via the USB connection of the PSP. 31 | - Manually create the PSP/GAME (optionally PSP/GAME150) folders on the 32 | Memory Stick. 33 | - Copy the "battery" and "installer" programs to the PSP/GAME 34 | (optionally PSP/GAME150) folder. 35 | - Copy the 1.50 official updater as UPDATE.PBP to the root of the 36 | Memory Stick. 37 | - Remove the Memory Stick and disable the USB connection. 38 | - Run "installer" through the firmware on the PSP. This application 39 | will create the firmware files on the root of the Memory Stick, as 40 | well as msipl.bin. 41 | - Connect the Memory Stick again via the USB connection of the PSP. 42 | - Execute "msipl" application on the PC with the msipl.bin to write 43 | the IPL to memory stick. 44 | - Remove the Memory Stick and disable the USB connection. 45 | - Execute "battery" application on the PSP to modify the battery. 46 | - Congratulation, you are now in posession of a "Magic Memory Stick" 47 | and a "JigKick Battery". 48 | 49 | USAGE 50 | - Insert Memory Stick into the PSP 51 | - Remove power cord and insert the JigKick Battery into the PSP. 52 | - A menu appears when the PSP boots. Follow the onscreen information 53 | and instructions. 54 | 55 | NOTES AND RESTRICTIONS 56 | - The firmware in the Memory Stick is not a full 1.50, but a minimal 57 | subset. Therefore, not all applications (such as flashers, or 58 | recovery apps) will load. 59 | - Only Memory Stick Pro Duo are compatible. Memory Stick Duo 60 | (e.g. 32MB sticks) are not supported. 61 | - The IDStorage cannot be totally restored, as there is no known way 62 | to regenerate it properly. 63 | - It is strongly RECOMMENDED to make a flash dump of the PSP before 64 | any downgrading operation. 65 | - There might be a BSOD at the end of the downgrade. This is normal, 66 | and happens on the standard downgraders. 67 | - All hardware revisions known at this day are supported. 68 | - This release contains no Sony-copyrighted material. All required 69 | Sony data is generated from the v1.50 update files. 70 | 71 | CREDITS 72 | - Please do not edit or remove these credits... ;) 73 | - All work done by the Prometheus team aka Team C+D: 74 | 75 | Adrahil (VoidPointer) 76 | Booster 77 | Cswindle (Caretaker) 78 | Dark_AleX (Malyot) 79 | Ditlew 80 | Fanjita (FullerMonty) 81 | Joek2100 (CosmicOverSoul) 82 | Jim 83 | Mathieulh (WiseFellow) 84 | Nem (h1ckeyph0rce) 85 | Psp250 86 | Skylark 87 | TyRaNiD (bockscar) 88 | 89 | - With thanks to everyone who has contributed to the PSPSDK, without which 90 | nothing would have been possible. 91 | -------------------------------------------------------------------------------- /IPL_SDK/psp_nand.c: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | PSP IPL NAND Flash Driver 3 | ****************************************************************************/ 4 | #include 5 | #include "psp_nand.h" 6 | 7 | // 8MB buffer for data 8 | #define BUFFER_SIZE (8*1024*1024) 9 | unsigned char buf_data[BUFFER_SIZE]; 10 | 11 | // 1MB for all area of EXTRA data 12 | unsigned char buf_extra[0x10 * 0x20 * 0x800]; 13 | 14 | /**************************************************************************** 15 | NAND_CTRL(0xbd101004):bit assign 16 | 17 | R/-B : 0x01 18 | ??? : 0x02 19 | -CLE : 0x04 20 | -WE : 0x08 21 | CE : 0x10 22 | ??? : 0x20 23 | ??? : 0x40 24 | WP : 0x80 25 | -RE : 0x100 or 0x200 26 | ALE : 0x200 or 0x100 27 | 28 | ****************************************************************************/ 29 | 30 | /* NAND I/F register s */ 31 | 32 | 33 | #define NAND_STS (volatile u32 *)(0xbd101004) 34 | #define NAND_CTRL (volatile u32 *)(0xbd101004) 35 | #define NAND_CMD (volatile u32 *)(0xbd101008) 36 | #define NAND_ADR (volatile u32 *)(0xbd10100c) 37 | #define NAND_END (volatile u32 *)(0xbd101014) 38 | 39 | #define NAND_AUTO_ADR (volatile u32 *)(0xbd101020) 40 | #define NAND_AUTO_CMD (volatile u32 *)(0xbd101024) 41 | #define NAND_AUTO_STS (volatile u32 *)(0xbd101024) 42 | #define NAND_AUTO_ERR (volatile u32 *)(0xbd101028) 43 | 44 | #define NAND_MODE (volatile u32 *)(0xbd101000) 45 | #define NAND_DAT (volatile u32 *)(0xbd101300) 46 | 47 | #define NAND_DATA (volatile u32 *)(0xbff00000) 48 | #define NAND_EXTRA (volatile u32 *)(0xbff00900) 49 | 50 | /**************************************************************************** 51 | reset CMD 52 | ****************************************************************************/ 53 | static void pspNandReset(void) 54 | { 55 | *NAND_CMD = 0xff; 56 | while( *NAND_STS &0x01 ==0); 57 | *NAND_END = 0x01; 58 | } 59 | 60 | /**************************************************************************** 61 | ****************************************************************************/ 62 | int pspNandReadSector(int sector,u32 *databuf,u32 *extrabuf) 63 | { 64 | u32 *ptr; 65 | int size; 66 | 67 | while( *NAND_STS &0x01 ==0); 68 | 69 | // start command 70 | *NAND_AUTO_ADR = sector<<10; 71 | *NAND_AUTO_CMD = 0x0301; 72 | 73 | while(*NAND_AUTO_STS & 1); 74 | if(*NAND_AUTO_ERR) return -1; 75 | ; 76 | ptr = NAND_DATA; 77 | 78 | extrabuf[0] = ptr[0x900/4]; 79 | extrabuf[1] = ptr[0x904/4]; 80 | extrabuf[2] = ptr[0x908/4]; 81 | ; 82 | for(size=0x200;size>0;size-=4) 83 | *databuf++ = *ptr++; 84 | return 0; 85 | } 86 | 87 | /**************************************************************************** 88 | ****************************************************************************/ 89 | static u16 iplfat_buf[0x200/2]; 90 | static u32 extra_buf[3]; 91 | 92 | int pspNandReadIPLFat(void) 93 | { 94 | int sector; 95 | pspNandReset(); 96 | 97 | sector=0x80; 98 | do{ 99 | if( pspNandReadSector(sector,iplfat_buf,extra_buf) < 0) return 0x8001018c; 100 | sector+=0x20; 101 | }while(extra_buf[1] != 0x6dc64a38); 102 | } 103 | 104 | /**************************************************************************** 105 | ****************************************************************************/ 106 | int pspNandReadIPLBlock(int block,u32 *databuf) 107 | { 108 | int sector; 109 | int size; 110 | 111 | sector = ( (iplfat_buf[block>>2]<<2) | (block & 3) ) * 0x08; 112 | for(size=0;size<8;size++) 113 | { 114 | if( pspNandReadSector(sector,databuf,extra_buf) < 0) return -1; 115 | if(extra_buf[1] != 0x6dc64a38) return -1; 116 | databuf += 0x200/4; 117 | sector++; 118 | } 119 | return 0; 120 | } 121 | 122 | -------------------------------------------------------------------------------- /MS_MULTI_LOADER/iplboot.c: -------------------------------------------------------------------------------- 1 | /* 2 | IPL exploit BOOT LOADER (MS ver) 3 | */ 4 | 5 | #include 6 | 7 | #include "psp_uart.h" 8 | #include "kprintf.h" 9 | #include "patch.h" 10 | #include "syscon.h" 11 | #include "lcdc.h" 12 | #include "cache.h" 13 | 14 | #include "fatload.h" 15 | 16 | #define UART_MESSAGE 0 17 | 18 | /**************************************************************************** 19 | load boot file 20 | ****************************************************************************/ 21 | 22 | #define SENSE_MASK (\ 23 | SYSCON_CTRL_TRIANGLE|SYSCON_CTRL_CIRCLE|SYSCON_CTRL_CROSS|SYSCON_CTRL_RECTANGLE|\ 24 | SYSCON_CTRL_SELECT|SYSCON_CTRL_LTRG|SYSCON_CTRL_RTRG|\ 25 | SYSCON_CTRL_START|SYSCON_CTRL_HOME|SYSCON_CTRL_VOL_UP|SYSCON_CTRL_VOL_DN|\ 26 | SYSCON_CTRL_LCD|SYSCON_CTRL_NOTE|\ 27 | SYSCON_CTRL_ALLOW_UP|SYSCON_CTRL_ALLOW_RT|SYSCON_CTRL_ALLOW_DN|SYSCON_CTRL_ALLOW_LT\ 28 | ) 29 | 30 | const char *select_boot_file(void) 31 | { 32 | u32 ctrl; 33 | 34 | // get PSP buttons 35 | #if 1 36 | _pspSysconGetCtrl1(&ctrl); 37 | Kprintf("\nCONTROL VALUE=%08X\n",ctrl); 38 | #else 39 | u8 lx,ly; 40 | _pspSysconCtrlAStickPower(1); 41 | _pspSysconGetCtrl2(ctrl,&lx,&ly); 42 | Kprintf("\nCONTROL %08X:%02X:%02X\n",ctrl,lx,ly); 43 | #endif 44 | 45 | // positive 46 | ctrl = ~ctrl; 47 | 48 | // LTRG + ALLOW ? 49 | switch(ctrl&SENSE_MASK) 50 | { 51 | case SYSCON_CTRL_LTRG|SYSCON_CTRL_ALLOW_UP: return "ipl/ipl_up.bin"; 52 | case SYSCON_CTRL_LTRG|SYSCON_CTRL_ALLOW_RT: return "ipl/ipl_rt.bin"; 53 | case SYSCON_CTRL_LTRG|SYSCON_CTRL_ALLOW_DN: return "ipl/ipl_dn.bin"; 54 | case SYSCON_CTRL_LTRG|SYSCON_CTRL_ALLOW_LT: return "ipl/ipl_lt.bin"; 55 | case SYSCON_CTRL_LTRG: return "ipl/ipl.bin"; 56 | } 57 | return NULL; 58 | } 59 | 60 | /**************************************************************************** 61 | IPL exploit entry point 62 | ****************************************************************************/ 63 | void entry(void) 64 | { 65 | int flip_led = 0; 66 | void (*entry)(void); 67 | const char *name; 68 | u32 sts; 69 | 70 | #if UART_MESSAGE 71 | // SYNC UART 72 | psp_uart_init(115200); 73 | Kprintf("MS BOOT PROGRAM\n"); 74 | #endif 75 | 76 | // GPIO enable 77 | REG32(0xbc100058) |= 0x02; 78 | REG32(0xbc10007c) |= (1<<26) | 0xc8; 79 | REG32(0xbe240000) |= 0xc8; 80 | 81 | REG32(0xbc100058) |= 0x00800000; 82 | REG32(0xbc100050) |= 0x0000608E; 83 | REG32(0xbc10004c) &= 0xFFFFFBF7; 84 | REG32(0xbc100078) &= 0x00000002; 85 | #if 0 86 | dl 0D500010,00000001 ; [$bd500010] = 00000001 87 | dl 3D500010,00000001 ; while( [$bd500010] & 1) 88 | dl 0D500040,00000001 ; [$bd500040] = 00000001 89 | dl F0000000 ; end 90 | 91 | #endif 92 | 93 | // SYSCON power controll 94 | pspSyscon_init(); 95 | pspSysconCtrlLED(0,1); 96 | pspSysconCtrlLED(1,1); 97 | pspSysconCtrlHRPower(1); 98 | pspSysconCtrlMsPower(1); 99 | 100 | // MS/FAT init 101 | ms_fat_init(); 102 | 103 | // laod boot file 104 | name = select_boot_file(); 105 | if(name==NULL) 106 | { 107 | // reset reboot 108 | Kprintf("Reset for NAND Flash BOOT\n\n "); 109 | pspSysconResetDevice(1); 110 | } 111 | #if UART_MESSAGE 112 | Kprintf("Loading %s\n",name); 113 | #endif 114 | entry = (void *)0x040e0000; 115 | if( (entry = ms_load_bootloader(name)) != 0 ) 116 | { 117 | #if UART_MESSAGE 118 | Kprintf("EXECUTE %s(%08x)\n",name,entry); 119 | #endif 120 | // goto loaded PROGRAM 121 | pspClearDcache(); 122 | pspClearIcache(); 123 | entry(); 124 | } 125 | 126 | #if UART_MESSAGE 127 | Kprintf("MS LOAD/BOOT ERROR\n"); 128 | #endif 129 | 130 | // message to UART when boot error 131 | sts = pspSysconNop(); 132 | while(1) 133 | { 134 | // both LED flash 135 | REG32(0xbe24000c) = 0xC0; 136 | Syscon_wait(125000/4); 137 | REG32(0xbe240008) = 0xC0; 138 | Syscon_wait(125000/4); 139 | 140 | if( !(sts&SYSCON_STS_POWER_SW_ON) && ((sts=pspSysconNop()) & SYSCON_STS_POWER_SW_ON) ) 141 | { 142 | #if UART_MESSAGE 143 | Kprintf("Power OFF\n\n "); 144 | #endif 145 | pspSysconPowerStandby(); 146 | } 147 | } 148 | // restart PRE-IPL 149 | } 150 | -------------------------------------------------------------------------------- /ML_MAIN_BIN_DUMPER/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | PSP IPL main.bin dumper 3 | */ 4 | 5 | #include 6 | 7 | #include "psp_uart.h" 8 | #include "kprintf.h" 9 | #include "patch.h" 10 | #include "syscon.h" 11 | #include "cache.h" 12 | 13 | #include "memstk.h" 14 | #include "tff.h" /* Tiny-FatFs declarations */ 15 | #include "fatload.h" 16 | 17 | #define DUMP_MAIN_BIN 1 18 | 19 | // load IPL from ms file (or NAND Flash) 20 | #define LOAD_IPL_FILE_NAME "/ipl.bin" 21 | 22 | // load IPL from ms file (or NAND Flash) 23 | #define MAIN_BIN_FILE_NAME "/ipl_main.bin" 24 | #define MAIN_BIN_SIZE 0x010000 25 | 26 | /**************************************************************************** 27 | title message for header 28 | ****************************************************************************/ 29 | const char __title__[] __attribute__ (( section (".init"))) = "IPL main.bin DUMPER"; 30 | 31 | /**************************************************************************** 32 | reset PSP 33 | ****************************************************************************/ 34 | void reboot_psp(void) 35 | { 36 | // reset reboot 37 | Kprintf("Reset PSP\n\n"); 38 | pspSysconResetDevice(1); 39 | while(1); 40 | } 41 | 42 | /**************************************************************************** 43 | INTERRIGENT SEARCH 44 | ****************************************************************************/ 45 | static u32 mips_regs[32]; 46 | static void parge_regs(void) 47 | { 48 | int i; 49 | for(i=0;i<32;i++) mips_regs[i] = 0; 50 | } 51 | 52 | u32 *search_long_jump(void *start,void *end,u32 jump_address) 53 | { 54 | u32 *ptr; 55 | int reg; 56 | 57 | parge_regs(); 58 | for(ptr=(u32 *)start;ptr<(u32 *)end;ptr++) 59 | { 60 | if( (ptr[0] & 0xffe00000) == MIPS_LUI(0,0) ) 61 | { 62 | reg = (ptr[0]>>16) & 31; 63 | mips_regs[reg]=ptr[0]<<16; 64 | Kprintf("%08X:LUI R%2d,%08X\n",(u32)ptr,reg,mips_regs[reg]); 65 | } 66 | 67 | if( (ptr[0] & 0xfc1fffff) == MIPS_JR(0) ) 68 | { 69 | reg = (ptr[0]>>21)&31; 70 | Kprintf("%08X:JR r%2d[%08X]\n",(u32)ptr,reg,mips_regs[reg]); 71 | if(mips_regs[reg]==jump_address) 72 | { 73 | Kprintf("Found main.bin call %08X , entry %08X\n",(u32)ptr,mips_regs[reg]); 74 | // main_bin_entry = mips_regs[reg]; 75 | return ptr; 76 | } 77 | parge_regs(); 78 | } 79 | 80 | if( ptr[0] & 0xfc000000 == MIPS_J(0) ) 81 | { 82 | Kprintf("%08X:J\n"); 83 | parge_regs(); 84 | } 85 | } 86 | return 0; 87 | } 88 | 89 | /**************************************************************************** 90 | before jump main.bin 91 | 92 | (after decrypt/loaded main.bin) 93 | ****************************************************************************/ 94 | void patch_main_bin(void) 95 | { 96 | u32 *code = (u32 *)0x04000000; 97 | 98 | Kprintf("dump main.bin\n"); 99 | ms_save_file(MAIN_BIN_FILE_NAME,(void *)0x04000000,MAIN_BIN_SIZE); 100 | 101 | Kprintf("\nMAIN.BIN DUMPED!\n"); 102 | 103 | // reset reboot 104 | reboot_psp(); 105 | } 106 | 107 | /**************************************************************************** 108 | entry point 109 | ****************************************************************************/ 110 | int main(void) 111 | { 112 | void (*ipl_bin_entry)(void); 113 | u32 *patch_point; 114 | 115 | Kprintf("ENTER:%s\n",__title__); 116 | 117 | // init I/O 118 | pspSyscon_init(); 119 | pspSysconCtrlLED(0,1); 120 | pspSysconCtrlLED(1,1); 121 | pspSysconCtrlMsPower(1); 122 | 123 | // MS/FAT system 124 | ms_fat_init(); 125 | 126 | #ifdef LOAD_IPL_FILE_NAME 127 | // load FW1.50 IPL for initialize DDR-SDRAM controller 128 | if(ms_load_ipl(LOAD_IPL_FILE_NAME) == NULL) 129 | { 130 | Kprintf("can't load %s\n",LOAD_IPL_FILE_NAME); 131 | while(1); 132 | } 133 | #else 134 | // load IPL from NAND flash 135 | nand_load_ipl(); 136 | #endif 137 | 138 | Kprintf("IPL loaded\n"); 139 | 140 | // interrigent HOOK , "jump main.bin" 141 | patch_point = search_long_jump(0x040f0000,0x040f1000,0x04000000); 142 | if(!patch_point) 143 | { 144 | reboot_psp(); 145 | } 146 | // hook JR instruction 147 | patch_point[0] = MIPS_J(patch_main_bin); 148 | 149 | // clear main.bin area 150 | u32 *ptr; 151 | for(ptr=(u32 *)0x04000000;ptr<(u32 *)(0x04080000+MAIN_BIN_SIZE);ptr++) *ptr=0; 152 | 153 | pspClearDcache(); 154 | pspClearIcache(); 155 | 156 | // goto IPL.bin 157 | ipl_bin_entry = (u32 *)0x040f0000; 158 | ipl_bin_entry(); 159 | 160 | return 0; 161 | } 162 | -------------------------------------------------------------------------------- /IPL_SDK/kprintf.c: -------------------------------------------------------------------------------- 1 | /* 2 | Kprintf 3 | */ 4 | #include 5 | #include 6 | #include "psp_uart.h" 7 | #include "kprintf.h" 8 | 9 | ///////////////////////////////////////////////////////////////////////////// 10 | ///////////////////////////////////////////////////////////////////////////// 11 | #define _PUTC(VAL) uart_dbg_putc(0,(VAL)) 12 | 13 | ///////////////////////////////////////////////////////////////////////////// 14 | ///////////////////////////////////////////////////////////////////////////// 15 | #define DIFF_INT_LONG 0 /* support 'l' parameter ? */ 16 | 17 | #define FLAG_PLUS 0x80 18 | #define FLAG_ZERO 0x40 19 | #define FLAG_UNSIGN 0x20 20 | 21 | static inline int numtofile(unsigned long number,int place,char flags,int deci,int chra) 22 | { 23 | unsigned long num; 24 | unsigned long digit = 1; 25 | int stores = 0; 26 | 27 | /* '+','-' */ 28 | if(!(flags&FLAG_UNSIGN)) 29 | { 30 | if(((long)number)<0) 31 | { 32 | _PUTC('-'); 33 | stores++; 34 | number = -number; 35 | }else if(flags&FLAG_PLUS) 36 | { 37 | _PUTC(number==0 ? ' ' : '+'); 38 | stores++; 39 | } 40 | } 41 | 42 | /* max digit */ 43 | while( (place>1) || (number >= (digit*deci)) ) 44 | { 45 | // maximum check 46 | if(digit > digit*deci) break; 47 | digit *= deci; 48 | place--; 49 | } 50 | 51 | /* head '0' or ' ' */ 52 | while( digit>1 ) 53 | { 54 | if( (number/digit)%deci > 0) break; 55 | _PUTC(flags&FLAG_ZERO ? '0':' '); 56 | stores++; 57 | digit /= deci; 58 | } 59 | 60 | while( digit ) 61 | { 62 | num = (number/digit)%deci; 63 | if( num < 10 ) 64 | _PUTC('0'+num); 65 | else 66 | _PUTC(chra+num-10); 67 | stores++; 68 | digit /= deci; 69 | } 70 | return stores; 71 | } 72 | 73 | /* format decomposer */ 74 | static int __vprintf(const char *format,va_list arg) 75 | { 76 | char flags; 77 | int len_n,len_e; 78 | char *sptr; 79 | #if DIFF_INT_LONG 80 | char size; 81 | #endif 82 | int stores = 0; 83 | long val_long; 84 | unsigned char base; 85 | 86 | while(*format) 87 | { 88 | if(*format!='%') 89 | _PUTC(*format++); 90 | else 91 | { /* % entry */ 92 | format++; 93 | 94 | flags = 0; 95 | /* head '+' */ 96 | if(*format == '+') 97 | { 98 | flags |= FLAG_PLUS; 99 | format++; 100 | } else if(*format == '-') 101 | format++; 102 | 103 | /* head '0' */ 104 | if(*format == '0') 105 | { 106 | flags |= FLAG_ZERO; 107 | format++; 108 | } 109 | 110 | /* length */ 111 | len_n = len_e = 0; 112 | while(*format>='0' && *format<='9') 113 | len_n = len_n*10 + (*format++)-'0'; 114 | /* '.' */ 115 | if(*format=='.') 116 | { 117 | format++; 118 | while(*format>='0' && *format<='9') 119 | len_e = len_e*10 + (*format++)-'0'; 120 | } 121 | #if DIFF_INT_LONG 122 | size = sizeof(int); /* int */ 123 | #endif 124 | base = 10; 125 | again: 126 | /* type check */ 127 | switch(*format|0x20) 128 | { 129 | case 'l': /* longlong / long */ 130 | #if DIFF_INT_LONG 131 | size = (*format&0x20) ? sizeof(long) : sizeof(longlong); 132 | #endif 133 | format++; 134 | goto again; 135 | case 'u': 136 | flags |= FLAG_UNSIGN; 137 | format++; 138 | goto again; 139 | 140 | case 'c': 141 | _PUTC((char)va_arg(arg,int)); 142 | break; 143 | 144 | case 'x': 145 | flags |= FLAG_UNSIGN; 146 | base = 16; 147 | case 'd': 148 | #if DIFF_INT_LONG 149 | switch(size) 150 | { 151 | case 1: val_long = va_arg(arg,long); 152 | case 2: val_long = va_arg(arg,longlong); 153 | default: 154 | if(flags&FLAG_UNSIGN) 155 | val_long = (unsigned int)va_arg(arg,unsigned int); 156 | else 157 | val_long = va_arg(arg,int); 158 | } 159 | #else 160 | if(flags&FLAG_UNSIGN) 161 | val_long = (unsigned int)va_arg(arg,int); 162 | else 163 | val_long = va_arg(arg,int); 164 | #endif 165 | stores += numtofile(val_long,len_n,flags,base,*format-'X'+'A'); 166 | break; 167 | case 's': 168 | sptr = va_arg(arg,char *); 169 | while(*sptr) 170 | { 171 | _PUTC(*sptr++); 172 | stores++; 173 | } 174 | break; 175 | default: 176 | break; 177 | } 178 | if(*format) format++; 179 | } 180 | } 181 | return stores; 182 | } 183 | 184 | ///////////////////////////////////////////////////////////////////////////// 185 | // Kprintf for PSP uart 186 | ///////////////////////////////////////////////////////////////////////////// 187 | void Kprintf(const char *text,...) 188 | { 189 | va_list arg; 190 | 191 | uart_dbg_putc(0,0x200); 192 | va_start(arg,text); 193 | __vprintf(text,arg); 194 | va_end(arg); 195 | uart_dbg_putc(0,0x201); 196 | } 197 | 198 | -------------------------------------------------------------------------------- /ML_DDRDUMPER/fatload.c: -------------------------------------------------------------------------------- 1 | /* 2 | MS FAT file boot loader 3 | */ 4 | 5 | #include 6 | #include "kprintf.h" 7 | #include "cache.h" 8 | #include "syscon.h" 9 | #include "kirk.h" 10 | //#include "preipl.h" 11 | 12 | #include "memstk.h" 13 | #include "tff.h" /* Tiny-FatFs declarations */ 14 | 15 | #include "patch.h" 16 | #include "patch.h" 17 | 18 | /**************************************************************************** 19 | IPL load BOOT 20 | ****************************************************************************/ 21 | static int check_ipl_address(u32 address) 22 | { 23 | if(address >= 0x04000000 && address < 0x04200000) return 1; 24 | return 0; 25 | } 26 | 27 | static int check_ipl_address2(u32 address,u32 offset) 28 | { 29 | return check_ipl_address(address+offset); 30 | } 31 | 32 | /**************************************************************************** 33 | IPL load BOOT 34 | ****************************************************************************/ 35 | static FATFS FileSystem; 36 | static FIL FileObject; 37 | 38 | extern int _ms_init(void); 39 | 40 | int ms_load_file(const char *path,void *top_addr) 41 | { 42 | FRESULT result; 43 | WORD readed; 44 | BYTE *load_addr; 45 | int ttl_read; 46 | 47 | load_addr = (BYTE *)top_addr; 48 | 49 | result = f_mount(0,&FileSystem); 50 | if(result!=0) 51 | { 52 | //Kprintf("f_mount error %08X\n",result); 53 | return -1; 54 | } 55 | 56 | result = f_open(&FileObject,path,FA_READ|FA_OPEN_EXISTING); 57 | if(result!=0) 58 | { 59 | //Kprintf("f_open %s error\n",path); 60 | return -1; 61 | } 62 | 63 | ttl_read = 0; 64 | do{ 65 | result = f_read(&FileObject,load_addr,0x8000,&readed); 66 | if(result!=0) 67 | { 68 | //Kprintf("f_read error\n"); 69 | return -1; 70 | } 71 | //Kprintf("f_read addr=%08X size=%08X\n",(int)load_addr,readed); 72 | load_addr += readed; 73 | ttl_read += readed; 74 | }while(readed!=0); 75 | //Kprintf("readed %d bytes\n",ttl_read); 76 | 77 | f_close(&FileObject); 78 | 79 | return ttl_read; 80 | } 81 | 82 | /**************************************************************************** 83 | save file 84 | ****************************************************************************/ 85 | int ms_save_file(const char *path,const void *data,int size) 86 | { 87 | FRESULT result; 88 | WORD writed; 89 | int num_write; 90 | int block_cnt = 0; 91 | 92 | // 93 | result = f_mount(0,&FileSystem); 94 | if(result!=0) 95 | { 96 | Kprintf("f_mount error %08X\n",result); 97 | return -1; 98 | } 99 | 100 | result = f_open(&FileObject,path,FA_WRITE|FA_CREATE_ALWAYS); 101 | if(result!=0) 102 | { 103 | Kprintf("f_open %s error\n",path); 104 | return -1; 105 | } 106 | 107 | while(size) 108 | { 109 | num_write = size>0x8000 ? 0x8000 : size; 110 | result = f_write(&FileObject,data,num_write,&writed); 111 | if(result!=0 || num_write!=writed) 112 | { 113 | Kprintf("f_write error\n"); 114 | return -1; 115 | } 116 | //Kprintf("f_write %08X:%04X\n",(int)data,writed); 117 | data += num_write; 118 | size -= num_write; 119 | 120 | // flip LED 121 | block_cnt++; 122 | if(block_cnt&1) 123 | REG32(0xbe24000c) = 0x40; 124 | else 125 | REG32(0xbe240008) = 0x40; 126 | if( (block_cnt%32)==0) 127 | { 128 | // clear WDT 129 | pspSysconNop(); 130 | Kprintf("Left %08X\n",size); 131 | } 132 | } 133 | //Kprintf("readed %d bytes\n",ttl_read); 134 | f_close(&FileObject); 135 | 136 | return 0; 137 | } 138 | 139 | 140 | /**************************************************************************** 141 | universal IPL/file loader 142 | 143 | 1.encrypted IPL BLOCK DATA 144 | 2.decrypted IPL BLOCK DATA 145 | 3.binary included header of decrypted IPL BLOCK DATA. 146 | 4.plain binaly. 147 | 148 | ****************************************************************************/ 149 | //static DWORD ipl_buf[0x1000/4] __attribute__((aligned(256))); 150 | //static DWORD ipl_buf2[0x1000/4] __attribute__((aligned(64))); 151 | 152 | static DWORD *ipl_buf = (DWORD *)0xbfd00000; 153 | 154 | void *ms_load_ipl(const char *path) 155 | 156 | { 157 | FRESULT result; 158 | WORD readed; 159 | DWORD *src; 160 | 161 | DWORD *top; 162 | DWORD size; 163 | void *entry; 164 | DWORD sum; 165 | int binary_type = 0; 166 | 167 | result = f_mount(0,&FileSystem); 168 | if(result!=0) 169 | { 170 | Kprintf("f_mount error %08X\n",result); 171 | return 0; 172 | } 173 | 174 | result = f_open(&FileObject,path,FA_READ|FA_OPEN_EXISTING); 175 | if(result!=0) 176 | { 177 | Kprintf("f_open %s error\n",path); 178 | return 0; 179 | } 180 | 181 | do{ 182 | result = f_read(&FileObject,ipl_buf,0x1000,&readed); 183 | if(result!=0) 184 | { 185 | Kprintf("f_read error\n"); 186 | entry = 0; 187 | goto error; 188 | } 189 | 190 | if(binary_type==0) 191 | { 192 | // chech decrypted HEADER 193 | top = (DWORD *)(ipl_buf[0]); 194 | size = (ipl_buf[1]); 195 | entry= (void *)(ipl_buf[2]); 196 | sum = (ipl_buf[3]); 197 | if( 198 | check_ipl_address(top) && 199 | check_ipl_address(top+size) && 200 | (entry==0 || ( entry >= top && entry<=(top+size))) && 201 | sum == 0 202 | ){ 203 | // decrypted with header 204 | binary_type = 2; 205 | } else if( 206 | ipl_buf[0x60/4]==0x01 && 207 | ipl_buf[0x64/4]==0 && 208 | ipl_buf[0x68/4]==0 && 209 | ipl_buf[0x6c/4]==0xffffffff 210 | ) 211 | { 212 | // encrypted IPL 213 | binary_type = 1; 214 | } 215 | } 216 | 217 | // decrypt block 218 | if(binary_type==1) 219 | { 220 | if( pspKirkProc(ipl_buf,0x1000,ipl_buf,0x1000,0x01) < 0) 221 | { 222 | Kprintf("Decrypt error\n"); 223 | entry = 0; 224 | goto error; 225 | } 226 | } 227 | 228 | // load BLOCK 229 | top = (ipl_buf[0]); 230 | size = (ipl_buf[1]); 231 | entry= (ipl_buf[2]); 232 | sum = (ipl_buf[3]); 233 | src = &(ipl_buf[4]); 234 | //Kprintf("TOP %08X SIZE %08X ENTRY %08X SUM %08X\n",top,size,entry,sum); 235 | 236 | while(size) 237 | { 238 | *top++ = *src++; 239 | size -= 4; 240 | } 241 | 242 | }while(entry==0); 243 | //Kprintf("readed %d bytes\n",ttl_read); 244 | error: 245 | f_close(&FileObject); 246 | 247 | return entry; 248 | } 249 | 250 | /**************************************************************************** 251 | initialize FAT system 252 | ****************************************************************************/ 253 | int ms_fat_init(void) 254 | { 255 | pspMsInit(); 256 | } 257 | -------------------------------------------------------------------------------- /ML_RECOVERY_LOADER/fatload.c: -------------------------------------------------------------------------------- 1 | /* 2 | MS FAT file boot loader 3 | 4 | PANDORA'S IPL edition 5 | */ 6 | 7 | #include 8 | #include "kprintf.h" 9 | #include "cache.h" 10 | #include "syscon.h" 11 | 12 | #include "memstk.h" 13 | #include "tff.h" /* Tiny-FatFs declarations */ 14 | 15 | #include "patch.h" 16 | #include "patch.h" 17 | 18 | #define SUPPORT_PANDORAS_MS_IPL 1 19 | 20 | /**************************************************************************** 21 | IPL load BOOT 22 | ****************************************************************************/ 23 | static int check_ipl_address(u32 address) 24 | { 25 | if(address >= 0x04000000 && address < 0x04200000) return 1; 26 | return 0; 27 | } 28 | 29 | static int check_ipl_address2(u32 address,u32 offset) 30 | { 31 | return check_ipl_address(address+offset); 32 | } 33 | 34 | /**************************************************************************** 35 | ****************************************************************************/ 36 | int ms_poll_access(int cnt) 37 | { 38 | // flip LED 39 | if(cnt&1) 40 | REG32(0xbe24000c) = 0x40; 41 | else 42 | REG32(0xbe240008) = 0x40; 43 | if( (cnt%32)==0) 44 | { 45 | // clear WDT 46 | pspSysconNop(); 47 | return 1; 48 | } 49 | return 0; 50 | } 51 | 52 | /**************************************************************************** 53 | IPL load BOOT 54 | ****************************************************************************/ 55 | static FATFS FileSystem; 56 | static FIL FileObject; 57 | 58 | extern int _ms_init(void); 59 | 60 | int ms_load_file(const char *path,void *top_addr) 61 | { 62 | FRESULT result; 63 | WORD readed; 64 | BYTE *load_addr; 65 | int ttl_read; 66 | int block_cnt = 0; 67 | 68 | load_addr = (BYTE *)top_addr; 69 | 70 | result = f_mount(0,&FileSystem); 71 | if(result!=0) 72 | { 73 | //Kprintf("f_mount error %08X\n",result); 74 | return -1; 75 | } 76 | 77 | result = f_open(&FileObject,path,FA_READ|FA_OPEN_EXISTING); 78 | if(result!=0) 79 | { 80 | //Kprintf("f_open %s error\n",path); 81 | return -1; 82 | } 83 | 84 | ttl_read = 0; 85 | do{ 86 | result = f_read(&FileObject,load_addr,0x8000,&readed); 87 | if(result!=0) 88 | { 89 | //Kprintf("f_read error\n"); 90 | return -1; 91 | } 92 | //Kprintf("f_read addr=%08X size=%08X\n",(int)load_addr,readed); 93 | load_addr += readed; 94 | ttl_read += readed; 95 | 96 | ms_poll_access(block_cnt++); 97 | 98 | }while(readed!=0); 99 | //Kprintf("readed %d bytes\n",ttl_read); 100 | 101 | f_close(&FileObject); 102 | REG32(0xbe24000c) = 0x40; 103 | 104 | return ttl_read; 105 | } 106 | 107 | /**************************************************************************** 108 | save file 109 | ****************************************************************************/ 110 | int ms_save_file(const char *path,const void *data,int size) 111 | { 112 | FRESULT result; 113 | WORD writed; 114 | int num_write; 115 | int block_cnt = 0; 116 | 117 | // 118 | result = f_mount(0,&FileSystem); 119 | if(result!=0) 120 | { 121 | Kprintf("f_mount error %08X\n",result); 122 | return -1; 123 | } 124 | 125 | result = f_open(&FileObject,path,FA_WRITE|FA_CREATE_ALWAYS); 126 | if(result!=0) 127 | { 128 | Kprintf("f_open %s error\n",path); 129 | return -1; 130 | } 131 | 132 | while(size) 133 | { 134 | num_write = size>0x8000 ? 0x8000 : size; 135 | result = f_write(&FileObject,data,num_write,&writed); 136 | if(result!=0 || num_write!=writed) 137 | { 138 | Kprintf("f_write error\n"); 139 | return -1; 140 | } 141 | //Kprintf("f_write %08X:%04X\n",(int)data,writed); 142 | data += num_write; 143 | size -= num_write; 144 | 145 | if( ms_poll_access(block_cnt++) ) 146 | { 147 | Kprintf("Left %08X\n",size); 148 | } 149 | } 150 | //Kprintf("readed %d bytes\n",ttl_read); 151 | f_close(&FileObject); 152 | REG32(0xbe24000c) = 0x40; 153 | 154 | return 0; 155 | } 156 | 157 | /**************************************************************************** 158 | PSP_IPL loader 159 | 160 | 1.encrypted IPL BLOCK DATA (1000h BLOCK) 161 | 2.decrypted IPL BLOCK DATA (1000h BLOCK) 162 | 163 | ****************************************************************************/ 164 | static DWORD *ipl_buf = (DWORD *)0xbfd00000; 165 | 166 | void *ms_load_ipl(const char *path) 167 | { 168 | FRESULT result; 169 | WORD readed; 170 | DWORD *src; 171 | 172 | DWORD *top; 173 | DWORD size; 174 | void *entry; 175 | DWORD sum; 176 | int binary_type = 0; 177 | 178 | result = f_mount(0,&FileSystem); 179 | if(result!=0) 180 | { 181 | Kprintf("f_mount error %08X\n",result); 182 | return 0; 183 | } 184 | 185 | result = f_open(&FileObject,path,FA_READ|FA_OPEN_EXISTING); 186 | if(result!=0) 187 | { 188 | Kprintf("f_open %s error\n",path); 189 | return 0; 190 | } 191 | 192 | #if SUPPORT_PANDORAS_MS_IPL 193 | /* 194 | see ms_ipl.bin of Pandora's Battery Recovery Menu 195 | 196 | 0x0000-0x0fff : IPL EXPLOIT 1st boot loader 197 | 0x1000-0x3fff : PATCH.BIN(0x040e0000-) , boot.bin patch loader , called after setup main.bin 198 | 0x4000-end : each 0x1000 decrypted block of 1.50 IPL data 199 | */ 200 | Kprintf("bypass IPL exploit block\n"); 201 | result = f_read(&FileObject,ipl_buf,0x1000,&readed); 202 | 203 | Kprintf("loading patcher.bin\n"); 204 | result = f_read(&FileObject,(void *)(0x040e0000),0x3000,&readed); 205 | #endif 206 | 207 | do{ 208 | result = f_read(&FileObject,ipl_buf,0x1000,&readed); 209 | if(result!=0) 210 | { 211 | Kprintf("f_read error\n"); 212 | entry = 0; 213 | goto error; 214 | } 215 | 216 | if(binary_type==0) 217 | { 218 | // chech decrypted HEADER 219 | top = (DWORD *)(ipl_buf[0]); 220 | size = (ipl_buf[1]); 221 | entry= (void *)(ipl_buf[2]); 222 | sum = (ipl_buf[3]); 223 | if( 224 | check_ipl_address(top) && 225 | check_ipl_address(top+size) && 226 | (entry==0 || ( entry >= top && entry<=(top+size))) && 227 | sum == 0 228 | ){ 229 | // decrypted with header 230 | Kprintf("Decrypted IPL\n"); 231 | binary_type = 2; 232 | } else if( 233 | ipl_buf[0x60/4]==0x01 && 234 | ipl_buf[0x64/4]==0 && 235 | ipl_buf[0x68/4]==0) 236 | { 237 | // encrypted IPL 238 | Kprintf("Encrypted IPL\n"); 239 | binary_type = 1; 240 | } 241 | } 242 | 243 | // decrypt block 244 | if(binary_type==1) 245 | { 246 | if( pspKirkProc(ipl_buf,0x1000,ipl_buf,0x1000,0x01) < 0) 247 | { 248 | Kprintf("Decrypt error\n"); 249 | entry = 0; 250 | goto error; 251 | } 252 | } 253 | 254 | // load BLOCK 255 | top = (ipl_buf[0]); 256 | size = (ipl_buf[1]); 257 | entry= (ipl_buf[2]); 258 | sum = (ipl_buf[3]); 259 | src = &(ipl_buf[4]); 260 | Kprintf("TOP %08X SIZE %08X ENTRY %08X SUM %08X\n",top,size,entry,sum); 261 | 262 | while(size) 263 | { 264 | *top++ = *src++; 265 | size -= 4; 266 | } 267 | 268 | }while(entry==0); 269 | //Kprintf("readed %d bytes\n",ttl_read); 270 | error: 271 | f_close(&FileObject); 272 | 273 | return entry; 274 | } 275 | 276 | /**************************************************************************** 277 | initialize FAT system 278 | ****************************************************************************/ 279 | int ms_fat_init(void) 280 | { 281 | pspMsInit(); 282 | } 283 | -------------------------------------------------------------------------------- /ML_BIOS_DUMPER/fatload.c: -------------------------------------------------------------------------------- 1 | /* 2 | MS FAT file boot loader 3 | */ 4 | 5 | #include 6 | #include "kprintf.h" 7 | #include "cache.h" 8 | #include "syscon.h" 9 | #include "kirk.h" 10 | //#include "preipl.h" 11 | 12 | #include "memstk.h" 13 | #include "tff.h" /* Tiny-FatFs declarations */ 14 | 15 | #include "patch.h" 16 | #include "patch.h" 17 | 18 | /**************************************************************************** 19 | IPL load BOOT 20 | ****************************************************************************/ 21 | static int check_ipl_address(u32 address) 22 | { 23 | if(address >= 0x04000000 && address < 0x04200000) return 1; 24 | return 0; 25 | } 26 | 27 | static int check_ipl_address2(u32 address,u32 offset) 28 | { 29 | return check_ipl_address(address+offset); 30 | } 31 | 32 | /**************************************************************************** 33 | ****************************************************************************/ 34 | int ms_poll_access(int cnt) 35 | { 36 | // flip LED 37 | if(cnt&1) 38 | REG32(0xbe24000c) = 0x40; 39 | else 40 | REG32(0xbe240008) = 0x40; 41 | if( (cnt%32)==0) 42 | { 43 | // clear WDT 44 | pspSysconNop(); 45 | return 1; 46 | } 47 | return 0; 48 | } 49 | 50 | /**************************************************************************** 51 | IPL load BOOT 52 | ****************************************************************************/ 53 | static FATFS FileSystem; 54 | static FIL FileObject; 55 | 56 | extern int _ms_init(void); 57 | 58 | int ms_load_file(const char *path,void *top_addr) 59 | { 60 | FRESULT result; 61 | WORD readed; 62 | BYTE *load_addr; 63 | int ttl_read; 64 | int block_cnt = 0; 65 | 66 | load_addr = (BYTE *)top_addr; 67 | 68 | result = f_mount(0,&FileSystem); 69 | if(result!=0) 70 | { 71 | //Kprintf("f_mount error %08X\n",result); 72 | return -1; 73 | } 74 | 75 | result = f_open(&FileObject,path,FA_READ|FA_OPEN_EXISTING); 76 | if(result!=0) 77 | { 78 | //Kprintf("f_open %s error\n",path); 79 | return -1; 80 | } 81 | 82 | ttl_read = 0; 83 | do{ 84 | result = f_read(&FileObject,load_addr,0x8000,&readed); 85 | if(result!=0) 86 | { 87 | //Kprintf("f_read error\n"); 88 | return -1; 89 | } 90 | //Kprintf("f_read addr=%08X size=%08X\n",(int)load_addr,readed); 91 | load_addr += readed; 92 | ttl_read += readed; 93 | 94 | ms_poll_access(block_cnt++); 95 | 96 | }while(readed!=0); 97 | //Kprintf("readed %d bytes\n",ttl_read); 98 | 99 | f_close(&FileObject); 100 | REG32(0xbe24000c) = 0x40; 101 | 102 | return ttl_read; 103 | } 104 | 105 | /**************************************************************************** 106 | save file 107 | ****************************************************************************/ 108 | int ms_save_file(const char *path,const void *data,int size) 109 | { 110 | FRESULT result; 111 | WORD writed; 112 | int num_write; 113 | int block_cnt = 0; 114 | 115 | // 116 | result = f_mount(0,&FileSystem); 117 | if(result!=0) 118 | { 119 | Kprintf("f_mount error %08X\n",result); 120 | return -1; 121 | } 122 | 123 | result = f_open(&FileObject,path,FA_WRITE|FA_CREATE_ALWAYS); 124 | if(result!=0) 125 | { 126 | Kprintf("f_open %s error\n",path); 127 | return -1; 128 | } 129 | 130 | while(size) 131 | { 132 | num_write = size>0x8000 ? 0x8000 : size; 133 | result = f_write(&FileObject,data,num_write,&writed); 134 | if(result!=0 || num_write!=writed) 135 | { 136 | Kprintf("f_write error\n"); 137 | return -1; 138 | } 139 | //Kprintf("f_write %08X:%04X\n",(int)data,writed); 140 | data += num_write; 141 | size -= num_write; 142 | 143 | if( ms_poll_access(block_cnt++) ) 144 | { 145 | Kprintf("Left %08X\n",size); 146 | } 147 | } 148 | //Kprintf("readed %d bytes\n",ttl_read); 149 | f_close(&FileObject); 150 | REG32(0xbe24000c) = 0x40; 151 | 152 | return 0; 153 | } 154 | 155 | /**************************************************************************** 156 | PSP_IPL loader 157 | 158 | 1.encrypted IPL BLOCK DATA (1000h BLOCK) 159 | 2.decrypted IPL BLOCK DATA (1000h BLOCK) 160 | 161 | ****************************************************************************/ 162 | static DWORD *ipl_buf = (DWORD *)0xbfd00000; 163 | 164 | void *ms_load_ipl(const char *path) 165 | { 166 | FRESULT result; 167 | WORD readed; 168 | DWORD *src; 169 | 170 | DWORD *top; 171 | DWORD size; 172 | void *entry; 173 | DWORD sum; 174 | int binary_type = 0; 175 | 176 | result = f_mount(0,&FileSystem); 177 | if(result!=0) 178 | { 179 | Kprintf("f_mount error %08X\n",result); 180 | return 0; 181 | } 182 | 183 | result = f_open(&FileObject,path,FA_READ|FA_OPEN_EXISTING); 184 | if(result!=0) 185 | { 186 | Kprintf("f_open %s error\n",path); 187 | return 0; 188 | } 189 | 190 | do{ 191 | result = f_read(&FileObject,ipl_buf,0x1000,&readed); 192 | if(result!=0) 193 | { 194 | Kprintf("f_read error\n"); 195 | entry = 0; 196 | goto error; 197 | } 198 | 199 | if(binary_type==0) 200 | { 201 | // chech decrypted HEADER 202 | top = (DWORD *)(ipl_buf[0]); 203 | size = (ipl_buf[1]); 204 | entry= (void *)(ipl_buf[2]); 205 | sum = (ipl_buf[3]); 206 | if( 207 | check_ipl_address(top) && 208 | check_ipl_address(top+size) && 209 | (entry==0 || ( entry >= top && entry<=(top+size))) && 210 | sum == 0 211 | ){ 212 | // decrypted with header 213 | binary_type = 2; 214 | } else if( 215 | ipl_buf[0x60/4]==0x01 && 216 | ipl_buf[0x64/4]==0 && 217 | ipl_buf[0x68/4]==0 218 | ) 219 | { 220 | // encrypted IPL 221 | binary_type = 1; 222 | } 223 | } 224 | 225 | // decrypt block 226 | if(binary_type==1) 227 | { 228 | if( pspKirkProc(ipl_buf,0x1000,ipl_buf,0x1000,0x01) < 0) 229 | { 230 | Kprintf("Decrypt error\n"); 231 | entry = 0; 232 | goto error; 233 | } 234 | } 235 | 236 | // load BLOCK 237 | top = (ipl_buf[0]); 238 | size = (ipl_buf[1]); 239 | entry= (ipl_buf[2]); 240 | sum = (ipl_buf[3]); 241 | src = &(ipl_buf[4]); 242 | Kprintf("TOP %08X SIZE %08X ENTRY %08X SUM %08X\n",top,size,entry,sum); 243 | 244 | while(size) 245 | { 246 | *top++ = *src++; 247 | size -= 4; 248 | } 249 | 250 | }while(entry==0); 251 | //Kprintf("readed %d bytes\n",ttl_read); 252 | error: 253 | f_close(&FileObject); 254 | 255 | return entry; 256 | } 257 | 258 | /**************************************************************************** 259 | universal IPL/file loader 260 | 261 | 1.encrypted IPL BLOCK DATA 262 | 2.decrypted IPL BLOCK DATA 263 | 3.binary included header of single decrypted IPL BLOCK DATA. 264 | 265 | ****************************************************************************/ 266 | void *ms_load_bootloader(const char *path) 267 | { 268 | FRESULT result; 269 | WORD readed; 270 | DWORD *src; 271 | 272 | DWORD *top; 273 | DWORD size; 274 | void *entry; 275 | DWORD sum; 276 | int file_type; 277 | 278 | result = f_mount(0,&FileSystem); 279 | if(result!=0) 280 | { 281 | Kprintf("f_mount error %08X\n",result); 282 | return 0; 283 | } 284 | 285 | // check file format 286 | result = f_open(&FileObject,path,FA_READ|FA_OPEN_EXISTING); 287 | if(result!=0) 288 | { 289 | Kprintf("f_open %s error\n",path); 290 | return 0; 291 | } 292 | 293 | // check 1st block 294 | result = f_read(&FileObject,ipl_buf,0x10,&readed); 295 | 296 | // chech decrypted IPL HEADER 297 | top = (DWORD *)(ipl_buf[0]); 298 | size = (ipl_buf[1]); 299 | entry= (void *)(ipl_buf[2]); 300 | sum = (ipl_buf[3]); 301 | if( 302 | check_ipl_address(top) && 303 | check_ipl_address(top+size) && 304 | (entry==0 || ( entry >= top && entry<=(top+size))) && 305 | sum == 0 306 | ){ 307 | // decrypted with header 308 | Kprintf("Decrypted Format\n"); 309 | if(entry==NULL) 310 | { 311 | // multi header == decrypted IPL 312 | f_close(&FileObject); 313 | return ms_load_ipl(path); 314 | } 315 | 316 | // single decrypted binary 317 | Kprintf("Single Binary Format\n"); 318 | while(size>0) 319 | { 320 | result = f_read(&FileObject,top,0x8000,&readed); 321 | if(result!=0) 322 | { 323 | //Kprintf("f_read error\n"); 324 | return -1; 325 | } 326 | Kprintf("f_read addr=%08X size=%08X\n",(int)top,readed); 327 | top += readed/4; 328 | size -= readed; 329 | } 330 | f_close(&FileObject); 331 | return entry; 332 | } 333 | 334 | // check encrypted IPL format 335 | result = f_read(&FileObject,ipl_buf+0x10/4,0x1000-0x10,&readed); 336 | f_close(&FileObject); 337 | 338 | if( pspKirkProc(ipl_buf,0x1000,ipl_buf,0x1000,0x01) ==0) 339 | { 340 | Kprintf("Encrypted Format\n"); 341 | return ms_load_ipl(path); 342 | } 343 | 344 | // 345 | Kprintf("Unsuported Format\n"); 346 | return NULL; 347 | } 348 | 349 | 350 | /**************************************************************************** 351 | initialize FAT system 352 | ****************************************************************************/ 353 | int ms_fat_init(void) 354 | { 355 | pspMsInit(); 356 | } 357 | -------------------------------------------------------------------------------- /ML_MAIN_BIN_DUMPER/fatload.c: -------------------------------------------------------------------------------- 1 | /* 2 | MS FAT file boot loader 3 | */ 4 | 5 | #include 6 | #include "kprintf.h" 7 | #include "cache.h" 8 | #include "syscon.h" 9 | #include "kirk.h" 10 | //#include "preipl.h" 11 | 12 | #include "memstk.h" 13 | #include "tff.h" /* Tiny-FatFs declarations */ 14 | 15 | #include "patch.h" 16 | #include "patch.h" 17 | 18 | /**************************************************************************** 19 | IPL load BOOT 20 | ****************************************************************************/ 21 | static int check_ipl_address(u32 address) 22 | { 23 | if(address >= 0x04000000 && address < 0x04200000) return 1; 24 | return 0; 25 | } 26 | 27 | static int check_ipl_address2(u32 address,u32 offset) 28 | { 29 | return check_ipl_address(address+offset); 30 | } 31 | 32 | /**************************************************************************** 33 | ****************************************************************************/ 34 | int ms_poll_access(int cnt) 35 | { 36 | // flip LED 37 | if(cnt&1) 38 | REG32(0xbe24000c) = 0x40; 39 | else 40 | REG32(0xbe240008) = 0x40; 41 | if( (cnt%32)==0) 42 | { 43 | // clear WDT 44 | pspSysconNop(); 45 | return 1; 46 | } 47 | return 0; 48 | } 49 | 50 | /**************************************************************************** 51 | IPL load BOOT 52 | ****************************************************************************/ 53 | static FATFS FileSystem; 54 | static FIL FileObject; 55 | 56 | extern int _ms_init(void); 57 | 58 | int ms_load_file(const char *path,void *top_addr) 59 | { 60 | FRESULT result; 61 | WORD readed; 62 | BYTE *load_addr; 63 | int ttl_read; 64 | int block_cnt = 0; 65 | 66 | load_addr = (BYTE *)top_addr; 67 | 68 | result = f_mount(0,&FileSystem); 69 | if(result!=0) 70 | { 71 | //Kprintf("f_mount error %08X\n",result); 72 | return -1; 73 | } 74 | 75 | result = f_open(&FileObject,path,FA_READ|FA_OPEN_EXISTING); 76 | if(result!=0) 77 | { 78 | //Kprintf("f_open %s error\n",path); 79 | return -1; 80 | } 81 | 82 | ttl_read = 0; 83 | do{ 84 | result = f_read(&FileObject,load_addr,0x8000,&readed); 85 | if(result!=0) 86 | { 87 | //Kprintf("f_read error\n"); 88 | return -1; 89 | } 90 | //Kprintf("f_read addr=%08X size=%08X\n",(int)load_addr,readed); 91 | load_addr += readed; 92 | ttl_read += readed; 93 | 94 | ms_poll_access(block_cnt++); 95 | 96 | }while(readed!=0); 97 | //Kprintf("readed %d bytes\n",ttl_read); 98 | 99 | f_close(&FileObject); 100 | REG32(0xbe24000c) = 0x40; 101 | 102 | return ttl_read; 103 | } 104 | 105 | /**************************************************************************** 106 | save file 107 | ****************************************************************************/ 108 | int ms_save_file(const char *path,const void *data,int size) 109 | { 110 | FRESULT result; 111 | WORD writed; 112 | int num_write; 113 | int block_cnt = 0; 114 | 115 | // 116 | result = f_mount(0,&FileSystem); 117 | if(result!=0) 118 | { 119 | Kprintf("f_mount error %08X\n",result); 120 | return -1; 121 | } 122 | 123 | result = f_open(&FileObject,path,FA_WRITE|FA_CREATE_ALWAYS); 124 | if(result!=0) 125 | { 126 | Kprintf("f_open %s error\n",path); 127 | return -1; 128 | } 129 | 130 | while(size) 131 | { 132 | num_write = size>0x8000 ? 0x8000 : size; 133 | result = f_write(&FileObject,data,num_write,&writed); 134 | if(result!=0 || num_write!=writed) 135 | { 136 | Kprintf("f_write error\n"); 137 | return -1; 138 | } 139 | //Kprintf("f_write %08X:%04X\n",(int)data,writed); 140 | data += num_write; 141 | size -= num_write; 142 | 143 | if( ms_poll_access(block_cnt++) ) 144 | { 145 | Kprintf("Left %08X\n",size); 146 | } 147 | } 148 | //Kprintf("readed %d bytes\n",ttl_read); 149 | f_close(&FileObject); 150 | REG32(0xbe24000c) = 0x40; 151 | 152 | return 0; 153 | } 154 | 155 | /**************************************************************************** 156 | PSP_IPL loader 157 | 158 | 1.encrypted IPL BLOCK DATA (1000h BLOCK) 159 | 2.decrypted IPL BLOCK DATA (1000h BLOCK) 160 | 161 | ****************************************************************************/ 162 | static DWORD *ipl_buf = (DWORD *)0xbfd00000; 163 | 164 | void *ms_load_ipl(const char *path) 165 | { 166 | FRESULT result; 167 | WORD readed; 168 | DWORD *src; 169 | 170 | DWORD *top; 171 | DWORD size; 172 | void *entry; 173 | DWORD sum; 174 | int binary_type = 0; 175 | 176 | result = f_mount(0,&FileSystem); 177 | if(result!=0) 178 | { 179 | Kprintf("f_mount error %08X\n",result); 180 | return 0; 181 | } 182 | 183 | result = f_open(&FileObject,path,FA_READ|FA_OPEN_EXISTING); 184 | if(result!=0) 185 | { 186 | Kprintf("f_open %s error\n",path); 187 | return 0; 188 | } 189 | 190 | do{ 191 | result = f_read(&FileObject,ipl_buf,0x1000,&readed); 192 | if(result!=0) 193 | { 194 | Kprintf("f_read error\n"); 195 | entry = 0; 196 | goto error; 197 | } 198 | 199 | if(binary_type==0) 200 | { 201 | // chech decrypted HEADER 202 | top = (DWORD *)(ipl_buf[0]); 203 | size = (ipl_buf[1]); 204 | entry= (void *)(ipl_buf[2]); 205 | sum = (ipl_buf[3]); 206 | if( 207 | check_ipl_address(top) && 208 | check_ipl_address(top+size) && 209 | (entry==0 || ( entry >= top && entry<=(top+size))) && 210 | sum == 0 211 | ){ 212 | // decrypted with header 213 | binary_type = 2; 214 | } else if( 215 | ipl_buf[0x60/4]==0x01 && 216 | ipl_buf[0x64/4]==0 && 217 | ipl_buf[0x68/4]==0 218 | ) 219 | { 220 | // encrypted IPL 221 | binary_type = 1; 222 | } 223 | } 224 | 225 | // decrypt block 226 | if(binary_type==1) 227 | { 228 | if( pspKirkProc(ipl_buf,0x1000,ipl_buf,0x1000,0x01) < 0) 229 | { 230 | Kprintf("Decrypt error\n"); 231 | entry = 0; 232 | goto error; 233 | } 234 | } 235 | 236 | // load BLOCK 237 | top = (ipl_buf[0]); 238 | size = (ipl_buf[1]); 239 | entry= (ipl_buf[2]); 240 | sum = (ipl_buf[3]); 241 | src = &(ipl_buf[4]); 242 | Kprintf("TOP %08X SIZE %08X ENTRY %08X SUM %08X\n",top,size,entry,sum); 243 | 244 | while(size) 245 | { 246 | *top++ = *src++; 247 | size -= 4; 248 | } 249 | 250 | }while(entry==0); 251 | //Kprintf("readed %d bytes\n",ttl_read); 252 | error: 253 | f_close(&FileObject); 254 | 255 | return entry; 256 | } 257 | 258 | /**************************************************************************** 259 | universal IPL/file loader 260 | 261 | 1.encrypted IPL BLOCK DATA 262 | 2.decrypted IPL BLOCK DATA 263 | 3.binary included header of single decrypted IPL BLOCK DATA. 264 | 265 | ****************************************************************************/ 266 | void *ms_load_bootloader(const char *path) 267 | { 268 | FRESULT result; 269 | WORD readed; 270 | DWORD *src; 271 | 272 | DWORD *top; 273 | DWORD size; 274 | void *entry; 275 | DWORD sum; 276 | int file_type; 277 | 278 | result = f_mount(0,&FileSystem); 279 | if(result!=0) 280 | { 281 | Kprintf("f_mount error %08X\n",result); 282 | return 0; 283 | } 284 | 285 | // check file format 286 | result = f_open(&FileObject,path,FA_READ|FA_OPEN_EXISTING); 287 | if(result!=0) 288 | { 289 | Kprintf("f_open %s error\n",path); 290 | return 0; 291 | } 292 | 293 | // check 1st block 294 | result = f_read(&FileObject,ipl_buf,0x10,&readed); 295 | 296 | // chech decrypted IPL HEADER 297 | top = (DWORD *)(ipl_buf[0]); 298 | size = (ipl_buf[1]); 299 | entry= (void *)(ipl_buf[2]); 300 | sum = (ipl_buf[3]); 301 | if( 302 | check_ipl_address(top) && 303 | check_ipl_address(top+size) && 304 | (entry==0 || ( entry >= top && entry<=(top+size))) && 305 | sum == 0 306 | ){ 307 | // decrypted with header 308 | Kprintf("Decrypted Format\n"); 309 | if(entry==NULL) 310 | { 311 | // multi header == decrypted IPL 312 | f_close(&FileObject); 313 | return ms_load_ipl(path); 314 | } 315 | 316 | // single decrypted binary 317 | Kprintf("Single Binary Format\n"); 318 | while(size>0) 319 | { 320 | result = f_read(&FileObject,top,0x8000,&readed); 321 | if(result!=0) 322 | { 323 | //Kprintf("f_read error\n"); 324 | return -1; 325 | } 326 | Kprintf("f_read addr=%08X size=%08X\n",(int)top,readed); 327 | top += readed/4; 328 | size -= readed; 329 | } 330 | f_close(&FileObject); 331 | return entry; 332 | } 333 | 334 | // check encrypted IPL format 335 | result = f_read(&FileObject,ipl_buf+0x10/4,0x1000-0x10,&readed); 336 | f_close(&FileObject); 337 | 338 | if( pspKirkProc(ipl_buf,0x1000,ipl_buf,0x1000,0x01) ==0) 339 | { 340 | Kprintf("Encrypted Format\n"); 341 | return ms_load_ipl(path); 342 | } 343 | 344 | // 345 | Kprintf("Unsuported Format\n"); 346 | return NULL; 347 | } 348 | 349 | 350 | /**************************************************************************** 351 | initialize FAT system 352 | ****************************************************************************/ 353 | int ms_fat_init(void) 354 | { 355 | pspMsInit(); 356 | } 357 | -------------------------------------------------------------------------------- /MS_BIOS_DUMPER/fatload.c: -------------------------------------------------------------------------------- 1 | /* 2 | MS FAT file boot loader 3 | */ 4 | 5 | #include 6 | #include "kprintf.h" 7 | #include "cache.h" 8 | #include "syscon.h" 9 | #include "kirk.h" 10 | //#include "preipl.h" 11 | 12 | #include "memstk.h" 13 | #include "tff.h" /* Tiny-FatFs declarations */ 14 | 15 | #include "patch.h" 16 | #include "patch.h" 17 | 18 | /**************************************************************************** 19 | IPL load BOOT 20 | ****************************************************************************/ 21 | static int check_ipl_address(u32 address) 22 | { 23 | if(address >= 0x04000000 && address < 0x04200000) return 1; 24 | return 0; 25 | } 26 | 27 | static int check_ipl_address2(u32 address,u32 offset) 28 | { 29 | return check_ipl_address(address+offset); 30 | } 31 | 32 | /**************************************************************************** 33 | ****************************************************************************/ 34 | int ms_poll_access(int cnt) 35 | { 36 | // flip LED 37 | if(cnt&1) 38 | REG32(0xbe24000c) = 0x40; 39 | else 40 | REG32(0xbe240008) = 0x40; 41 | if( (cnt%32)==0) 42 | { 43 | // clear WDT 44 | pspSysconNop(); 45 | return 1; 46 | } 47 | return 0; 48 | } 49 | 50 | /**************************************************************************** 51 | IPL load BOOT 52 | ****************************************************************************/ 53 | static FATFS FileSystem; 54 | static FIL FileObject; 55 | 56 | extern int _ms_init(void); 57 | 58 | int ms_load_file(const char *path,void *top_addr) 59 | { 60 | FRESULT result; 61 | WORD readed; 62 | BYTE *load_addr; 63 | int ttl_read; 64 | int block_cnt = 0; 65 | 66 | load_addr = (BYTE *)top_addr; 67 | 68 | result = f_mount(0,&FileSystem); 69 | if(result!=0) 70 | { 71 | //Kprintf("f_mount error %08X\n",result); 72 | return -1; 73 | } 74 | 75 | result = f_open(&FileObject,path,FA_READ|FA_OPEN_EXISTING); 76 | if(result!=0) 77 | { 78 | //Kprintf("f_open %s error\n",path); 79 | return -1; 80 | } 81 | 82 | ttl_read = 0; 83 | do{ 84 | result = f_read(&FileObject,load_addr,0x8000,&readed); 85 | if(result!=0) 86 | { 87 | //Kprintf("f_read error\n"); 88 | return -1; 89 | } 90 | //Kprintf("f_read addr=%08X size=%08X\n",(int)load_addr,readed); 91 | load_addr += readed; 92 | ttl_read += readed; 93 | 94 | ms_poll_access(block_cnt++); 95 | 96 | }while(readed!=0); 97 | //Kprintf("readed %d bytes\n",ttl_read); 98 | 99 | f_close(&FileObject); 100 | REG32(0xbe24000c) = 0x40; 101 | 102 | return ttl_read; 103 | } 104 | 105 | /**************************************************************************** 106 | save file 107 | ****************************************************************************/ 108 | int ms_save_file(const char *path,const void *data,int size) 109 | { 110 | FRESULT result; 111 | WORD writed; 112 | int num_write; 113 | int block_cnt = 0; 114 | 115 | // 116 | result = f_mount(0,&FileSystem); 117 | if(result!=0) 118 | { 119 | Kprintf("f_mount error %08X\n",result); 120 | return -1; 121 | } 122 | 123 | result = f_open(&FileObject,path,FA_WRITE|FA_CREATE_ALWAYS); 124 | if(result!=0) 125 | { 126 | Kprintf("f_open %s error\n",path); 127 | return -1; 128 | } 129 | 130 | while(size) 131 | { 132 | num_write = size>0x8000 ? 0x8000 : size; 133 | result = f_write(&FileObject,data,num_write,&writed); 134 | if(result!=0 || num_write!=writed) 135 | { 136 | Kprintf("f_write error\n"); 137 | return -1; 138 | } 139 | //Kprintf("f_write %08X:%04X\n",(int)data,writed); 140 | data += num_write; 141 | size -= num_write; 142 | 143 | if( ms_poll_access(block_cnt++) ) 144 | { 145 | Kprintf("Left %08X\n",size); 146 | } 147 | } 148 | //Kprintf("readed %d bytes\n",ttl_read); 149 | f_close(&FileObject); 150 | REG32(0xbe24000c) = 0x40; 151 | 152 | return 0; 153 | } 154 | 155 | /**************************************************************************** 156 | PSP_IPL loader 157 | 158 | 1.encrypted IPL BLOCK DATA (1000h BLOCK) 159 | 2.decrypted IPL BLOCK DATA (1000h BLOCK) 160 | 161 | ****************************************************************************/ 162 | static DWORD *ipl_buf = (DWORD *)0xbfd00000; 163 | 164 | void *ms_load_ipl(const char *path) 165 | { 166 | FRESULT result; 167 | WORD readed; 168 | DWORD *src; 169 | 170 | DWORD *top; 171 | DWORD size; 172 | void *entry; 173 | DWORD sum; 174 | int binary_type = 0; 175 | 176 | result = f_mount(0,&FileSystem); 177 | if(result!=0) 178 | { 179 | Kprintf("f_mount error %08X\n",result); 180 | return 0; 181 | } 182 | 183 | result = f_open(&FileObject,path,FA_READ|FA_OPEN_EXISTING); 184 | if(result!=0) 185 | { 186 | Kprintf("f_open %s error\n",path); 187 | return 0; 188 | } 189 | 190 | do{ 191 | result = f_read(&FileObject,ipl_buf,0x1000,&readed); 192 | if(result!=0) 193 | { 194 | Kprintf("f_read error\n"); 195 | entry = 0; 196 | goto error; 197 | } 198 | 199 | if(binary_type==0) 200 | { 201 | // chech decrypted HEADER 202 | top = (DWORD *)(ipl_buf[0]); 203 | size = (ipl_buf[1]); 204 | entry= (void *)(ipl_buf[2]); 205 | sum = (ipl_buf[3]); 206 | if( 207 | check_ipl_address(top) && 208 | check_ipl_address(top+size) && 209 | (entry==0 || ( entry >= top && entry<=(top+size))) && 210 | sum == 0 211 | ){ 212 | // decrypted with header 213 | binary_type = 2; 214 | } else if( 215 | ipl_buf[0x60/4]==0x01 && 216 | ipl_buf[0x64/4]==0 && 217 | ipl_buf[0x68/4]==0 218 | ) 219 | { 220 | // encrypted IPL 221 | binary_type = 1; 222 | } 223 | } 224 | 225 | // decrypt block 226 | if(binary_type==1) 227 | { 228 | if( pspKirkProc(ipl_buf,0x1000,ipl_buf,0x1000,0x01) < 0) 229 | { 230 | Kprintf("Decrypt error\n"); 231 | entry = 0; 232 | goto error; 233 | } 234 | } 235 | 236 | // load BLOCK 237 | top = (ipl_buf[0]); 238 | size = (ipl_buf[1]); 239 | entry= (ipl_buf[2]); 240 | sum = (ipl_buf[3]); 241 | src = &(ipl_buf[4]); 242 | Kprintf("TOP %08X SIZE %08X ENTRY %08X SUM %08X\n",top,size,entry,sum); 243 | 244 | while(size) 245 | { 246 | *top++ = *src++; 247 | size -= 4; 248 | } 249 | 250 | }while(entry==0); 251 | //Kprintf("readed %d bytes\n",ttl_read); 252 | error: 253 | f_close(&FileObject); 254 | 255 | return entry; 256 | } 257 | 258 | /**************************************************************************** 259 | universal IPL/file loader 260 | 261 | 1.encrypted IPL BLOCK DATA 262 | 2.decrypted IPL BLOCK DATA 263 | 3.binary included header of single decrypted IPL BLOCK DATA. 264 | 265 | ****************************************************************************/ 266 | void *ms_load_bootloader(const char *path) 267 | { 268 | FRESULT result; 269 | WORD readed; 270 | DWORD *src; 271 | 272 | DWORD *top; 273 | DWORD size; 274 | void *entry; 275 | DWORD sum; 276 | int file_type; 277 | 278 | result = f_mount(0,&FileSystem); 279 | if(result!=0) 280 | { 281 | Kprintf("f_mount error %08X\n",result); 282 | return 0; 283 | } 284 | 285 | // check file format 286 | result = f_open(&FileObject,path,FA_READ|FA_OPEN_EXISTING); 287 | if(result!=0) 288 | { 289 | Kprintf("f_open %s error\n",path); 290 | return 0; 291 | } 292 | 293 | // check 1st block 294 | result = f_read(&FileObject,ipl_buf,0x10,&readed); 295 | 296 | // chech decrypted IPL HEADER 297 | top = (DWORD *)(ipl_buf[0]); 298 | size = (ipl_buf[1]); 299 | entry= (void *)(ipl_buf[2]); 300 | sum = (ipl_buf[3]); 301 | if( 302 | check_ipl_address(top) && 303 | check_ipl_address(top+size) && 304 | (entry==0 || ( entry >= top && entry<=(top+size))) && 305 | sum == 0 306 | ){ 307 | // decrypted with header 308 | Kprintf("Decrypted Format\n"); 309 | if(entry==NULL) 310 | { 311 | // multi header == decrypted IPL 312 | f_close(&FileObject); 313 | return ms_load_ipl(path); 314 | } 315 | 316 | // single decrypted binary 317 | Kprintf("Single Binary Format\n"); 318 | while(size>0) 319 | { 320 | result = f_read(&FileObject,top,0x8000,&readed); 321 | if(result!=0) 322 | { 323 | //Kprintf("f_read error\n"); 324 | return -1; 325 | } 326 | Kprintf("f_read addr=%08X size=%08X\n",(int)top,readed); 327 | top += readed/4; 328 | size -= readed; 329 | } 330 | f_close(&FileObject); 331 | return entry; 332 | } 333 | 334 | // check encrypted IPL format 335 | result = f_read(&FileObject,ipl_buf+0x10/4,0x1000-0x10,&readed); 336 | f_close(&FileObject); 337 | 338 | if( pspKirkProc(ipl_buf,0x1000,ipl_buf,0x1000,0x01) ==0) 339 | { 340 | Kprintf("Encrypted Format\n"); 341 | return ms_load_ipl(path); 342 | } 343 | 344 | // 345 | Kprintf("Unsuported Format\n"); 346 | return NULL; 347 | } 348 | 349 | 350 | /**************************************************************************** 351 | initialize FAT system 352 | ****************************************************************************/ 353 | int ms_fat_init(void) 354 | { 355 | pspMsInit(); 356 | } 357 | -------------------------------------------------------------------------------- /IPL_SDK/syscon.c: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | PSP IPL SYSCON Driver 3 | ****************************************************************************/ 4 | #include 5 | #include "kprintf.h" 6 | 7 | #include "sysreg.h" 8 | #include "syscon.h" 9 | 10 | #define BYPASS_ERR_CHECK 1 11 | 12 | #define REG32(ADDR) (*(vu32*)(ADDR)) 13 | 14 | /**************************************************************************** 15 | initialize SYSCON HW 16 | ****************************************************************************/ 17 | int pspSyscon_init(void) 18 | { 19 | sceSysregSpiClkSelect(0,1); 20 | 21 | sceSysregSpiClkEnable(0); 22 | 23 | //sceSysregSpiIoEnable(0) 24 | REG32(0xbc100078) |= (0x1000000<<0); 25 | 26 | // init SPI 27 | REG32(0xbe580000) = 0xcf; 28 | REG32(0xbe580004) = 0x04; 29 | REG32(0xbe580014) = 0; 30 | REG32(0xbe580024) = 0; 31 | 32 | // sceGpioPortClear 33 | REG32(0xbe24000c) = 0x08; 34 | 35 | // GPIO3 OUT 36 | REG32(0xbe240000) |= 0x08; 37 | // GPIO4 IN 38 | REG32(0xbe240000) &= ~0x10; 39 | 40 | // GpioSetIntrMode(4,3) 41 | REG32(0xbe240010) &= ~0x10; 42 | REG32(0xbe240014) &= ~0x10; 43 | REG32(0xbe240018) |= 0x10; 44 | REG32(0xbe240024) = 0x10; 45 | 46 | #if 0 47 | pspSyscon_driver_Unkonow_7ec5a957(wram_0108); 48 | sceSyscon_driver_Unkonow_7bcc5eae(); 49 | sceSysconGetPowerStatus(powersts); 50 | #endif 51 | 52 | return 0; 53 | } 54 | 55 | /**************************************************************************** 56 | SYSCON comminucation 57 | ****************************************************************************/ 58 | int Syscon_cmd(u8 *tx_buf,u8 *rx_buf) 59 | { 60 | volatile u16 dmy; 61 | u8 *ptr; 62 | int result; 63 | u16 wdata; 64 | u8 bdata; 65 | int cnt; 66 | u8 sum; 67 | int i; 68 | 69 | // Kprintf("SYSCON CMD %02X,%02X\n",tx_buf[0],tx_buf[1]); 70 | retry: 71 | // calc & set TX sum 72 | sum = 0; 73 | cnt = tx_buf[1]; 74 | for(i=0;i=0;i--) 88 | rx_buf[i]=0xff; 89 | // 90 | //wait 5usec after GPIO3.fall 91 | // 92 | // Syscon_wait(5); 93 | 94 | // sceKernelCpuSuspendIntr() 95 | 96 | // sceGpioPortRead(); 97 | dmy = REG32(0xbe240004); 98 | // sceGpioPortClear(8) 99 | REG32(0xbe24000c) = 0x08; 100 | 101 | if(REG32(0xbe58000c) & 4) 102 | { 103 | //Kprintf("RX DUMMY:"); 104 | // clear prevouse data ? 105 | while( REG32(0xbe58000c) & 4) 106 | { 107 | dmy = REG32(0xbe580008); 108 | //Kprintf("%04X:",dmy); 109 | } 110 | //Kprintf("\n"); 111 | } 112 | dmy = REG32(0xbe58000c); 113 | ; 114 | REG32(0xbe580020) = 3; // clear error status ? 115 | ; 116 | // TX data 117 | // cnt = tx_buf[1]; 118 | ptr = tx_buf; 119 | //Kprintf("TX DATA (%d):",cnt); 120 | 121 | for(i=0;i<(cnt+1);i+=2) 122 | { 123 | dmy = REG32(0xbe58000c); 124 | //Kprintf("%04X ",(ptr[0]<<8)|ptr[1] ); 125 | REG32(0xbe580008) = (ptr[0]<<8)|ptr[1]; 126 | ptr += 2; 127 | } 128 | //Kprintf("\n"); 129 | REG32(0xbe580004) = 6; // RX mode ? 130 | 131 | //Kprintf("set GPIO3\n"); 132 | // sceGpioPortSet(8) 133 | REG32(0xbe240008) = 0x08; 134 | // 135 | //wait 5usec after GPIO3.fall 136 | // 137 | // Syscon_wait(5); 138 | 139 | //Kprintf("wait ACK %02X\n",REG32(0xbe240020)&0x18); 140 | //-------------------------------------------------------------- 141 | //wait for GPIO4 raise 142 | //-------------------------------------------------------------- 143 | // r2 = sceGpioQueryIntr(4) 144 | while( (REG32(0xbe240020) & 0x10)==0) 145 | { 146 | //Kprintf("%02X ",REG32(0xbe240004)&0x18); 147 | } 148 | 149 | // GpioAcquireIntr(4) 150 | REG32(0xbe240024) = 0x10; 151 | 152 | //-------------------------------------------------------------- 153 | //receive 154 | //-------------------------------------------------------------- 155 | 156 | //Kprintf("receive\n"); 157 | result = 0; 158 | 159 | #if BYPASS_ERR_CHECK 160 | #else 161 | // error check 162 | if( (REG32(0xbe58000c) & 4)==0) 163 | { 164 | //Kprintf("SYSCON err 1\n"); 165 | // error ! 166 | rx_buf[0] = 0xff; 167 | result = -1; 168 | 169 | // r16[$4] |= 0x00100000 // error 170 | for(cnt=0x0f;cnt;cnt--); 171 | } 172 | 173 | // error check 174 | if( (REG32(0xbe58000c) & 1)==0) 175 | { 176 | //Kprintf("SYSCON err 2\n"); 177 | // r16[$4] |= $00200000 // error 178 | result = -1; 179 | } 180 | 181 | // error check ? 182 | if( REG32(0xbe580018) & 1) 183 | { 184 | //Kprintf("SYSCON err 3\n"); 185 | REG32(0xbe580020) = 1; 186 | // r16[$4] |= $00400000 // error 187 | } 188 | #endif 189 | 190 | //Kprintf("RX data:"); 191 | // receive data 192 | ptr = rx_buf; 193 | for(i=0;i<0x10;i+=2) 194 | { 195 | if( (REG32(0xbe58000c) & 4)==0) 196 | break; 197 | 198 | wdata = REG32(0xbe580008); 199 | bdata = wdata>>8; 200 | if(i==0) 201 | { 202 | result = bdata; // 1st RX data : result ? 203 | } 204 | ptr[0] = bdata; 205 | ptr[1] = wdata & 0xff; 206 | //Kprintf("%02X %02X ",ptr[0],ptr[1]); 207 | ptr+=2; 208 | } 209 | //Kprintf("\n"); 210 | REG32(0xbe580004) = 4; 211 | ; 212 | // sceGpioPortClear(8) 213 | REG32(0xbe24000c) = 0x08; 214 | ; 215 | //Kprintf("check sum\n"); 216 | // calc and check RX sum 217 | if(result>0) 218 | { 219 | cnt = rx_buf[1]; 220 | if(cnt < 3) 221 | { 222 | result = -2; 223 | } 224 | else 225 | { 226 | ptr = rx_buf; 227 | sum = 0; 228 | for(i=0;i>8); 261 | tx_buf[4] = (u8)(param>>16); 262 | tx_buf[5] = (u8)(param>>24); 263 | return Syscon_cmd(tx_buf,rx_buf); 264 | } 265 | 266 | /**************************************************************************** 267 | 4bytes result command 268 | ****************************************************************************/ 269 | int pspSyscon_rx_dword(u32 *param,u8 cmd) 270 | { 271 | u8 tx_buf[0x10],rx_buf[0x10]; 272 | int result; 273 | 274 | tx_buf[0] = cmd; 275 | tx_buf[1] = 2; 276 | 277 | result = Syscon_cmd(tx_buf,rx_buf); 278 | if(result>=0) 279 | { 280 | switch(rx_buf[1]) 281 | { 282 | case 4: *param = rx_buf[3]; break; 283 | case 5: *param = rx_buf[3]|(rx_buf[4]<<8); break; 284 | case 6: *param = rx_buf[3]|(rx_buf[4]<<8)|(rx_buf[5]<<16); break; 285 | default: 286 | *param = rx_buf[3]|(rx_buf[4]<<8)|(rx_buf[5]<<16)|(rx_buf[6]<<24); 287 | } 288 | } 289 | return result; 290 | } 291 | 292 | /**************************************************************************** 293 | non parameter command 294 | ****************************************************************************/ 295 | int pspSyscon_tx_noparam(u8 cmd) 296 | { 297 | return pspSyscon_tx_dword(0,cmd,2); 298 | } 299 | 300 | /**************************************************************************** 301 | ****************************************************************************/ 302 | u32 Syscon_wait(u32 usec) 303 | { 304 | u32 i; 305 | vu32 dmy = 0; 306 | 307 | while(usec--) 308 | { 309 | for(i=0;i<10;i++) 310 | { 311 | dmy ^= REG32(0xbe240000); 312 | } 313 | } 314 | return dmy; 315 | } 316 | 317 | /**************************************************************************** 318 | LED power controll 319 | ****************************************************************************/ 320 | int pspSysconCtrlLED(int sel,int is_on) 321 | { 322 | u32 param; 323 | 324 | param = (is_on==0) ? 0xf0 : 0x00; 325 | if(sel==1) 326 | { 327 | param += 0x90; 328 | } 329 | else 330 | { 331 | param += 0x50; 332 | if(sel!=0) 333 | { 334 | param = (is_on==0) ? 0 : 0xf0; 335 | param = (-is_on); 336 | param += 0x30; 337 | } 338 | } 339 | return pspSyscon_tx_dword(param,0x47,0x03); 340 | } 341 | 342 | /**************************************************************************** 343 | get CTRL value 344 | ****************************************************************************/ 345 | int _pspSysconGetCtrl2(u32 *ctrl,u8 *vol1,u8 *vol2) 346 | { 347 | u8 tx_buf[0x10],rx_buf[0x10]; 348 | int result; 349 | 350 | tx_buf[0] = 0x08; 351 | tx_buf[1] = 2; 352 | result = Syscon_cmd(tx_buf,rx_buf); 353 | *ctrl = rx_buf[3]|(rx_buf[4]<<8)|(rx_buf[5]<<16)|(rx_buf[6]<<24); 354 | *vol1 = rx_buf[7]; 355 | *vol2 = rx_buf[8]; 356 | return result; 357 | } 358 | -------------------------------------------------------------------------------- /MS_NORMAL/memstk.c: -------------------------------------------------------------------------------- 1 | /* 2 | PSP MemoryStick Driver 3 | */ 4 | #include 5 | #include "Kprintf.h" 6 | 7 | #include "syscon.h" 8 | 9 | //HOWTO COMPILE & MAKE WORK: 10 | 11 | // 1b) Add _wsbw function to code. 12 | // 3) Check syntax of all functions with "int addr"/"int buffer" 13 | // to see if they do pointer stuff correctly. 14 | // I was lazy so no void*, just int for addr. 15 | // 4) Call MS_INIT 16 | // 5) Call MS_READBLOCK with params 17 | // 6) Figure out what provokes that crash you just had. 18 | // (I'm ready to bet money that it will crash although i didn't test it) 19 | // Anyway, you're on your own now. ;) 20 | 21 | #define SHOW_READ_DATA 0 22 | #define SHOW_ERR_MSG 0 23 | #define SHOW_SECTOR_ACCESS 0 24 | #define SHOW_STATUS_REG 0 25 | 26 | #define IO_MEM_STICK_CMD *((volatile int*)(0xBD200030)) 27 | #define IO_MEM_STICK_DATA *((volatile int*)(0xBD200034)) 28 | #define IO_MEM_STICK_STATUS *((volatile int*)(0xBD200038)) 29 | #define IO_MEM_STICK_SYS *((volatile int*)(0xBD20003C)) 30 | 31 | #define MSRST 0x8000 32 | 33 | #define MS_FIFO_RW 0x4000 34 | #define MS_RDY 0x1000 35 | #define MS_TIME_OUT 0x100 36 | #define MS_CRC_ERROR 0x200 37 | 38 | 39 | #define READ_PAGE_DATA 0x2000 40 | #define READ_REG 0x4000 41 | #define GET_INT 0x7000 42 | #define SET_RW_REG_ADRS 0x8000 43 | #define EX_SET_CMD 0x9000 44 | 45 | #define WRITE_REG (0xB000) 46 | #define SET_CMD (0xE000) 47 | 48 | #define INT_REG_CED 0x80 49 | #define INT_REG_ERR 0x40 50 | #define INT_REG_BREQ 0x20 51 | #define INT_REG_CMDNK 0x01 52 | /* 53 | ;NORM_COMP = (ced && !err) 54 | ;CMD_ERR_TER = (ced && err) 55 | ;NORM_DATA_TRANS = (!err && breq) 56 | ;DATA_REQ_ERR = (err && breq) 57 | ;CMD_EXE = (!ced && !breq) 58 | ;CMD_NOT_EXE = cmdnk 59 | */ 60 | 61 | /**************************************************************************** 62 | ****************************************************************************/ 63 | static int ms_wait_ready(void) 64 | { 65 | int status; 66 | //Kprintf("ms_wait_ready\n"); 67 | do{ 68 | status = IO_MEM_STICK_STATUS; 69 | }while(!(status & MS_RDY)); 70 | 71 | if (status & (MS_CRC_ERROR|MS_TIME_OUT)) 72 | { 73 | #if SHOW_ERR_MSG 74 | Kprintf("err:ms_wait_ready %08X\n",status); 75 | #endif 76 | return -1; 77 | } 78 | return 0; 79 | } 80 | 81 | /**************************************************************************** 82 | ****************************************************************************/ 83 | static int send_data_and_sync(int arg1, int arg2) 84 | { 85 | int ret; 86 | IO_MEM_STICK_DATA = arg1; 87 | IO_MEM_STICK_DATA = arg2; 88 | ret = ms_wait_ready(); 89 | return ret; 90 | } 91 | 92 | /**************************************************************************** 93 | ****************************************************************************/ 94 | static int ms_get_reg_int(void) 95 | { 96 | int ret, dummy, status; 97 | 98 | IO_MEM_STICK_CMD = GET_INT | 0x1; 99 | 100 | do{ 101 | status = IO_MEM_STICK_STATUS; 102 | if(status & MS_TIME_OUT) 103 | { 104 | #if SHOW_ERR_MSG 105 | Kprintf("err:get_reg_int timeout\n"); 106 | #endif 107 | return -1; 108 | } 109 | }while(!(status & MS_FIFO_RW)); 110 | 111 | ret = IO_MEM_STICK_DATA; 112 | dummy = IO_MEM_STICK_DATA; 113 | 114 | do{ 115 | status = IO_MEM_STICK_STATUS; 116 | if(status & MS_TIME_OUT) 117 | { 118 | #if SHOW_ERR_MSG 119 | Kprintf("err:get_reg_int timeout\n"); 120 | #endif 121 | return -1; 122 | } 123 | }while(!(status & MS_RDY)); 124 | 125 | return ret & 0xff; 126 | } 127 | 128 | /**************************************************************************** 129 | ****************************************************************************/ 130 | static int read_data(void *addr, int count) 131 | { 132 | int i; 133 | int status; 134 | for(i = 0; i> 16) & 0x15 != 0) return -1; 222 | #endif 223 | return 0; 224 | } 225 | 226 | /**************************************************************************** 227 | ****************************************************************************/ 228 | int pspMsInit(void) 229 | { 230 | //Kprintf("_ms_init\n"); 231 | 232 | //initialize the hardware 233 | *((volatile int*)(0xBC100054)) |= 0x00000100; 234 | *((volatile int*)(0xBC100050)) |= 0x00000400; 235 | *((volatile int*)(0xBC100078)) |= 0x00000010; 236 | *((volatile int*)(0xBC10004C)) &= 0xFFFFFEFF; 237 | 238 | //Kprintf("reset\n"); 239 | 240 | //reset the controller 241 | IO_MEM_STICK_SYS = MSRST; 242 | while(IO_MEM_STICK_SYS & MSRST); 243 | 244 | //Kprintf("check status\n"); 245 | ms_check_status(); 246 | ms_wait_ready(); 247 | ms_wait_ced(); 248 | 249 | return 0; 250 | } 251 | 252 | /**************************************************************************** 253 | ****************************************************************************/ 254 | int pspMsReadSector(int sector, void *addr) 255 | { 256 | int ret; 257 | 258 | #if SHOW_SECTOR_ACCESS 259 | Kprintf("ms_read_sector(%08X,%08X)\n",sector,addr); 260 | #endif 261 | 262 | /* 263 | MS format 264 | SYS_PARAM_REG (0x10) 265 | BLOCK_ADD_REG2 (0x11) 266 | BLOCK_ADD_REG1 (0x12) 267 | BLOCK_ADD_REG0 (0x13) 268 | CMD_PARAM_REG (0x14) 269 | PAGE_ADD_REG (0x15) 270 | OVER_WR_FLAG_REG (0x16) 271 | 272 | MSPro format 273 | //size = 1; 274 | buf[0] = mode; // 0x10 275 | buf[1] = (size & 0xFF00) >> 8; 276 | buf[2] = (size & 0xFF); 277 | buf[3] = (address & 0xFF000000) >> 24; 278 | buf[4] = (address & 0x00FF0000) >> 16; 279 | buf[5] = (address & 0x0000FF00) >> 8; 280 | buf[6] = (address & 0x000000FF); 281 | buf[7] = 0x00; 282 | 283 | */ 284 | //send a command with 8 bytes of params, reverse endian. (0x200001XX 0xYYYYYY00) => READ_DATA 285 | IO_MEM_STICK_CMD = EX_SET_CMD | 0x7; 286 | ret = send_data_and_sync(0x010020 | (sector>>24)<<24, ((sector>>16)&0xff) | (sector&0xff00) | ((sector<<16)&0xff0000) ); 287 | if (ret < 0) return -1; 288 | 289 | ms_wait_unk1(); 290 | 291 | //Kprintf("wait BREQ\n"); 292 | do{ 293 | ret = ms_get_reg_int(); 294 | if (ret < 0) return -1; 295 | }while((ret & INT_REG_BREQ) == 0); 296 | 297 | if (ret & INT_REG_ERR) 298 | { 299 | #if SHOW_ERR_MSG 300 | Kprintf("err:ms wait int\n"); 301 | #endif 302 | return -1; 303 | } 304 | 305 | //Kprintf("READ_PAGE_DATA\n"); 306 | 307 | //send command to read data and get the data. 308 | IO_MEM_STICK_CMD = READ_PAGE_DATA | 512; 309 | ret = read_data(addr, 512); 310 | if (ret < 0) return -1; 311 | 312 | if (ms_wait_ready() < 0) return -1; 313 | ms_wait_unk1(); 314 | ms_wait_ced(); 315 | 316 | return 0; 317 | } 318 | -------------------------------------------------------------------------------- /IPL_SDK/memstkro.c: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | PSP IPL MemoryStick Driver (read only) 3 | 4 | note: 5 | Supported MsProDuo Only. 6 | 7 | ****************************************************************************/ 8 | #include 9 | #include "Kprintf.h" 10 | 11 | #include "syscon.h" 12 | 13 | // debug switches 14 | #define SHOW_READ_DATA 0 15 | #define SHOW_ERR_MSG 0 16 | #define SHOW_SECTOR_ACCESS 0 17 | #define SHOW_STATUS_REG 0 18 | 19 | // HW registers 20 | #define IO_MEM_STICK_CMD *((volatile int*)(0xBD200030)) 21 | #define IO_MEM_STICK_DATA *((volatile int*)(0xBD200034)) 22 | #define IO_MEM_STICK_STATUS *((volatile int*)(0xBD200038)) 23 | #define IO_MEM_STICK_SYS *((volatile int*)(0xBD20003C)) 24 | 25 | // SYS bit 26 | #define MSRST 0x8000 27 | 28 | // STATUS bit 29 | #define MS_FIFO_RW 0x4000 30 | #define MS_RDY 0x1000 31 | #define MS_TIME_OUT 0x0100 32 | #define MS_CRC_ERROR 0x0200 33 | 34 | // MS command code 35 | #define READ_PAGE_DATA 0x2000 36 | #define READ_REG 0x4000 37 | #define GET_INT 0x7000 38 | #define SET_RW_REG_ADRS 0x8000 39 | #define EX_SET_CMD 0x9000 40 | #define WRITE_REG 0xB000 41 | #define WRITE_PAGE_DATA 0xD000 42 | #define SET_CMD 0xE000 43 | 44 | // MS status bit 45 | #define INT_REG_CED 0x80 46 | #define INT_REG_ERR 0x40 47 | #define INT_REG_BREQ 0x20 48 | #define INT_REG_CMDNK 0x01 49 | /* 50 | ;NORM_COMP = (ced && !err) 51 | ;CMD_ERR_TER = (ced && err) 52 | ;NORM_DATA_TRANS = (!err && breq) 53 | ;DATA_REQ_ERR = (err && breq) 54 | ;CMD_EXE = (!ced && !breq) 55 | ;CMD_NOT_EXE = cmdnk 56 | */ 57 | 58 | /**************************************************************************** 59 | ****************************************************************************/ 60 | static int ms_wait_ready(void) 61 | { 62 | int status; 63 | //Kprintf("ms_wait_ready\n"); 64 | do{ 65 | status = IO_MEM_STICK_STATUS; 66 | }while(!(status & MS_RDY)); 67 | 68 | if (status & (MS_CRC_ERROR|MS_TIME_OUT)) 69 | { 70 | #if SHOW_ERR_MSG 71 | Kprintf("err:ms_wait_ready %08X\n",status); 72 | #endif 73 | return -1; 74 | } 75 | return 0; 76 | } 77 | 78 | /**************************************************************************** 79 | ****************************************************************************/ 80 | static int send_data_and_sync(int arg1, int arg2) 81 | { 82 | int ret; 83 | IO_MEM_STICK_DATA = arg1; 84 | IO_MEM_STICK_DATA = arg2; 85 | ret = ms_wait_ready(); 86 | return ret; 87 | } 88 | 89 | /**************************************************************************** 90 | ****************************************************************************/ 91 | static int ms_get_reg_int(void) 92 | { 93 | int ret, dummy, status; 94 | 95 | IO_MEM_STICK_CMD = GET_INT | 0x1; 96 | 97 | do{ 98 | status = IO_MEM_STICK_STATUS; 99 | if(status & MS_TIME_OUT) 100 | { 101 | #if SHOW_ERR_MSG 102 | Kprintf("err:get_reg_int timeout\n"); 103 | #endif 104 | return -1; 105 | } 106 | }while(!(status & MS_FIFO_RW)); 107 | 108 | ret = IO_MEM_STICK_DATA; 109 | dummy = IO_MEM_STICK_DATA; 110 | 111 | do{ 112 | status = IO_MEM_STICK_STATUS; 113 | if(status & MS_TIME_OUT) 114 | { 115 | #if SHOW_ERR_MSG 116 | Kprintf("err:get_reg_int timeout\n"); 117 | #endif 118 | return -1; 119 | } 120 | }while(!(status & MS_RDY)); 121 | 122 | return ret & 0xff; 123 | } 124 | 125 | /**************************************************************************** 126 | ****************************************************************************/ 127 | static int read_data(void *addr, int count) 128 | { 129 | int i; 130 | int status; 131 | for(i = 0; i> 16) & 0x15 != 0) return -1; 219 | #endif 220 | return 0; 221 | } 222 | 223 | /**************************************************************************** 224 | ****************************************************************************/ 225 | int pspMsInit(void) 226 | { 227 | //Kprintf("_ms_init\n"); 228 | 229 | //initialize the hardware 230 | *((volatile int*)(0xBC100054)) |= 0x00000100; 231 | *((volatile int*)(0xBC100050)) |= 0x00000400; 232 | *((volatile int*)(0xBC100078)) |= 0x00000010; 233 | *((volatile int*)(0xBC10004C)) &= 0xFFFFFEFF; 234 | 235 | //Kprintf("reset\n"); 236 | 237 | //reset the controller 238 | IO_MEM_STICK_SYS = MSRST; 239 | while(IO_MEM_STICK_SYS & MSRST); 240 | 241 | //Kprintf("check status\n"); 242 | ms_check_status(); 243 | ms_wait_ready(); 244 | ms_wait_ced(); 245 | 246 | return 0; 247 | } 248 | 249 | /**************************************************************************** 250 | ****************************************************************************/ 251 | int pspMsReadSector(int sector, void *addr) 252 | { 253 | int ret; 254 | 255 | #if SHOW_SECTOR_ACCESS 256 | Kprintf("ms_read_sector(%08X,%08X)\n",sector,addr); 257 | #endif 258 | 259 | /* 260 | MS format 261 | SYS_PARAM_REG (0x10) 262 | BLOCK_ADD_REG2 (0x11) 263 | BLOCK_ADD_REG1 (0x12) 264 | BLOCK_ADD_REG0 (0x13) 265 | CMD_PARAM_REG (0x14) 266 | PAGE_ADD_REG (0x15) 267 | OVER_WR_FLAG_REG (0x16) 268 | 269 | MSPro format 270 | //size = 1; 271 | buf[0] = mode; // 0x10 272 | buf[1] = (size & 0xFF00) >> 8; 273 | buf[2] = (size & 0xFF); 274 | buf[3] = (address & 0xFF000000) >> 24; 275 | buf[4] = (address & 0x00FF0000) >> 16; 276 | buf[5] = (address & 0x0000FF00) >> 8; 277 | buf[6] = (address & 0x000000FF); 278 | buf[7] = 0x00; 279 | 280 | */ 281 | //send a command with 8 bytes of params, reverse endian. (0x200001XX 0xYYYYYY00) => READ_DATA 282 | IO_MEM_STICK_CMD = EX_SET_CMD | 0x7; 283 | ret = send_data_and_sync(0x010020 | (sector>>24)<<24, ((sector>>16)&0xff) | (sector&0xff00) | ((sector<<16)&0xff0000) ); 284 | if (ret < 0) return -1; 285 | 286 | ms_wait_unk1(); 287 | 288 | //Kprintf("wait BREQ\n"); 289 | do{ 290 | ret = ms_get_reg_int(); 291 | if (ret < 0) return -1; 292 | }while((ret & INT_REG_BREQ) == 0); 293 | 294 | if (ret & INT_REG_ERR) 295 | { 296 | #if SHOW_ERR_MSG 297 | Kprintf("err:ms wait int\n"); 298 | #endif 299 | return -1; 300 | } 301 | 302 | //Kprintf("READ_PAGE_DATA\n"); 303 | 304 | //send command to read data and get the data. 305 | IO_MEM_STICK_CMD = READ_PAGE_DATA | 512; 306 | ret = read_data(addr, 512); 307 | if (ret < 0) return -1; 308 | 309 | if (ms_wait_ready() < 0) return -1; 310 | ms_wait_unk1(); 311 | ms_wait_ced(); 312 | 313 | return 0; 314 | } 315 | 316 | /**************************************************************************** 317 | ****************************************************************************/ 318 | int pspMsWriteSector(int sector, void *addr) 319 | { 320 | return -1; 321 | } 322 | -------------------------------------------------------------------------------- /IPL_SDK/fatload.c: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | MS-FAT PSP bootfile loader 3 | ****************************************************************************/ 4 | 5 | #include 6 | #include "kprintf.h" 7 | #include "cache.h" 8 | #include "syscon.h" 9 | #include "kirk.h" 10 | 11 | #include "memstk.h" 12 | #include "tff.h" /* Tiny-FatFs declarations */ 13 | 14 | #include "patch.h" 15 | #include "patch.h" 16 | 17 | #define __VERBOSE__ 0 18 | 19 | /**************************************************************************** 20 | IPL load BOOT 21 | ****************************************************************************/ 22 | static int check_ipl_address(u32 address) 23 | { 24 | if(address >= 0x04000000 && address < 0x04200000) return 1; 25 | return 0; 26 | } 27 | 28 | static int check_ipl_address2(u32 address,u32 offset) 29 | { 30 | return check_ipl_address(address+offset); 31 | } 32 | 33 | /**************************************************************************** 34 | ****************************************************************************/ 35 | int ms_poll_access(int cnt) 36 | { 37 | // flip LED 38 | if(cnt&1) 39 | REG32(0xbe24000c) = 0x40; 40 | else 41 | REG32(0xbe240008) = 0x40; 42 | if( (cnt%32)==0) 43 | { 44 | // clear WDT 45 | pspSysconNop(); 46 | return 1; 47 | } 48 | return 0; 49 | } 50 | 51 | /**************************************************************************** 52 | IPL load BOOT 53 | ****************************************************************************/ 54 | static FATFS FileSystem; 55 | static FIL FileObject; 56 | 57 | extern int _ms_init(void); 58 | 59 | int ms_load_file(const char *path,void *top_addr) 60 | { 61 | FRESULT result; 62 | WORD readed; 63 | BYTE *load_addr; 64 | int ttl_read; 65 | int block_cnt = 0; 66 | 67 | load_addr = (BYTE *)top_addr; 68 | 69 | result = f_mount(0,&FileSystem); 70 | if(result!=0) 71 | { 72 | //Kprintf("f_mount error %08X\n",result); 73 | return -1; 74 | } 75 | 76 | result = f_open(&FileObject,path,FA_READ|FA_OPEN_EXISTING); 77 | if(result!=0) 78 | { 79 | //Kprintf("f_open %s error\n",path); 80 | return -1; 81 | } 82 | 83 | ttl_read = 0; 84 | do{ 85 | result = f_read(&FileObject,load_addr,0x8000,&readed); 86 | if(result!=0) 87 | { 88 | //Kprintf("f_read error\n"); 89 | return -1; 90 | } 91 | //Kprintf("f_read addr=%08X size=%08X\n",(int)load_addr,readed); 92 | load_addr += readed; 93 | ttl_read += readed; 94 | 95 | ms_poll_access(block_cnt++); 96 | 97 | }while(readed!=0); 98 | //Kprintf("readed %d bytes\n",ttl_read); 99 | 100 | f_close(&FileObject); 101 | REG32(0xbe24000c) = 0x40; 102 | 103 | return ttl_read; 104 | } 105 | 106 | #if 0 107 | /**************************************************************************** 108 | save file 109 | ****************************************************************************/ 110 | int ms_save_file(const char *path,const void *data,int size) 111 | { 112 | FRESULT result; 113 | WORD writed; 114 | int num_write; 115 | int block_cnt = 0; 116 | 117 | // 118 | result = f_mount(0,&FileSystem); 119 | if(result!=0) 120 | { 121 | #if __VERBOSE__ 122 | Kprintf("f_mount error %08X\n",result); 123 | #endif 124 | return -1; 125 | } 126 | 127 | result = f_open(&FileObject,path,FA_WRITE|FA_CREATE_ALWAYS); 128 | if(result!=0) 129 | { 130 | #if __VERBOSE__ 131 | Kprintf("f_open %s error\n",path); 132 | #endif 133 | return -1; 134 | } 135 | 136 | while(size) 137 | { 138 | num_write = size>0x8000 ? 0x8000 : size; 139 | result = f_write(&FileObject,data,num_write,&writed); 140 | if(result!=0 || num_write!=writed) 141 | { 142 | #if __VERBOSE__ 143 | Kprintf("f_write error\n"); 144 | #endif 145 | return -1; 146 | } 147 | //Kprintf("f_write %08X:%04X\n",(int)data,writed); 148 | data += num_write; 149 | size -= num_write; 150 | 151 | if( ms_poll_access(block_cnt++) ) 152 | { 153 | #if __VERBOSE__ 154 | Kprintf("Left %08X\n",size); 155 | #endif 156 | } 157 | } 158 | //Kprintf("readed %d bytes\n",ttl_read); 159 | f_close(&FileObject); 160 | REG32(0xbe24000c) = 0x40; 161 | 162 | return 0; 163 | } 164 | #endif 165 | 166 | /**************************************************************************** 167 | PSP_IPL loader 168 | 169 | 1.encrypted IPL BLOCK DATA (1000h BLOCK) 170 | 2.decrypted IPL BLOCK DATA (1000h BLOCK) 171 | 172 | ****************************************************************************/ 173 | static DWORD *ipl_buf = (DWORD *)0xbfd00000; 174 | 175 | void *ms_load_ipl(const char *path) 176 | { 177 | FRESULT result; 178 | WORD readed; 179 | DWORD *src; 180 | 181 | DWORD *top; 182 | DWORD size; 183 | void *entry; 184 | DWORD sum; 185 | int binary_type = 0; 186 | 187 | result = f_mount(0,&FileSystem); 188 | if(result!=0) 189 | { 190 | #if __VERBOSE__ 191 | Kprintf("f_mount error %08X\n",result); 192 | #endif 193 | return 0; 194 | } 195 | 196 | result = f_open(&FileObject,path,FA_READ|FA_OPEN_EXISTING); 197 | if(result!=0) 198 | { 199 | #if __VERBOSE__ 200 | Kprintf("f_open %s error\n",path); 201 | #endif 202 | return 0; 203 | } 204 | 205 | do{ 206 | result = f_read(&FileObject,ipl_buf,0x1000,&readed); 207 | if(result!=0) 208 | { 209 | #if __VERBOSE__ 210 | Kprintf("f_read error\n"); 211 | #endif 212 | entry = 0; 213 | goto error; 214 | } 215 | 216 | if(binary_type==0) 217 | { 218 | // chech decrypted HEADER 219 | top = (DWORD *)(ipl_buf[0]); 220 | size = (ipl_buf[1]); 221 | entry= (void *)(ipl_buf[2]); 222 | sum = (ipl_buf[3]); 223 | if( 224 | check_ipl_address(top) && 225 | check_ipl_address(top+size) && 226 | (entry==0 || ( entry >= top && entry<=(top+size))) && 227 | sum == 0 228 | ){ 229 | // decrypted with header 230 | binary_type = 2; 231 | } else if( 232 | ipl_buf[0x60/4]==0x01 && 233 | ipl_buf[0x64/4]==0 && 234 | ipl_buf[0x68/4]==0 235 | ) 236 | { 237 | // encrypted IPL 238 | binary_type = 1; 239 | } 240 | } 241 | 242 | // decrypt block 243 | if(binary_type==1) 244 | { 245 | if( pspKirkProc(ipl_buf,0x1000,ipl_buf,0x1000,0x01) < 0) 246 | { 247 | #if __VERBOSE__ 248 | Kprintf("Decrypt error\n"); 249 | #endif 250 | entry = 0; 251 | goto error; 252 | } 253 | } 254 | 255 | // load BLOCK 256 | top = (ipl_buf[0]); 257 | size = (ipl_buf[1]); 258 | entry= (ipl_buf[2]); 259 | sum = (ipl_buf[3]); 260 | src = &(ipl_buf[4]); 261 | #if __VERBOSE__ 262 | Kprintf("TOP %08X SIZE %08X ENTRY %08X SUM %08X\n",top,size,entry,sum); 263 | #endif 264 | while(size) 265 | { 266 | *top++ = *src++; 267 | size -= 4; 268 | } 269 | 270 | }while(entry==0); 271 | //Kprintf("readed %d bytes\n",ttl_read); 272 | error: 273 | f_close(&FileObject); 274 | 275 | return entry; 276 | } 277 | 278 | /**************************************************************************** 279 | universal IPL/file loader 280 | 281 | 1.encrypted IPL BLOCK DATA 282 | 2.decrypted IPL BLOCK DATA 283 | 3.binary included header of single decrypted IPL BLOCK DATA. 284 | 285 | ****************************************************************************/ 286 | void *ms_load_bootloader(const char *path) 287 | { 288 | FRESULT result; 289 | WORD readed; 290 | DWORD *src; 291 | 292 | DWORD *top; 293 | DWORD size; 294 | void *entry; 295 | DWORD sum; 296 | int file_type; 297 | 298 | result = f_mount(0,&FileSystem); 299 | if(result!=0) 300 | { 301 | #if __VERBOSE__ 302 | Kprintf("f_mount error %08X\n",result); 303 | #endif 304 | return 0; 305 | } 306 | 307 | // check file format 308 | result = f_open(&FileObject,path,FA_READ|FA_OPEN_EXISTING); 309 | if(result!=0) 310 | { 311 | #if __VERBOSE__ 312 | Kprintf("f_open %s error\n",path); 313 | #endif 314 | return 0; 315 | } 316 | 317 | // check 1st block 318 | result = f_read(&FileObject,ipl_buf,0x10,&readed); 319 | 320 | // chech decrypted IPL HEADER 321 | top = (DWORD *)(ipl_buf[0]); 322 | size = (ipl_buf[1]); 323 | entry= (void *)(ipl_buf[2]); 324 | sum = (ipl_buf[3]); 325 | if( 326 | check_ipl_address(top) && 327 | check_ipl_address(top+size) && 328 | (entry==0 || ( entry >= top && entry<=(top+size))) && 329 | sum == 0 330 | ){ 331 | // decrypted with header 332 | Kprintf("Decrypted Format\n"); 333 | if(entry==NULL) 334 | { 335 | // multi header == decrypted IPL 336 | f_close(&FileObject); 337 | return ms_load_ipl(path); 338 | } 339 | 340 | // single decrypted binary 341 | #if __VERBOSE__ 342 | Kprintf("Single Binary Format\n"); 343 | #endif 344 | while(size>0) 345 | { 346 | result = f_read(&FileObject,top,0x8000,&readed); 347 | if(result!=0) 348 | { 349 | //Kprintf("f_read error\n"); 350 | return -1; 351 | } 352 | #if __VERBOSE__ 353 | Kprintf("f_read addr=%08X size=%08X\n",(int)top,readed); 354 | #endif 355 | top += readed/4; 356 | size -= readed; 357 | } 358 | f_close(&FileObject); 359 | return entry; 360 | } 361 | 362 | // check encrypted IPL format 363 | result = f_read(&FileObject,ipl_buf+0x10/4,0x1000-0x10,&readed); 364 | f_close(&FileObject); 365 | 366 | if( pspKirkProc(ipl_buf,0x1000,ipl_buf,0x1000,0x01) ==0) 367 | { 368 | Kprintf("Encrypted Format\n"); 369 | return ms_load_ipl(path); 370 | } 371 | 372 | // 373 | Kprintf("Unsuported Format\n"); 374 | return NULL; 375 | } 376 | 377 | 378 | /**************************************************************************** 379 | initialize FAT system 380 | ****************************************************************************/ 381 | int ms_fat_init(void) 382 | { 383 | pspMsInit(); 384 | } 385 | -------------------------------------------------------------------------------- /MS_MULTI_LOADER/fatload.c: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | MS-FAT PSP bootfile loader 3 | ****************************************************************************/ 4 | 5 | #include 6 | #include "kprintf.h" 7 | #include "cache.h" 8 | #include "syscon.h" 9 | #include "kirk.h" 10 | //#include "preipl.h" 11 | 12 | #include "memstk.h" 13 | #include "tff.h" /* Tiny-FatFs declarations */ 14 | 15 | #include "patch.h" 16 | #include "patch.h" 17 | 18 | #define __VERBOSE__ 0 19 | 20 | /**************************************************************************** 21 | IPL load BOOT 22 | ****************************************************************************/ 23 | static int check_ipl_address(u32 address) 24 | { 25 | if(address >= 0x04000000 && address < 0x04200000) return 1; 26 | return 0; 27 | } 28 | 29 | static int check_ipl_address2(u32 address,u32 offset) 30 | { 31 | return check_ipl_address(address+offset); 32 | } 33 | 34 | /**************************************************************************** 35 | ****************************************************************************/ 36 | int ms_poll_access(int cnt) 37 | { 38 | // flip LED 39 | if(cnt&1) 40 | REG32(0xbe24000c) = 0x40; 41 | else 42 | REG32(0xbe240008) = 0x40; 43 | if( (cnt%32)==0) 44 | { 45 | // clear WDT 46 | pspSysconNop(); 47 | return 1; 48 | } 49 | return 0; 50 | } 51 | 52 | /**************************************************************************** 53 | IPL load BOOT 54 | ****************************************************************************/ 55 | static FATFS FileSystem; 56 | static FIL FileObject; 57 | 58 | extern int _ms_init(void); 59 | 60 | int ms_load_file(const char *path,void *top_addr) 61 | { 62 | FRESULT result; 63 | WORD readed; 64 | BYTE *load_addr; 65 | int ttl_read; 66 | int block_cnt = 0; 67 | 68 | load_addr = (BYTE *)top_addr; 69 | 70 | result = f_mount(0,&FileSystem); 71 | if(result!=0) 72 | { 73 | //Kprintf("f_mount error %08X\n",result); 74 | return -1; 75 | } 76 | 77 | result = f_open(&FileObject,path,FA_READ|FA_OPEN_EXISTING); 78 | if(result!=0) 79 | { 80 | //Kprintf("f_open %s error\n",path); 81 | return -1; 82 | } 83 | 84 | ttl_read = 0; 85 | do{ 86 | result = f_read(&FileObject,load_addr,0x8000,&readed); 87 | if(result!=0) 88 | { 89 | //Kprintf("f_read error\n"); 90 | return -1; 91 | } 92 | //Kprintf("f_read addr=%08X size=%08X\n",(int)load_addr,readed); 93 | load_addr += readed; 94 | ttl_read += readed; 95 | 96 | ms_poll_access(block_cnt++); 97 | 98 | }while(readed!=0); 99 | //Kprintf("readed %d bytes\n",ttl_read); 100 | 101 | f_close(&FileObject); 102 | REG32(0xbe24000c) = 0x40; 103 | 104 | return ttl_read; 105 | } 106 | 107 | #if 0 108 | /**************************************************************************** 109 | save file 110 | ****************************************************************************/ 111 | int ms_save_file(const char *path,const void *data,int size) 112 | { 113 | FRESULT result; 114 | WORD writed; 115 | int num_write; 116 | int block_cnt = 0; 117 | 118 | // 119 | result = f_mount(0,&FileSystem); 120 | if(result!=0) 121 | { 122 | #if __VERBOSE__ 123 | Kprintf("f_mount error %08X\n",result); 124 | #endif 125 | return -1; 126 | } 127 | 128 | result = f_open(&FileObject,path,FA_WRITE|FA_CREATE_ALWAYS); 129 | if(result!=0) 130 | { 131 | #if __VERBOSE__ 132 | Kprintf("f_open %s error\n",path); 133 | #endif 134 | return -1; 135 | } 136 | 137 | while(size) 138 | { 139 | num_write = size>0x8000 ? 0x8000 : size; 140 | result = f_write(&FileObject,data,num_write,&writed); 141 | if(result!=0 || num_write!=writed) 142 | { 143 | #if __VERBOSE__ 144 | Kprintf("f_write error\n"); 145 | #endif 146 | return -1; 147 | } 148 | //Kprintf("f_write %08X:%04X\n",(int)data,writed); 149 | data += num_write; 150 | size -= num_write; 151 | 152 | if( ms_poll_access(block_cnt++) ) 153 | { 154 | #if __VERBOSE__ 155 | Kprintf("Left %08X\n",size); 156 | #endif 157 | } 158 | } 159 | //Kprintf("readed %d bytes\n",ttl_read); 160 | f_close(&FileObject); 161 | REG32(0xbe24000c) = 0x40; 162 | 163 | return 0; 164 | } 165 | #endif 166 | 167 | /**************************************************************************** 168 | PSP_IPL loader 169 | 170 | 1.encrypted IPL BLOCK DATA (1000h BLOCK) 171 | 2.decrypted IPL BLOCK DATA (1000h BLOCK) 172 | 173 | ****************************************************************************/ 174 | static DWORD *ipl_buf = (DWORD *)0xbfd00000; 175 | 176 | void *ms_load_ipl(const char *path) 177 | { 178 | FRESULT result; 179 | WORD readed; 180 | DWORD *src; 181 | 182 | DWORD *top; 183 | DWORD size; 184 | void *entry; 185 | DWORD sum; 186 | int binary_type = 0; 187 | 188 | result = f_mount(0,&FileSystem); 189 | if(result!=0) 190 | { 191 | #if __VERBOSE__ 192 | Kprintf("f_mount error %08X\n",result); 193 | #endif 194 | return 0; 195 | } 196 | 197 | result = f_open(&FileObject,path,FA_READ|FA_OPEN_EXISTING); 198 | if(result!=0) 199 | { 200 | #if __VERBOSE__ 201 | Kprintf("f_open %s error\n",path); 202 | #endif 203 | return 0; 204 | } 205 | 206 | do{ 207 | result = f_read(&FileObject,ipl_buf,0x1000,&readed); 208 | if(result!=0) 209 | { 210 | #if __VERBOSE__ 211 | Kprintf("f_read error\n"); 212 | #endif 213 | entry = 0; 214 | goto error; 215 | } 216 | 217 | if(binary_type==0) 218 | { 219 | // chech decrypted HEADER 220 | top = (DWORD *)(ipl_buf[0]); 221 | size = (ipl_buf[1]); 222 | entry= (void *)(ipl_buf[2]); 223 | sum = (ipl_buf[3]); 224 | if( 225 | check_ipl_address(top) && 226 | check_ipl_address(top+size) && 227 | (entry==0 || ( entry >= top && entry<=(top+size))) && 228 | sum == 0 229 | ){ 230 | // decrypted with header 231 | binary_type = 2; 232 | } else if( 233 | ipl_buf[0x60/4]==0x01 && 234 | ipl_buf[0x64/4]==0 && 235 | ipl_buf[0x68/4]==0 236 | ) 237 | { 238 | // encrypted IPL 239 | binary_type = 1; 240 | } 241 | } 242 | 243 | // decrypt block 244 | if(binary_type==1) 245 | { 246 | if( pspKirkProc(ipl_buf,0x1000,ipl_buf,0x1000,0x01) < 0) 247 | { 248 | #if __VERBOSE__ 249 | Kprintf("Decrypt error\n"); 250 | #endif 251 | entry = 0; 252 | goto error; 253 | } 254 | } 255 | 256 | // load BLOCK 257 | top = (ipl_buf[0]); 258 | size = (ipl_buf[1]); 259 | entry= (ipl_buf[2]); 260 | sum = (ipl_buf[3]); 261 | src = &(ipl_buf[4]); 262 | #if __VERBOSE__ 263 | Kprintf("TOP %08X SIZE %08X ENTRY %08X SUM %08X\n",top,size,entry,sum); 264 | #endif 265 | while(size) 266 | { 267 | *top++ = *src++; 268 | size -= 4; 269 | } 270 | 271 | }while(entry==0); 272 | //Kprintf("readed %d bytes\n",ttl_read); 273 | error: 274 | f_close(&FileObject); 275 | 276 | return entry; 277 | } 278 | 279 | /**************************************************************************** 280 | universal IPL/file loader 281 | 282 | 1.encrypted IPL BLOCK DATA 283 | 2.decrypted IPL BLOCK DATA 284 | 3.binary included header of single decrypted IPL BLOCK DATA. 285 | 286 | ****************************************************************************/ 287 | void *ms_load_bootloader(const char *path) 288 | { 289 | FRESULT result; 290 | WORD readed; 291 | DWORD *src; 292 | 293 | DWORD *top; 294 | DWORD size; 295 | void *entry; 296 | DWORD sum; 297 | int file_type; 298 | 299 | result = f_mount(0,&FileSystem); 300 | if(result!=0) 301 | { 302 | #if __VERBOSE__ 303 | Kprintf("f_mount error %08X\n",result); 304 | #endif 305 | return 0; 306 | } 307 | 308 | // check file format 309 | result = f_open(&FileObject,path,FA_READ|FA_OPEN_EXISTING); 310 | if(result!=0) 311 | { 312 | #if __VERBOSE__ 313 | Kprintf("f_open %s error\n",path); 314 | #endif 315 | return 0; 316 | } 317 | 318 | // check 1st block 319 | result = f_read(&FileObject,ipl_buf,0x10,&readed); 320 | 321 | // chech decrypted IPL HEADER 322 | top = (DWORD *)(ipl_buf[0]); 323 | size = (ipl_buf[1]); 324 | entry= (void *)(ipl_buf[2]); 325 | sum = (ipl_buf[3]); 326 | if( 327 | check_ipl_address(top) && 328 | check_ipl_address(top+size) && 329 | (entry==0 || ( entry >= top && entry<=(top+size))) && 330 | sum == 0 331 | ){ 332 | // decrypted with header 333 | Kprintf("Decrypted Format\n"); 334 | if(entry==NULL) 335 | { 336 | // multi header == decrypted IPL 337 | f_close(&FileObject); 338 | return ms_load_ipl(path); 339 | } 340 | 341 | // single decrypted binary 342 | #if __VERBOSE__ 343 | Kprintf("Single Binary Format\n"); 344 | #endif 345 | while(size>0) 346 | { 347 | result = f_read(&FileObject,top,0x8000,&readed); 348 | if(result!=0) 349 | { 350 | //Kprintf("f_read error\n"); 351 | return -1; 352 | } 353 | #if __VERBOSE__ 354 | Kprintf("f_read addr=%08X size=%08X\n",(int)top,readed); 355 | #endif 356 | top += readed/4; 357 | size -= readed; 358 | } 359 | f_close(&FileObject); 360 | return entry; 361 | } 362 | 363 | // check encrypted IPL format 364 | result = f_read(&FileObject,ipl_buf+0x10/4,0x1000-0x10,&readed); 365 | f_close(&FileObject); 366 | 367 | if( pspKirkProc(ipl_buf,0x1000,ipl_buf,0x1000,0x01) ==0) 368 | { 369 | Kprintf("Encrypted Format\n"); 370 | return ms_load_ipl(path); 371 | } 372 | 373 | // 374 | Kprintf("Unsuported Format\n"); 375 | return NULL; 376 | } 377 | 378 | 379 | /**************************************************************************** 380 | initialize FAT system 381 | ****************************************************************************/ 382 | int ms_fat_init(void) 383 | { 384 | pspMsInit(); 385 | } 386 | -------------------------------------------------------------------------------- /MS_NORMAL/ipl_ms.x: -------------------------------------------------------------------------------- 1 | /* Default linker script, for normal executables */ 2 | OUTPUT_FORMAT("elf32-littlemips", "elf32-bigmips", 3 | "elf32-littlemips") 4 | OUTPUT_ARCH(mips:allegrex) 5 | ENTRY(_start) 6 | SEARCH_DIR("c"); SEARCH_DIR("/devkitPro/devkitPSP_4.0.1/psp/lib"); 7 | /* Do we need any of these for elf? 8 | __DYNAMIC = 0; */ 9 | SECTIONS 10 | { 11 | /* Read-only sections, merged into text segment: */ 12 | PROVIDE (__executable_start = 0x040d0000); . = 0x040d0000; 13 | .rel.init : { *(.rel.init) } 14 | .rela.init : { *(.rela.init) } 15 | .rel.text : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) } 16 | .rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) } 17 | .rel.fini : { *(.rel.fini) } 18 | .rela.fini : { *(.rela.fini) } 19 | .rel.rodata : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) } 20 | .rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) } 21 | .rel.data.rel.ro : { *(.rel.data.rel.ro*) } 22 | .rela.data.rel.ro : { *(.rel.data.rel.ro*) } 23 | .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) } 24 | .rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) } 25 | .rel.tdata : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) } 26 | .rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) } 27 | .rel.tbss : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) } 28 | .rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) } 29 | .rel.ctors : { *(.rel.ctors) } 30 | .rela.ctors : { *(.rela.ctors) } 31 | .rel.dtors : { *(.rel.dtors) } 32 | .rela.dtors : { *(.rela.dtors) } 33 | .rel.got : { *(.rel.got) } 34 | .rela.got : { *(.rela.got) } 35 | .rel.sdata : { *(.rel.sdata .rel.sdata.* .rel.gnu.linkonce.s.*) } 36 | .rela.sdata : { *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) } 37 | .rel.sbss : { *(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*) } 38 | .rela.sbss : { *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*) } 39 | .rel.sdata2 : { *(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.*) } 40 | .rela.sdata2 : { *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) } 41 | .rel.sbss2 : { *(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.*) } 42 | .rela.sbss2 : { *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) } 43 | .rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) } 44 | .rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) } 45 | .rel.plt : { *(.rel.plt) } 46 | .rela.plt : { *(.rela.plt) } 47 | .interp : { *(.interp) } 48 | .dynamic : { *(.dynamic) } 49 | .hash : { *(.hash) } 50 | .dynsym : { *(.dynsym) } 51 | .dynstr : { *(.dynstr) } 52 | .gnu.version : { *(.gnu.version) } 53 | .gnu.version_d : { *(.gnu.version_d) } 54 | .gnu.version_r : { *(.gnu.version_r) } 55 | .init : 56 | { 57 | KEEP (*(.init)) 58 | } =0 59 | .plt : { *(.plt) } 60 | .text : 61 | { 62 | _ftext = . ; 63 | *(.text .stub .text.* .gnu.linkonce.t.*) 64 | KEEP (*(.text.*personality*)) 65 | /* .gnu.warning sections are handled specially by elf32.em. */ 66 | *(.gnu.warning) 67 | *(.mips16.fn.*) *(.mips16.call.*) 68 | } =0 69 | .fini : 70 | { 71 | KEEP (*(.fini)) 72 | } =0 73 | PROVIDE (__etext = .); 74 | PROVIDE (_etext = .); 75 | PROVIDE (etext = .); 76 | .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } 77 | .rodata1 : { *(.rodata1) } 78 | .sdata2 : { *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) } 79 | .sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) } 80 | .eh_frame_hdr : { *(.eh_frame_hdr) } 81 | .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) } 82 | .gcc_except_table : ONLY_IF_RO { KEEP (*(.gcc_except_table)) *(.gcc_except_table.*) } 83 | /* Adjust the address for the data segment. We want to adjust up to 84 | the same address within the page on the next page up. */ 85 | . = ALIGN (0x40) - ((0x40 - .) & (0x40 - 1)); . = DATA_SEGMENT_ALIGN (0x40, 0x1000); 86 | /* Exception handling */ 87 | .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) } 88 | .gcc_except_table : ONLY_IF_RW { KEEP (*(.gcc_except_table)) *(.gcc_except_table.*) } 89 | /* Thread Local Storage sections */ 90 | .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } 91 | .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } 92 | /* Ensure the __preinit_array_start label is properly aligned. We 93 | could instead move the label definition inside the section, but 94 | the linker would then create the section even if it turns out to 95 | be empty, which isn't pretty. */ 96 | . = ALIGN(32 / 8); 97 | PROVIDE (__preinit_array_start = .); 98 | .preinit_array : { KEEP (*(.preinit_array)) } 99 | PROVIDE (__preinit_array_end = .); 100 | PROVIDE (__init_array_start = .); 101 | .init_array : { KEEP (*(.init_array)) } 102 | PROVIDE (__init_array_end = .); 103 | PROVIDE (__fini_array_start = .); 104 | .fini_array : { KEEP (*(.fini_array)) } 105 | PROVIDE (__fini_array_end = .); 106 | .ctors : 107 | { 108 | /* gcc uses crtbegin.o to find the start of 109 | the constructors, so we make sure it is 110 | first. Because this is a wildcard, it 111 | doesn't matter if the user does not 112 | actually link against crtbegin.o; the 113 | linker won't look for a file to match a 114 | wildcard. The wildcard also means that it 115 | doesn't matter which directory crtbegin.o 116 | is in. */ 117 | KEEP (*crtbegin*.o(.ctors)) 118 | /* We don't want to include the .ctor section from 119 | from the crtend.o file until after the sorted ctors. 120 | The .ctor section from the crtend file contains the 121 | end of ctors marker and it must be last */ 122 | KEEP (*(EXCLUDE_FILE (*crtend*.o ) .ctors)) 123 | KEEP (*(SORT(.ctors.*))) 124 | KEEP (*(.ctors)) 125 | } 126 | .dtors : 127 | { 128 | KEEP (*crtbegin*.o(.dtors)) 129 | KEEP (*(EXCLUDE_FILE (*crtend*.o ) .dtors)) 130 | KEEP (*(SORT(.dtors.*))) 131 | KEEP (*(.dtors)) 132 | } 133 | .jcr : { KEEP (*(.jcr)) } 134 | .data.rel.ro : { *(.data.rel.ro.local) *(.data.rel.ro*) } 135 | . = DATA_SEGMENT_RELRO_END (0, .); 136 | .data : 137 | { 138 | _fdata = . ; 139 | *(.data .data.* .gnu.linkonce.d.*) 140 | KEEP (*(.gnu.linkonce.d.*personality*)) 141 | SORT(CONSTRUCTORS) 142 | } 143 | .data1 : { *(.data1) } 144 | . = .; 145 | _gp = ALIGN(16) + 0x7ff0; 146 | .got : { *(.got.plt) *(.got) } 147 | /* We want the small data sections together, so single-instruction offsets 148 | can access them all, and initialized data all before uninitialized, so 149 | we can shorten the on-disk segment size. */ 150 | .sdata : 151 | { 152 | *(.sdata .sdata.* .gnu.linkonce.s.*) 153 | } 154 | .lit8 : { *(.lit8) } 155 | .lit4 : { *(.lit4) } 156 | _edata = .; 157 | PROVIDE (edata = .); 158 | __bss_start = .; 159 | _fbss = .; 160 | .sbss : 161 | { 162 | PROVIDE (__sbss_start = .); 163 | PROVIDE (___sbss_start = .); 164 | *(.dynsbss) 165 | *(.sbss .sbss.* .gnu.linkonce.sb.*) 166 | *(.scommon) 167 | PROVIDE (__sbss_end = .); 168 | PROVIDE (___sbss_end = .); 169 | } 170 | .bss : 171 | { 172 | *(.dynbss) 173 | *(.bss .bss.* .gnu.linkonce.b.*) 174 | *(COMMON) 175 | /* Align here to ensure that the .bss section occupies space up to 176 | _end. Align after .bss to ensure correct alignment even if the 177 | .bss section disappears because there are no input sections. */ 178 | . = ALIGN(32 / 8); 179 | } 180 | . = ALIGN(32 / 8); 181 | _end = .; 182 | PROVIDE (end = .); 183 | . = DATA_SEGMENT_END (.); 184 | /* Stabs debugging sections. */ 185 | .stab 0 : { *(.stab) } 186 | .stabstr 0 : { *(.stabstr) } 187 | .stab.excl 0 : { *(.stab.excl) } 188 | .stab.exclstr 0 : { *(.stab.exclstr) } 189 | .stab.index 0 : { *(.stab.index) } 190 | .stab.indexstr 0 : { *(.stab.indexstr) } 191 | .comment 0 : { *(.comment) } 192 | /* DWARF debug sections. 193 | Symbols in the DWARF debugging sections are relative to the beginning 194 | of the section so we begin them at 0. */ 195 | /* DWARF 1 */ 196 | .debug 0 : { *(.debug) } 197 | .line 0 : { *(.line) } 198 | /* GNU DWARF 1 extensions */ 199 | .debug_srcinfo 0 : { *(.debug_srcinfo) } 200 | .debug_sfnames 0 : { *(.debug_sfnames) } 201 | /* DWARF 1.1 and DWARF 2 */ 202 | .debug_aranges 0 : { *(.debug_aranges) } 203 | .debug_pubnames 0 : { *(.debug_pubnames) } 204 | /* DWARF 2 */ 205 | .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } 206 | .debug_abbrev 0 : { *(.debug_abbrev) } 207 | .debug_line 0 : { *(.debug_line) } 208 | .debug_frame 0 : { *(.debug_frame) } 209 | .debug_str 0 : { *(.debug_str) } 210 | .debug_loc 0 : { *(.debug_loc) } 211 | .debug_macinfo 0 : { *(.debug_macinfo) } 212 | /* SGI/MIPS DWARF 2 extensions */ 213 | .debug_weaknames 0 : { *(.debug_weaknames) } 214 | .debug_funcnames 0 : { *(.debug_funcnames) } 215 | .debug_typenames 0 : { *(.debug_typenames) } 216 | .debug_varnames 0 : { *(.debug_varnames) } 217 | .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) } 218 | .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) } 219 | /DISCARD/ : { *(.note.GNU-stack) } 220 | } 221 | -------------------------------------------------------------------------------- /MS_MULTI_LOADER/ipl_mload.x: -------------------------------------------------------------------------------- 1 | /* Default linker script, for normal executables */ 2 | OUTPUT_FORMAT("elf32-littlemips", "elf32-bigmips", 3 | "elf32-littlemips") 4 | OUTPUT_ARCH(mips:allegrex) 5 | ENTRY(_start) 6 | SEARCH_DIR("c"); SEARCH_DIR("/devkitPro/devkitPSP_4.0.1/psp/lib"); 7 | /* Do we need any of these for elf? 8 | __DYNAMIC = 0; */ 9 | SECTIONS 10 | { 11 | /* Read-only sections, merged into text segment: */ 12 | PROVIDE (__executable_start = 0x041e0000); . = 0x041e0000; 13 | .rel.init : { *(.rel.init) } 14 | .rela.init : { *(.rela.init) } 15 | .rel.text : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) } 16 | .rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) } 17 | .rel.fini : { *(.rel.fini) } 18 | .rela.fini : { *(.rela.fini) } 19 | .rel.rodata : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) } 20 | .rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) } 21 | .rel.data.rel.ro : { *(.rel.data.rel.ro*) } 22 | .rela.data.rel.ro : { *(.rel.data.rel.ro*) } 23 | .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) } 24 | .rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) } 25 | .rel.tdata : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) } 26 | .rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) } 27 | .rel.tbss : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) } 28 | .rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) } 29 | .rel.ctors : { *(.rel.ctors) } 30 | .rela.ctors : { *(.rela.ctors) } 31 | .rel.dtors : { *(.rel.dtors) } 32 | .rela.dtors : { *(.rela.dtors) } 33 | .rel.got : { *(.rel.got) } 34 | .rela.got : { *(.rela.got) } 35 | .rel.sdata : { *(.rel.sdata .rel.sdata.* .rel.gnu.linkonce.s.*) } 36 | .rela.sdata : { *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) } 37 | .rel.sbss : { *(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*) } 38 | .rela.sbss : { *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*) } 39 | .rel.sdata2 : { *(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.*) } 40 | .rela.sdata2 : { *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) } 41 | .rel.sbss2 : { *(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.*) } 42 | .rela.sbss2 : { *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) } 43 | .rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) } 44 | .rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) } 45 | .rel.plt : { *(.rel.plt) } 46 | .rela.plt : { *(.rela.plt) } 47 | .interp : { *(.interp) } 48 | .dynamic : { *(.dynamic) } 49 | .hash : { *(.hash) } 50 | .dynsym : { *(.dynsym) } 51 | .dynstr : { *(.dynstr) } 52 | .gnu.version : { *(.gnu.version) } 53 | .gnu.version_d : { *(.gnu.version_d) } 54 | .gnu.version_r : { *(.gnu.version_r) } 55 | .init : 56 | { 57 | KEEP (*(.init)) 58 | } =0 59 | .plt : { *(.plt) } 60 | .text : 61 | { 62 | _ftext = . ; 63 | *(.text .stub .text.* .gnu.linkonce.t.*) 64 | KEEP (*(.text.*personality*)) 65 | /* .gnu.warning sections are handled specially by elf32.em. */ 66 | *(.gnu.warning) 67 | *(.mips16.fn.*) *(.mips16.call.*) 68 | } =0 69 | .fini : 70 | { 71 | KEEP (*(.fini)) 72 | } =0 73 | PROVIDE (__etext = .); 74 | PROVIDE (_etext = .); 75 | PROVIDE (etext = .); 76 | .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } 77 | .rodata1 : { *(.rodata1) } 78 | .sdata2 : { *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) } 79 | .sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) } 80 | .eh_frame_hdr : { *(.eh_frame_hdr) } 81 | .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) } 82 | .gcc_except_table : ONLY_IF_RO { KEEP (*(.gcc_except_table)) *(.gcc_except_table.*) } 83 | /* Adjust the address for the data segment. We want to adjust up to 84 | the same address within the page on the next page up. */ 85 | . = ALIGN (0x40) - ((0x40 - .) & (0x40 - 1)); . = DATA_SEGMENT_ALIGN (0x40, 0x1000); 86 | /* Exception handling */ 87 | .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) } 88 | .gcc_except_table : ONLY_IF_RW { KEEP (*(.gcc_except_table)) *(.gcc_except_table.*) } 89 | /* Thread Local Storage sections */ 90 | .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } 91 | .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } 92 | /* Ensure the __preinit_array_start label is properly aligned. We 93 | could instead move the label definition inside the section, but 94 | the linker would then create the section even if it turns out to 95 | be empty, which isn't pretty. */ 96 | . = ALIGN(32 / 8); 97 | PROVIDE (__preinit_array_start = .); 98 | .preinit_array : { KEEP (*(.preinit_array)) } 99 | PROVIDE (__preinit_array_end = .); 100 | PROVIDE (__init_array_start = .); 101 | .init_array : { KEEP (*(.init_array)) } 102 | PROVIDE (__init_array_end = .); 103 | PROVIDE (__fini_array_start = .); 104 | .fini_array : { KEEP (*(.fini_array)) } 105 | PROVIDE (__fini_array_end = .); 106 | .ctors : 107 | { 108 | /* gcc uses crtbegin.o to find the start of 109 | the constructors, so we make sure it is 110 | first. Because this is a wildcard, it 111 | doesn't matter if the user does not 112 | actually link against crtbegin.o; the 113 | linker won't look for a file to match a 114 | wildcard. The wildcard also means that it 115 | doesn't matter which directory crtbegin.o 116 | is in. */ 117 | KEEP (*crtbegin*.o(.ctors)) 118 | /* We don't want to include the .ctor section from 119 | from the crtend.o file until after the sorted ctors. 120 | The .ctor section from the crtend file contains the 121 | end of ctors marker and it must be last */ 122 | KEEP (*(EXCLUDE_FILE (*crtend*.o ) .ctors)) 123 | KEEP (*(SORT(.ctors.*))) 124 | KEEP (*(.ctors)) 125 | } 126 | .dtors : 127 | { 128 | KEEP (*crtbegin*.o(.dtors)) 129 | KEEP (*(EXCLUDE_FILE (*crtend*.o ) .dtors)) 130 | KEEP (*(SORT(.dtors.*))) 131 | KEEP (*(.dtors)) 132 | } 133 | .jcr : { KEEP (*(.jcr)) } 134 | .data.rel.ro : { *(.data.rel.ro.local) *(.data.rel.ro*) } 135 | . = DATA_SEGMENT_RELRO_END (0, .); 136 | .data : 137 | { 138 | _fdata = . ; 139 | *(.data .data.* .gnu.linkonce.d.*) 140 | KEEP (*(.gnu.linkonce.d.*personality*)) 141 | SORT(CONSTRUCTORS) 142 | } 143 | .data1 : { *(.data1) } 144 | . = .; 145 | _gp = ALIGN(16) + 0x7ff0; 146 | .got : { *(.got.plt) *(.got) } 147 | /* We want the small data sections together, so single-instruction offsets 148 | can access them all, and initialized data all before uninitialized, so 149 | we can shorten the on-disk segment size. */ 150 | .sdata : 151 | { 152 | *(.sdata .sdata.* .gnu.linkonce.s.*) 153 | } 154 | .lit8 : { *(.lit8) } 155 | .lit4 : { *(.lit4) } 156 | _edata = .; 157 | PROVIDE (edata = .); 158 | __bss_start = .; 159 | _fbss = .; 160 | .sbss : 161 | { 162 | PROVIDE (__sbss_start = .); 163 | PROVIDE (___sbss_start = .); 164 | *(.dynsbss) 165 | *(.sbss .sbss.* .gnu.linkonce.sb.*) 166 | *(.scommon) 167 | PROVIDE (__sbss_end = .); 168 | PROVIDE (___sbss_end = .); 169 | } 170 | .bss : 171 | { 172 | *(.dynbss) 173 | *(.bss .bss.* .gnu.linkonce.b.*) 174 | *(COMMON) 175 | /* Align here to ensure that the .bss section occupies space up to 176 | _end. Align after .bss to ensure correct alignment even if the 177 | .bss section disappears because there are no input sections. */ 178 | . = ALIGN(32 / 8); 179 | } 180 | . = ALIGN(32 / 8); 181 | _end = .; 182 | PROVIDE (end = .); 183 | . = DATA_SEGMENT_END (.); 184 | /* Stabs debugging sections. */ 185 | .stab 0 : { *(.stab) } 186 | .stabstr 0 : { *(.stabstr) } 187 | .stab.excl 0 : { *(.stab.excl) } 188 | .stab.exclstr 0 : { *(.stab.exclstr) } 189 | .stab.index 0 : { *(.stab.index) } 190 | .stab.indexstr 0 : { *(.stab.indexstr) } 191 | .comment 0 : { *(.comment) } 192 | /* DWARF debug sections. 193 | Symbols in the DWARF debugging sections are relative to the beginning 194 | of the section so we begin them at 0. */ 195 | /* DWARF 1 */ 196 | .debug 0 : { *(.debug) } 197 | .line 0 : { *(.line) } 198 | /* GNU DWARF 1 extensions */ 199 | .debug_srcinfo 0 : { *(.debug_srcinfo) } 200 | .debug_sfnames 0 : { *(.debug_sfnames) } 201 | /* DWARF 1.1 and DWARF 2 */ 202 | .debug_aranges 0 : { *(.debug_aranges) } 203 | .debug_pubnames 0 : { *(.debug_pubnames) } 204 | /* DWARF 2 */ 205 | .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } 206 | .debug_abbrev 0 : { *(.debug_abbrev) } 207 | .debug_line 0 : { *(.debug_line) } 208 | .debug_frame 0 : { *(.debug_frame) } 209 | .debug_str 0 : { *(.debug_str) } 210 | .debug_loc 0 : { *(.debug_loc) } 211 | .debug_macinfo 0 : { *(.debug_macinfo) } 212 | /* SGI/MIPS DWARF 2 extensions */ 213 | .debug_weaknames 0 : { *(.debug_weaknames) } 214 | .debug_funcnames 0 : { *(.debug_funcnames) } 215 | .debug_typenames 0 : { *(.debug_typenames) } 216 | .debug_varnames 0 : { *(.debug_varnames) } 217 | .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) } 218 | .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) } 219 | /DISCARD/ : { *(.note.GNU-stack) } 220 | } 221 | -------------------------------------------------------------------------------- /IPL_SDK/pspipl.x: -------------------------------------------------------------------------------- 1 | /* Default linker script, for normal executables */ 2 | OUTPUT_FORMAT("elf32-littlemips", "elf32-bigmips", 3 | "elf32-littlemips") 4 | OUTPUT_ARCH(mips:allegrex) 5 | ENTRY(_start) 6 | SEARCH_DIR("c"); SEARCH_DIR("/devkitPro/devkitPSP_4.0.1/psp/lib"); 7 | /* Do we need any of these for elf? 8 | __DYNAMIC = 0; */ 9 | SECTIONS 10 | { 11 | /* Read-only sections, merged into text segment: */ 12 | PROVIDE (__executable_start = 0x040e0000); . = 0x040e0000; 13 | .rel.init : { *(.rel.init) } 14 | .rela.init : { *(.rela.init) } 15 | .rel.text : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) } 16 | .rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) } 17 | .rel.fini : { *(.rel.fini) } 18 | .rela.fini : { *(.rela.fini) } 19 | .rel.rodata : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) } 20 | .rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) } 21 | .rel.data.rel.ro : { *(.rel.data.rel.ro*) } 22 | .rela.data.rel.ro : { *(.rel.data.rel.ro*) } 23 | .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) } 24 | .rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) } 25 | .rel.tdata : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) } 26 | .rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) } 27 | .rel.tbss : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) } 28 | .rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) } 29 | .rel.ctors : { *(.rel.ctors) } 30 | .rela.ctors : { *(.rela.ctors) } 31 | .rel.dtors : { *(.rel.dtors) } 32 | .rela.dtors : { *(.rela.dtors) } 33 | .rel.got : { *(.rel.got) } 34 | .rela.got : { *(.rela.got) } 35 | .rel.sdata : { *(.rel.sdata .rel.sdata.* .rel.gnu.linkonce.s.*) } 36 | .rela.sdata : { *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) } 37 | .rel.sbss : { *(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*) } 38 | .rela.sbss : { *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*) } 39 | .rel.sdata2 : { *(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.*) } 40 | .rela.sdata2 : { *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) } 41 | .rel.sbss2 : { *(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.*) } 42 | .rela.sbss2 : { *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) } 43 | .rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) } 44 | .rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) } 45 | .rel.plt : { *(.rel.plt) } 46 | .rela.plt : { *(.rela.plt) } 47 | .interp : { *(.interp) } 48 | .dynamic : { *(.dynamic) } 49 | .hash : { *(.hash) } 50 | .dynsym : { *(.dynsym) } 51 | .dynstr : { *(.dynstr) } 52 | .gnu.version : { *(.gnu.version) } 53 | .gnu.version_d : { *(.gnu.version_d) } 54 | .gnu.version_r : { *(.gnu.version_r) } 55 | .init : 56 | { 57 | KEEP (*(.init)) 58 | } =0 59 | .plt : { *(.plt) } 60 | .text : 61 | { 62 | _ftext = . ; 63 | *(.text .stub .text.* .gnu.linkonce.t.*) 64 | KEEP (*(.text.*personality*)) 65 | /* .gnu.warning sections are handled specially by elf32.em. */ 66 | *(.gnu.warning) 67 | *(.mips16.fn.*) *(.mips16.call.*) 68 | } =0 69 | .fini : 70 | { 71 | KEEP (*(.fini)) 72 | } =0 73 | 74 | PROVIDE (__etext = .); 75 | PROVIDE (_etext = .); 76 | PROVIDE (etext = .); 77 | .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } 78 | .rodata1 : { *(.rodata1) } 79 | .sdata2 : { *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) } 80 | .sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) } 81 | .eh_frame_hdr : { *(.eh_frame_hdr) } 82 | .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) } 83 | .gcc_except_table : ONLY_IF_RO { KEEP (*(.gcc_except_table)) *(.gcc_except_table.*) } 84 | /* Adjust the address for the data segment. We want to adjust up to 85 | the same address within the page on the next page up. */ 86 | . = ALIGN (0x40) - ((0x40 - .) & (0x40 - 1)); . = DATA_SEGMENT_ALIGN (0x40, 0x1000); 87 | /* Exception handling */ 88 | .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) } 89 | .gcc_except_table : ONLY_IF_RW { KEEP (*(.gcc_except_table)) *(.gcc_except_table.*) } 90 | /* Thread Local Storage sections */ 91 | .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } 92 | .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } 93 | /* Ensure the __preinit_array_start label is properly aligned. We 94 | could instead move the label definition inside the section, but 95 | the linker would then create the section even if it turns out to 96 | be empty, which isn't pretty. */ 97 | . = ALIGN(32 / 8); 98 | 99 | PROVIDE (__preinit_array_start = .); 100 | .preinit_array : { KEEP (*(.preinit_array)) } 101 | PROVIDE (__preinit_array_end = .); 102 | PROVIDE (__init_array_start = .); 103 | .init_array : { KEEP (*(.init_array)) } 104 | PROVIDE (__init_array_end = .); 105 | PROVIDE (__fini_array_start = .); 106 | .fini_array : { KEEP (*(.fini_array)) } 107 | PROVIDE (__fini_array_end = .); 108 | .ctors : 109 | { 110 | /* gcc uses crtbegin.o to find the start of 111 | the constructors, so we make sure it is 112 | first. Because this is a wildcard, it 113 | doesn't matter if the user does not 114 | actually link against crtbegin.o; the 115 | linker won't look for a file to match a 116 | wildcard. The wildcard also means that it 117 | doesn't matter which directory crtbegin.o 118 | is in. */ 119 | KEEP (*crtbegin*.o(.ctors)) 120 | /* We don't want to include the .ctor section from 121 | from the crtend.o file until after the sorted ctors. 122 | The .ctor section from the crtend file contains the 123 | end of ctors marker and it must be last */ 124 | KEEP (*(EXCLUDE_FILE (*crtend*.o ) .ctors)) 125 | KEEP (*(SORT(.ctors.*))) 126 | KEEP (*(.ctors)) 127 | } 128 | .dtors : 129 | { 130 | KEEP (*crtbegin*.o(.dtors)) 131 | KEEP (*(EXCLUDE_FILE (*crtend*.o ) .dtors)) 132 | KEEP (*(SORT(.dtors.*))) 133 | KEEP (*(.dtors)) 134 | } 135 | .jcr : { KEEP (*(.jcr)) } 136 | .data.rel.ro : { *(.data.rel.ro.local) *(.data.rel.ro*) } 137 | . = DATA_SEGMENT_RELRO_END (0, .); 138 | .data : 139 | { 140 | _fdata = . ; 141 | *(.data .data.* .gnu.linkonce.d.*) 142 | KEEP (*(.gnu.linkonce.d.*personality*)) 143 | SORT(CONSTRUCTORS) 144 | } 145 | .data1 : { *(.data1) } 146 | . = .; 147 | _gp = ALIGN(16) + 0x7ff0; 148 | .got : { *(.got.plt) *(.got) } 149 | /* We want the small data sections together, so single-instruction offsets 150 | can access them all, and initialized data all before uninitialized, so 151 | we can shorten the on-disk segment size. */ 152 | .sdata : 153 | { 154 | *(.sdata .sdata.* .gnu.linkonce.s.*) 155 | } 156 | .lit8 : { *(.lit8) } 157 | .lit4 : { *(.lit4) } 158 | _edata = .; 159 | PROVIDE (edata = .); 160 | __bss_start = .; 161 | _fbss = .; 162 | 163 | PROVIDE (__tsize = ALIGN(32 / 8) - __executable_start - 0x10); 164 | 165 | .sbss : 166 | { 167 | PROVIDE (__sbss_start = .); 168 | PROVIDE (___sbss_start = .); 169 | *(.dynsbss) 170 | *(.sbss .sbss.* .gnu.linkonce.sb.*) 171 | *(.scommon) 172 | PROVIDE (__sbss_end = .); 173 | PROVIDE (___sbss_end = .); 174 | } 175 | .bss : 176 | { 177 | *(.dynbss) 178 | *(.bss .bss.* .gnu.linkonce.b.*) 179 | *(COMMON) 180 | /* Align here to ensure that the .bss section occupies space up to 181 | _end. Align after .bss to ensure correct alignment even if the 182 | .bss section disappears because there are no input sections. */ 183 | . = ALIGN(32 / 8); 184 | } 185 | . = ALIGN(32 / 8); 186 | _end = .; 187 | PROVIDE (end = .); 188 | . = DATA_SEGMENT_END (.); 189 | /* Stabs debugging sections. */ 190 | .stab 0 : { *(.stab) } 191 | .stabstr 0 : { *(.stabstr) } 192 | .stab.excl 0 : { *(.stab.excl) } 193 | .stab.exclstr 0 : { *(.stab.exclstr) } 194 | .stab.index 0 : { *(.stab.index) } 195 | .stab.indexstr 0 : { *(.stab.indexstr) } 196 | .comment 0 : { *(.comment) } 197 | /* DWARF debug sections. 198 | Symbols in the DWARF debugging sections are relative to the beginning 199 | of the section so we begin them at 0. */ 200 | /* DWARF 1 */ 201 | .debug 0 : { *(.debug) } 202 | .line 0 : { *(.line) } 203 | /* GNU DWARF 1 extensions */ 204 | .debug_srcinfo 0 : { *(.debug_srcinfo) } 205 | .debug_sfnames 0 : { *(.debug_sfnames) } 206 | /* DWARF 1.1 and DWARF 2 */ 207 | .debug_aranges 0 : { *(.debug_aranges) } 208 | .debug_pubnames 0 : { *(.debug_pubnames) } 209 | /* DWARF 2 */ 210 | .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } 211 | .debug_abbrev 0 : { *(.debug_abbrev) } 212 | .debug_line 0 : { *(.debug_line) } 213 | .debug_frame 0 : { *(.debug_frame) } 214 | .debug_str 0 : { *(.debug_str) } 215 | .debug_loc 0 : { *(.debug_loc) } 216 | .debug_macinfo 0 : { *(.debug_macinfo) } 217 | /* SGI/MIPS DWARF 2 extensions */ 218 | .debug_weaknames 0 : { *(.debug_weaknames) } 219 | .debug_funcnames 0 : { *(.debug_funcnames) } 220 | .debug_typenames 0 : { *(.debug_typenames) } 221 | .debug_varnames 0 : { *(.debug_varnames) } 222 | .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) } 223 | .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) } 224 | /DISCARD/ : { *(.note.GNU-stack) } 225 | } 226 | -------------------------------------------------------------------------------- /ML_FLASH_LED/payloadipl.x: -------------------------------------------------------------------------------- 1 | /* Default linker script, for normal executables */ 2 | OUTPUT_FORMAT("elf32-littlemips", "elf32-bigmips", 3 | "elf32-littlemips") 4 | OUTPUT_ARCH(mips:allegrex) 5 | ENTRY(_start) 6 | SEARCH_DIR("c"); SEARCH_DIR("/devkitPro/devkitPSP_4.0.1/psp/lib"); 7 | /* Do we need any of these for elf? 8 | __DYNAMIC = 0; */ 9 | SECTIONS 10 | { 11 | /* Read-only sections, merged into text segment: */ 12 | PROVIDE (__executable_start = 0x040c0000); . = 0x040c0000; 13 | .rel.init : { *(.rel.init) } 14 | .rela.init : { *(.rela.init) } 15 | .rel.text : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) } 16 | .rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) } 17 | .rel.fini : { *(.rel.fini) } 18 | .rela.fini : { *(.rela.fini) } 19 | .rel.rodata : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) } 20 | .rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) } 21 | .rel.data.rel.ro : { *(.rel.data.rel.ro*) } 22 | .rela.data.rel.ro : { *(.rel.data.rel.ro*) } 23 | .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) } 24 | .rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) } 25 | .rel.tdata : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) } 26 | .rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) } 27 | .rel.tbss : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) } 28 | .rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) } 29 | .rel.ctors : { *(.rel.ctors) } 30 | .rela.ctors : { *(.rela.ctors) } 31 | .rel.dtors : { *(.rel.dtors) } 32 | .rela.dtors : { *(.rela.dtors) } 33 | .rel.got : { *(.rel.got) } 34 | .rela.got : { *(.rela.got) } 35 | .rel.sdata : { *(.rel.sdata .rel.sdata.* .rel.gnu.linkonce.s.*) } 36 | .rela.sdata : { *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) } 37 | .rel.sbss : { *(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*) } 38 | .rela.sbss : { *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*) } 39 | .rel.sdata2 : { *(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.*) } 40 | .rela.sdata2 : { *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) } 41 | .rel.sbss2 : { *(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.*) } 42 | .rela.sbss2 : { *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) } 43 | .rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) } 44 | .rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) } 45 | .rel.plt : { *(.rel.plt) } 46 | .rela.plt : { *(.rela.plt) } 47 | .interp : { *(.interp) } 48 | .dynamic : { *(.dynamic) } 49 | .hash : { *(.hash) } 50 | .dynsym : { *(.dynsym) } 51 | .dynstr : { *(.dynstr) } 52 | .gnu.version : { *(.gnu.version) } 53 | .gnu.version_d : { *(.gnu.version_d) } 54 | .gnu.version_r : { *(.gnu.version_r) } 55 | .init : 56 | { 57 | KEEP (*(.init)) 58 | } =0 59 | .plt : { *(.plt) } 60 | .text : 61 | { 62 | _ftext = . ; 63 | *(.text .stub .text.* .gnu.linkonce.t.*) 64 | KEEP (*(.text.*personality*)) 65 | /* .gnu.warning sections are handled specially by elf32.em. */ 66 | *(.gnu.warning) 67 | *(.mips16.fn.*) *(.mips16.call.*) 68 | } =0 69 | .fini : 70 | { 71 | KEEP (*(.fini)) 72 | } =0 73 | 74 | PROVIDE (__etext = .); 75 | PROVIDE (_etext = .); 76 | PROVIDE (etext = .); 77 | .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } 78 | .rodata1 : { *(.rodata1) } 79 | .sdata2 : { *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) } 80 | .sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) } 81 | .eh_frame_hdr : { *(.eh_frame_hdr) } 82 | .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) } 83 | .gcc_except_table : ONLY_IF_RO { KEEP (*(.gcc_except_table)) *(.gcc_except_table.*) } 84 | /* Adjust the address for the data segment. We want to adjust up to 85 | the same address within the page on the next page up. */ 86 | . = ALIGN (0x40) - ((0x40 - .) & (0x40 - 1)); . = DATA_SEGMENT_ALIGN (0x40, 0x1000); 87 | /* Exception handling */ 88 | .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) } 89 | .gcc_except_table : ONLY_IF_RW { KEEP (*(.gcc_except_table)) *(.gcc_except_table.*) } 90 | /* Thread Local Storage sections */ 91 | .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } 92 | .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } 93 | /* Ensure the __preinit_array_start label is properly aligned. We 94 | could instead move the label definition inside the section, but 95 | the linker would then create the section even if it turns out to 96 | be empty, which isn't pretty. */ 97 | . = ALIGN(32 / 8); 98 | 99 | PROVIDE (__preinit_array_start = .); 100 | .preinit_array : { KEEP (*(.preinit_array)) } 101 | PROVIDE (__preinit_array_end = .); 102 | PROVIDE (__init_array_start = .); 103 | .init_array : { KEEP (*(.init_array)) } 104 | PROVIDE (__init_array_end = .); 105 | PROVIDE (__fini_array_start = .); 106 | .fini_array : { KEEP (*(.fini_array)) } 107 | PROVIDE (__fini_array_end = .); 108 | .ctors : 109 | { 110 | /* gcc uses crtbegin.o to find the start of 111 | the constructors, so we make sure it is 112 | first. Because this is a wildcard, it 113 | doesn't matter if the user does not 114 | actually link against crtbegin.o; the 115 | linker won't look for a file to match a 116 | wildcard. The wildcard also means that it 117 | doesn't matter which directory crtbegin.o 118 | is in. */ 119 | KEEP (*crtbegin*.o(.ctors)) 120 | /* We don't want to include the .ctor section from 121 | from the crtend.o file until after the sorted ctors. 122 | The .ctor section from the crtend file contains the 123 | end of ctors marker and it must be last */ 124 | KEEP (*(EXCLUDE_FILE (*crtend*.o ) .ctors)) 125 | KEEP (*(SORT(.ctors.*))) 126 | KEEP (*(.ctors)) 127 | } 128 | .dtors : 129 | { 130 | KEEP (*crtbegin*.o(.dtors)) 131 | KEEP (*(EXCLUDE_FILE (*crtend*.o ) .dtors)) 132 | KEEP (*(SORT(.dtors.*))) 133 | KEEP (*(.dtors)) 134 | } 135 | .jcr : { KEEP (*(.jcr)) } 136 | .data.rel.ro : { *(.data.rel.ro.local) *(.data.rel.ro*) } 137 | . = DATA_SEGMENT_RELRO_END (0, .); 138 | .data : 139 | { 140 | _fdata = . ; 141 | *(.data .data.* .gnu.linkonce.d.*) 142 | KEEP (*(.gnu.linkonce.d.*personality*)) 143 | SORT(CONSTRUCTORS) 144 | } 145 | .data1 : { *(.data1) } 146 | . = .; 147 | _gp = ALIGN(16) + 0x7ff0; 148 | .got : { *(.got.plt) *(.got) } 149 | /* We want the small data sections together, so single-instruction offsets 150 | can access them all, and initialized data all before uninitialized, so 151 | we can shorten the on-disk segment size. */ 152 | .sdata : 153 | { 154 | *(.sdata .sdata.* .gnu.linkonce.s.*) 155 | } 156 | .lit8 : { *(.lit8) } 157 | .lit4 : { *(.lit4) } 158 | _edata = .; 159 | PROVIDE (edata = .); 160 | __bss_start = .; 161 | _fbss = .; 162 | 163 | PROVIDE (__tsize = ALIGN(32 / 8) - __executable_start - 0x10); 164 | 165 | .sbss : 166 | { 167 | PROVIDE (__sbss_start = .); 168 | PROVIDE (___sbss_start = .); 169 | *(.dynsbss) 170 | *(.sbss .sbss.* .gnu.linkonce.sb.*) 171 | *(.scommon) 172 | PROVIDE (__sbss_end = .); 173 | PROVIDE (___sbss_end = .); 174 | } 175 | .bss : 176 | { 177 | *(.dynbss) 178 | *(.bss .bss.* .gnu.linkonce.b.*) 179 | *(COMMON) 180 | /* Align here to ensure that the .bss section occupies space up to 181 | _end. Align after .bss to ensure correct alignment even if the 182 | .bss section disappears because there are no input sections. */ 183 | . = ALIGN(32 / 8); 184 | } 185 | . = ALIGN(32 / 8); 186 | _end = .; 187 | PROVIDE (end = .); 188 | . = DATA_SEGMENT_END (.); 189 | /* Stabs debugging sections. */ 190 | .stab 0 : { *(.stab) } 191 | .stabstr 0 : { *(.stabstr) } 192 | .stab.excl 0 : { *(.stab.excl) } 193 | .stab.exclstr 0 : { *(.stab.exclstr) } 194 | .stab.index 0 : { *(.stab.index) } 195 | .stab.indexstr 0 : { *(.stab.indexstr) } 196 | .comment 0 : { *(.comment) } 197 | /* DWARF debug sections. 198 | Symbols in the DWARF debugging sections are relative to the beginning 199 | of the section so we begin them at 0. */ 200 | /* DWARF 1 */ 201 | .debug 0 : { *(.debug) } 202 | .line 0 : { *(.line) } 203 | /* GNU DWARF 1 extensions */ 204 | .debug_srcinfo 0 : { *(.debug_srcinfo) } 205 | .debug_sfnames 0 : { *(.debug_sfnames) } 206 | /* DWARF 1.1 and DWARF 2 */ 207 | .debug_aranges 0 : { *(.debug_aranges) } 208 | .debug_pubnames 0 : { *(.debug_pubnames) } 209 | /* DWARF 2 */ 210 | .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } 211 | .debug_abbrev 0 : { *(.debug_abbrev) } 212 | .debug_line 0 : { *(.debug_line) } 213 | .debug_frame 0 : { *(.debug_frame) } 214 | .debug_str 0 : { *(.debug_str) } 215 | .debug_loc 0 : { *(.debug_loc) } 216 | .debug_macinfo 0 : { *(.debug_macinfo) } 217 | /* SGI/MIPS DWARF 2 extensions */ 218 | .debug_weaknames 0 : { *(.debug_weaknames) } 219 | .debug_funcnames 0 : { *(.debug_funcnames) } 220 | .debug_typenames 0 : { *(.debug_typenames) } 221 | .debug_varnames 0 : { *(.debug_varnames) } 222 | .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) } 223 | .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) } 224 | /DISCARD/ : { *(.note.GNU-stack) } 225 | } 226 | -------------------------------------------------------------------------------- /ML_RECOVERY_LOADER/payloadipl.x: -------------------------------------------------------------------------------- 1 | /* Default linker script, for normal executables */ 2 | OUTPUT_FORMAT("elf32-littlemips", "elf32-bigmips", 3 | "elf32-littlemips") 4 | OUTPUT_ARCH(mips:allegrex) 5 | ENTRY(_start) 6 | SEARCH_DIR("c"); SEARCH_DIR("/devkitPro/devkitPSP_4.0.1/psp/lib"); 7 | /* Do we need any of these for elf? 8 | __DYNAMIC = 0; */ 9 | SECTIONS 10 | { 11 | /* Read-only sections, merged into text segment: */ 12 | PROVIDE (__executable_start = 0x040c0000); . = 0x040c0000; 13 | .rel.init : { *(.rel.init) } 14 | .rela.init : { *(.rela.init) } 15 | .rel.text : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) } 16 | .rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) } 17 | .rel.fini : { *(.rel.fini) } 18 | .rela.fini : { *(.rela.fini) } 19 | .rel.rodata : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) } 20 | .rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) } 21 | .rel.data.rel.ro : { *(.rel.data.rel.ro*) } 22 | .rela.data.rel.ro : { *(.rel.data.rel.ro*) } 23 | .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) } 24 | .rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) } 25 | .rel.tdata : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) } 26 | .rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) } 27 | .rel.tbss : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) } 28 | .rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) } 29 | .rel.ctors : { *(.rel.ctors) } 30 | .rela.ctors : { *(.rela.ctors) } 31 | .rel.dtors : { *(.rel.dtors) } 32 | .rela.dtors : { *(.rela.dtors) } 33 | .rel.got : { *(.rel.got) } 34 | .rela.got : { *(.rela.got) } 35 | .rel.sdata : { *(.rel.sdata .rel.sdata.* .rel.gnu.linkonce.s.*) } 36 | .rela.sdata : { *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) } 37 | .rel.sbss : { *(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*) } 38 | .rela.sbss : { *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*) } 39 | .rel.sdata2 : { *(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.*) } 40 | .rela.sdata2 : { *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) } 41 | .rel.sbss2 : { *(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.*) } 42 | .rela.sbss2 : { *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) } 43 | .rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) } 44 | .rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) } 45 | .rel.plt : { *(.rel.plt) } 46 | .rela.plt : { *(.rela.plt) } 47 | .interp : { *(.interp) } 48 | .dynamic : { *(.dynamic) } 49 | .hash : { *(.hash) } 50 | .dynsym : { *(.dynsym) } 51 | .dynstr : { *(.dynstr) } 52 | .gnu.version : { *(.gnu.version) } 53 | .gnu.version_d : { *(.gnu.version_d) } 54 | .gnu.version_r : { *(.gnu.version_r) } 55 | .init : 56 | { 57 | KEEP (*(.init)) 58 | } =0 59 | .plt : { *(.plt) } 60 | .text : 61 | { 62 | _ftext = . ; 63 | *(.text .stub .text.* .gnu.linkonce.t.*) 64 | KEEP (*(.text.*personality*)) 65 | /* .gnu.warning sections are handled specially by elf32.em. */ 66 | *(.gnu.warning) 67 | *(.mips16.fn.*) *(.mips16.call.*) 68 | } =0 69 | .fini : 70 | { 71 | KEEP (*(.fini)) 72 | } =0 73 | 74 | PROVIDE (__etext = .); 75 | PROVIDE (_etext = .); 76 | PROVIDE (etext = .); 77 | .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } 78 | .rodata1 : { *(.rodata1) } 79 | .sdata2 : { *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) } 80 | .sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) } 81 | .eh_frame_hdr : { *(.eh_frame_hdr) } 82 | .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) } 83 | .gcc_except_table : ONLY_IF_RO { KEEP (*(.gcc_except_table)) *(.gcc_except_table.*) } 84 | /* Adjust the address for the data segment. We want to adjust up to 85 | the same address within the page on the next page up. */ 86 | . = ALIGN (0x40) - ((0x40 - .) & (0x40 - 1)); . = DATA_SEGMENT_ALIGN (0x40, 0x1000); 87 | /* Exception handling */ 88 | .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) } 89 | .gcc_except_table : ONLY_IF_RW { KEEP (*(.gcc_except_table)) *(.gcc_except_table.*) } 90 | /* Thread Local Storage sections */ 91 | .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } 92 | .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } 93 | /* Ensure the __preinit_array_start label is properly aligned. We 94 | could instead move the label definition inside the section, but 95 | the linker would then create the section even if it turns out to 96 | be empty, which isn't pretty. */ 97 | . = ALIGN(32 / 8); 98 | 99 | PROVIDE (__preinit_array_start = .); 100 | .preinit_array : { KEEP (*(.preinit_array)) } 101 | PROVIDE (__preinit_array_end = .); 102 | PROVIDE (__init_array_start = .); 103 | .init_array : { KEEP (*(.init_array)) } 104 | PROVIDE (__init_array_end = .); 105 | PROVIDE (__fini_array_start = .); 106 | .fini_array : { KEEP (*(.fini_array)) } 107 | PROVIDE (__fini_array_end = .); 108 | .ctors : 109 | { 110 | /* gcc uses crtbegin.o to find the start of 111 | the constructors, so we make sure it is 112 | first. Because this is a wildcard, it 113 | doesn't matter if the user does not 114 | actually link against crtbegin.o; the 115 | linker won't look for a file to match a 116 | wildcard. The wildcard also means that it 117 | doesn't matter which directory crtbegin.o 118 | is in. */ 119 | KEEP (*crtbegin*.o(.ctors)) 120 | /* We don't want to include the .ctor section from 121 | from the crtend.o file until after the sorted ctors. 122 | The .ctor section from the crtend file contains the 123 | end of ctors marker and it must be last */ 124 | KEEP (*(EXCLUDE_FILE (*crtend*.o ) .ctors)) 125 | KEEP (*(SORT(.ctors.*))) 126 | KEEP (*(.ctors)) 127 | } 128 | .dtors : 129 | { 130 | KEEP (*crtbegin*.o(.dtors)) 131 | KEEP (*(EXCLUDE_FILE (*crtend*.o ) .dtors)) 132 | KEEP (*(SORT(.dtors.*))) 133 | KEEP (*(.dtors)) 134 | } 135 | .jcr : { KEEP (*(.jcr)) } 136 | .data.rel.ro : { *(.data.rel.ro.local) *(.data.rel.ro*) } 137 | . = DATA_SEGMENT_RELRO_END (0, .); 138 | .data : 139 | { 140 | _fdata = . ; 141 | *(.data .data.* .gnu.linkonce.d.*) 142 | KEEP (*(.gnu.linkonce.d.*personality*)) 143 | SORT(CONSTRUCTORS) 144 | } 145 | .data1 : { *(.data1) } 146 | . = .; 147 | _gp = ALIGN(16) + 0x7ff0; 148 | .got : { *(.got.plt) *(.got) } 149 | /* We want the small data sections together, so single-instruction offsets 150 | can access them all, and initialized data all before uninitialized, so 151 | we can shorten the on-disk segment size. */ 152 | .sdata : 153 | { 154 | *(.sdata .sdata.* .gnu.linkonce.s.*) 155 | } 156 | .lit8 : { *(.lit8) } 157 | .lit4 : { *(.lit4) } 158 | _edata = .; 159 | PROVIDE (edata = .); 160 | __bss_start = .; 161 | _fbss = .; 162 | 163 | PROVIDE (__tsize = ALIGN(32 / 8) - __executable_start - 0x10); 164 | 165 | .sbss : 166 | { 167 | PROVIDE (__sbss_start = .); 168 | PROVIDE (___sbss_start = .); 169 | *(.dynsbss) 170 | *(.sbss .sbss.* .gnu.linkonce.sb.*) 171 | *(.scommon) 172 | PROVIDE (__sbss_end = .); 173 | PROVIDE (___sbss_end = .); 174 | } 175 | .bss : 176 | { 177 | *(.dynbss) 178 | *(.bss .bss.* .gnu.linkonce.b.*) 179 | *(COMMON) 180 | /* Align here to ensure that the .bss section occupies space up to 181 | _end. Align after .bss to ensure correct alignment even if the 182 | .bss section disappears because there are no input sections. */ 183 | . = ALIGN(32 / 8); 184 | } 185 | . = ALIGN(32 / 8); 186 | _end = .; 187 | PROVIDE (end = .); 188 | . = DATA_SEGMENT_END (.); 189 | /* Stabs debugging sections. */ 190 | .stab 0 : { *(.stab) } 191 | .stabstr 0 : { *(.stabstr) } 192 | .stab.excl 0 : { *(.stab.excl) } 193 | .stab.exclstr 0 : { *(.stab.exclstr) } 194 | .stab.index 0 : { *(.stab.index) } 195 | .stab.indexstr 0 : { *(.stab.indexstr) } 196 | .comment 0 : { *(.comment) } 197 | /* DWARF debug sections. 198 | Symbols in the DWARF debugging sections are relative to the beginning 199 | of the section so we begin them at 0. */ 200 | /* DWARF 1 */ 201 | .debug 0 : { *(.debug) } 202 | .line 0 : { *(.line) } 203 | /* GNU DWARF 1 extensions */ 204 | .debug_srcinfo 0 : { *(.debug_srcinfo) } 205 | .debug_sfnames 0 : { *(.debug_sfnames) } 206 | /* DWARF 1.1 and DWARF 2 */ 207 | .debug_aranges 0 : { *(.debug_aranges) } 208 | .debug_pubnames 0 : { *(.debug_pubnames) } 209 | /* DWARF 2 */ 210 | .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } 211 | .debug_abbrev 0 : { *(.debug_abbrev) } 212 | .debug_line 0 : { *(.debug_line) } 213 | .debug_frame 0 : { *(.debug_frame) } 214 | .debug_str 0 : { *(.debug_str) } 215 | .debug_loc 0 : { *(.debug_loc) } 216 | .debug_macinfo 0 : { *(.debug_macinfo) } 217 | /* SGI/MIPS DWARF 2 extensions */ 218 | .debug_weaknames 0 : { *(.debug_weaknames) } 219 | .debug_funcnames 0 : { *(.debug_funcnames) } 220 | .debug_typenames 0 : { *(.debug_typenames) } 221 | .debug_varnames 0 : { *(.debug_varnames) } 222 | .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) } 223 | .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) } 224 | /DISCARD/ : { *(.note.GNU-stack) } 225 | } 226 | --------------------------------------------------------------------------------