| 1 | 
 //-------------------------------------------------------------- | 
 
 
 
 
 
 | 2 | 
 //File name:    loader.c | 
 
 
 
 
 
 | 3 | 
 //-------------------------------------------------------------- | 
 
 
 
 
 
 | 4 | 
 //dlanor: This subprogram has been modified to minimize the code | 
 
 
 
 
 
 | 5 | 
 //dlanor: size of the resident loader portion. Some of the parts | 
 
 
 
 
 
 | 6 | 
 //dlanor: that were moved into the main program include loading | 
 
 
 
 
 
 | 7 | 
 //dlanor: of all IRXs and mounting pfs0: for ELFs on hdd. | 
 
 
 
 
 
 | 8 | 
 //dlanor: Another change was to skip threading in favor of ExecPS2 | 
 
 
 
 
 
 | 9 | 
 /*================================================================== | 
 
 
 
 
 
 | 10 | 
 ==                                                                                      == | 
 
 
 
 
 
 | 11 | 
 ==      Copyright(c)2004  Adam Metcalf(gamblore_@hotmail.com)           == | 
 
 
 
 
 
 | 12 | 
 ==      Copyright(c)2004  Thomas Hawcroft(t0mb0la@yahoo.com)            == | 
 
 
 
 
 
 | 13 | 
 ==      This file is subject to terms and conditions shown in the       == | 
 
 
 
 
 
 | 14 | 
 ==      file LICENSE which should be kept in the top folder of  == | 
 
 
 
 
 
 | 15 | 
 ==      this distribution.                                                      == | 
 
 
 
 
 
 | 16 | 
 ==                                                                                      == | 
 
 
 
 
 
 | 17 | 
 ==      Portions of this code taken from PS2Link:                               == | 
 
 
 
 
 
 | 18 | 
 ==                              pkoLoadElf                                              == | 
 
 
 
 
 
 | 19 | 
 ==                              wipeUserMemory                                  == | 
 
 
 
 
 
 | 20 | 
 ==                              (C) 2003 Tord Lindstrom (pukko@home.se) == | 
 
 
 
 
 
 | 21 | 
 ==                              (C) 2003 adresd (adresd_ps2dev@yahoo.com)       == | 
 
 
 
 
 
 | 22 | 
 ==      Portions of this code taken from Independence MC exploit        == | 
 
 
 
 
 
 | 23 | 
 ==                              tLoadElf                                                == | 
 
 
 
 
 
 | 24 | 
 ==                              LoadAndRunHDDElf                                        == | 
 
 
 
 
 
 | 25 | 
 ==                              (C) 2003 Marcus Brown <mrbrown@0xd6.org>        == | 
 
 
 
 
 
 | 26 | 
 ==                                                                                      == | 
 
 
 
 
 
 | 27 | 
 ==================================================================*/ | 
 
 
 
 
 
 | 28 | 
 #include "tamtypes.h" | 
 
 
 
 
 
 | 29 | 
 #include "debug.h" | 
 
 
 
 
 
 | 30 | 
 #include "kernel.h" | 
 
 
 
 
 
 | 31 | 
 #include "sifrpc.h" | 
 
 
 
 
 
 | 32 | 
 #include "loadfile.h" | 
 
 
 
 
 
 | 33 | 
 #include "fileio.h" | 
 
 
 
 
 
 | 34 | 
 #include "iopcontrol.h" | 
 
 
 
 
 
 | 35 | 
 #include "stdarg.h" | 
 
 
 
 
 
 | 36 | 
 #include "stdio.h" // Iritscen: added this for printf() | 
 
 
 
 
 
 | 37 | 
 #include "string.h" | 
 
 
 
 
 
 | 38 | 
 #include "malloc.h" | 
 
 
 
 
 
 | 39 | 
 #include "libmc.h" | 
 
 
 
 
 
 | 40 | 
 #include "iopheap.h" | 
 
 
 
 
 
 | 41 | 
 #include "sys/fcntl.h" | 
 
 
 
 
 
 | 42 | 
 #include "sys/stat.h" | 
 
 
 
 
 
 | 43 | 
 #include "sys/ioctl.h" | 
 
 
 
 
 
 | 44 | 
 #include "fileXio_rpc.h" | 
 
 
 
 
 
 | 45 | 
 #include "errno.h" | 
 
 
 
 
 
 | 46 | 
 #include "libhdd.h" | 
 
 
 
 
 
 | 47 | 
 #include "sbv_patches.h" | 
 
 
 
 
 
 | 48 | 
 //-------------------------------------------------------------- | 
 
 
 
 
 
 | 49 | 
 //#define DEBUG | 
 
 
 
 
 
 | 50 | 
 #ifdef DEBUG | 
 
 
 
 
 
 | 51 | 
 #define dbgprintf(args...) scr_printf(args) | 
 
 
 
 
 
 | 52 | 
 #define dbginit_scr() init_scr() | 
 
 
 
 
 
 | 53 | 
 #else | 
 
 
 
 
 
 | 54 | 
 #define dbgprintf(args...) do { } while(0) | 
 
 
 
 
 
 | 55 | 
 #define dbginit_scr() do { } while(0) | 
 
 
 
 
 
 | 56 | 
 #endif | 
 
 
 
 
 
 | 57 | 
  | 
 
 
 
 
 
 | 58 | 
 // ELF-header structures and identifiers | 
 
 
 
 
 
 | 59 | 
 #define ELF_MAGIC       0x464c457f | 
 
 
 
 
 
 | 60 | 
 #define ELF_PT_LOAD     1 | 
 
 
 
 
 
 | 61 | 
  | 
 
 
 
 
 
 | 62 | 
 //-------------------------------------------------------------- | 
 
 
 
 
 
 | 63 | 
 typedef struct | 
 
 
 
 
 
 | 64 | 
 { | 
 
 
 
 
 
 | 65 | 
         u8      ident[16]; | 
 
 
 
 
 
 | 66 | 
         u16     type; | 
 
 
 
 
 
 | 67 | 
         u16     machine; | 
 
 
 
 
 
 | 68 | 
         u32     version; | 
 
 
 
 
 
 | 69 | 
         u32     entry; | 
 
 
 
 
 
 | 70 | 
         u32     phoff; | 
 
 
 
 
 
 | 71 | 
         u32     shoff; | 
 
 
 
 
 
 | 72 | 
         u32     flags; | 
 
 
 
 
 
 | 73 | 
         u16     ehsize; | 
 
 
 
 
 
 | 74 | 
         u16     phentsize; | 
 
 
 
 
 
 | 75 | 
         u16     phnum; | 
 
 
 
 
 
 | 76 | 
         u16     shentsize; | 
 
 
 
 
 
 | 77 | 
         u16     shnum; | 
 
 
 
 
 
 | 78 | 
         u16     shstrndx; | 
 
 
 
 
 
 | 79 | 
         } elf_header_t; | 
 
 
 
 
 
 | 80 | 
 //-------------------------------------------------------------- | 
 
 
 
 
 
 | 81 | 
 typedef struct | 
 
 
 
 
 
 | 82 | 
 { | 
 
 
 
 
 
 | 83 | 
         u32     type; | 
 
 
 
 
 
 | 84 | 
         u32     offset; | 
 
 
 
 
 
 | 85 | 
         void    *vaddr; | 
 
 
 
 
 
 | 86 | 
         u32     paddr; | 
 
 
 
 
 
 | 87 | 
         u32     filesz; | 
 
 
 
 
 
 | 88 | 
         u32     memsz; | 
 
 
 
 
 
 | 89 | 
         u32     flags; | 
 
 
 
 
 
 | 90 | 
         u32     align; | 
 
 
 
 
 
 | 91 | 
         } elf_pheader_t; | 
 
 
 
 
 
 | 92 | 
 //-------------------------------------------------------------- | 
 
 
 
 
 
 | 93 | 
 t_ExecData elfdata; | 
 
 
 
 
 
 | 94 | 
  | 
 
 
 
 
 
 | 95 | 
 int fileMode =  FIO_S_IRUSR | FIO_S_IWUSR | FIO_S_IXUSR | FIO_S_IRGRP | FIO_S_IWGRP | FIO_S_IXGRP | FIO_S_IROTH | FIO_S_IWOTH | FIO_S_IXOTH; | 
 
 
 
 
 
 | 96 | 
 char HDDpath[256]; | 
 
 
 
 
 
 | 97 | 
 char partition[128]; | 
 
 
 
 
 
 | 98 | 
  | 
 
 
 
 
 
 | 99 | 
 static int pkoLoadElf(char *path); | 
 
 
 
 
 
 | 100 | 
  | 
 
 
 
 
 
 | 101 | 
 int userThreadID = 0; | 
 
 
 
 
 
 | 102 | 
 ////static char userThreadStack[16*1024] __attribute__((aligned(16))); | 
 
 
 
 
 
 | 103 | 
  | 
 
 
 
 
 
 | 104 | 
 #define MAX_ARGS 16 | 
 
 
 
 
 
 | 105 | 
 #define MAX_ARGLEN 256 | 
 
 
 
 
 
 | 106 | 
  | 
 
 
 
 
 
 | 107 | 
 struct argData | 
 
 
 
 
 
 | 108 | 
 { | 
 
 
 
 
 
 | 109 | 
         int flag;                     // Contains thread id atm | 
 
 
 
 
 
 | 110 | 
         int argc; | 
 
 
 
 
 
 | 111 | 
         char *argv[MAX_ARGS]; | 
 
 
 
 
 
 | 112 | 
 } __attribute__((packed)) userArgs; | 
 
 
 
 
 
 | 113 | 
 //-------------------------------------------------------------- | 
 
 
 
 
 
 | 114 | 
 //End of data declarations | 
 
 
 
 
 
 | 115 | 
 //-------------------------------------------------------------- | 
 
 
 
 
 
 | 116 | 
 //Start of function code: | 
 
 
 
 
 
 | 117 | 
 //-------------------------------------------------------------- | 
 
 
 
 
 
 | 118 | 
 // Read ELF from hard drive to required location(s) in memory. | 
 
 
 
 
 
 | 119 | 
 // Modified version of loader from Independence | 
 
 
 
 
 
 | 120 | 
 //      (C) 2003 Marcus R. Brown <mrbrown@0xd6.org> | 
 
 
 
 
 
 | 121 | 
 //-------------------------------------------------------------- | 
 
 
 
 
 
 | 122 | 
 static int tLoadElf(char *filename) | 
 
 
 
 
 
 | 123 | 
 { | 
 
 
 
 
 
 | 124 | 
         u8 *boot_elf = (u8 *)0x1800000; | 
 
 
 
 
 
 | 125 | 
         elf_header_t *eh = (elf_header_t *)boot_elf; | 
 
 
 
 
 
 | 126 | 
         elf_pheader_t *eph; | 
 
 
 
 
 
 | 127 | 
  | 
 
 
 
 
 
 | 128 | 
         int fd, size, i; | 
 
 
 
 
 
 | 129 | 
  | 
 
 
 
 
 
 | 130 | 
 //NB: Coming here means pfs0: was mounted correctly earlier | 
 
 
 
 
 
 | 131 | 
         if ((fd = fileXioOpen(filename, O_RDONLY, fileMode)) < 0) | 
 
 
 
 
 
 | 132 | 
         { | 
 
 
 
 
 
 | 133 | 
                 dbgprintf("Failed in fileXioOpen %s\n",filename); | 
 
 
 
 
 
 | 134 | 
                 goto error; | 
 
 
 
 
 
 | 135 | 
         } | 
 
 
 
 
 
 | 136 | 
         dbgprintf("Opened file %s\n",filename); | 
 
 
 
 
 
 | 137 | 
         size = fileXioLseek(fd, 0, SEEK_END); | 
 
 
 
 
 
 | 138 | 
         dbgprintf("File size = %i\n",size); | 
 
 
 
 
 
 | 139 | 
         if (!size) | 
 
 
 
 
 
 | 140 | 
         { | 
 
 
 
 
 
 | 141 | 
                 dbgprintf("Failed in fileXioLseek\n"); | 
 
 
 
 
 
 | 142 | 
                 fileXioClose(fd); | 
 
 
 
 
 
 | 143 | 
                 goto error; | 
 
 
 
 
 
 | 144 | 
                 } | 
 
 
 
 
 
 | 145 | 
         fileXioLseek(fd, 0, SEEK_SET); | 
 
 
 
 
 
 | 146 | 
         fileXioRead(fd, boot_elf, sizeof(elf_header_t)); | 
 
 
 
 
 
 | 147 | 
         dbgprintf("Read elf header from file\n"); | 
 
 
 
 
 
 | 148 | 
         fileXioLseek(fd, eh->phoff, SEEK_SET); | 
 
 
 
 
 
 | 149 | 
         eph = (elf_pheader_t *)(boot_elf + eh->phoff); | 
 
 
 
 
 
 | 150 | 
         size=eh->phnum*eh->phentsize; | 
 
 
 
 
 
 | 151 | 
         size=fileXioRead(fd, (void *)eph, size); | 
 
 
 
 
 
 | 152 | 
         dbgprintf("Read %i bytes of program header(s) from file\n",size); | 
 
 
 
 
 
 | 153 | 
         for (i = 0; i < eh->phnum; i++) | 
 
 
 
 
 
 | 154 | 
         { | 
 
 
 
 
 
 | 155 | 
                 if (eph[i].type != ELF_PT_LOAD) | 
 
 
 
 
 
 | 156 | 
                 continue; | 
 
 
 
 
 
 | 157 | 
  | 
 
 
 
 
 
 | 158 | 
                 fileXioLseek(fd, eph[i].offset, SEEK_SET); | 
 
 
 
 
 
 | 159 | 
                 size=eph[i].filesz; | 
 
 
 
 
 
 | 160 | 
                 size=fileXioRead(fd, eph[i].vaddr, size); | 
 
 
 
 
 
 | 161 | 
                 dbgprintf("Read %i bytes to %x\n", size, eph[i].vaddr); | 
 
 
 
 
 
 | 162 | 
                 if (eph[i].memsz > eph[i].filesz) | 
 
 
 
 
 
 | 163 | 
                         memset(eph[i].vaddr + eph[i].filesz, 0, | 
 
 
 
 
 
 | 164 | 
                                eph[i].memsz - eph[i].filesz); | 
 
 
 
 
 
 | 165 | 
         }                | 
 
 
 
 
 
 | 166 | 
  | 
 
 
 
 
 
 | 167 | 
         fileXioClose(fd); | 
 
 
 
 
 
 | 168 | 
 //      fileXioUmount("pfs0:");         We leave the filesystem mounted now for fakehost | 
 
 
 
 
 
 | 169 | 
  | 
 
 
 
 
 
 | 170 | 
         if (_lw((u32)&eh->ident) != ELF_MAGIC)          // this should have already been | 
 
 
 
 
 
 | 171 | 
         {                                         // done by menu, but a double-check | 
 
 
 
 
 
 | 172 | 
                 dbgprintf("Not a recognised ELF.\n");   // doesn't do any harm | 
 
 
 
 
 
 | 173 | 
                 goto error; | 
 
 
 
 
 
 | 174 | 
         } | 
 
 
 
 
 
 | 175 | 
          | 
 
 
 
 
 
 | 176 | 
         dbgprintf("entry=%x\n",eh->entry); | 
 
 
 
 
 
 | 177 | 
         elfdata.epc=eh->entry; | 
 
 
 
 
 
 | 178 | 
         return 0; | 
 
 
 
 
 
 | 179 | 
 error: | 
 
 
 
 
 
 | 180 | 
         elfdata.epc=0; | 
 
 
 
 
 
 | 181 | 
         return -1; | 
 
 
 
 
 
 | 182 | 
 } | 
 
 
 
 
 
 | 183 | 
 //-------------------------------------------------------------- | 
 
 
 
 
 
 | 184 | 
 //End of func:  int tLoadElf(char *filename) | 
 
 
 
 
 
 | 185 | 
 //-------------------------------------------------------------- | 
 
 
 
 
 
 | 186 | 
 // Load the actual elf, and create a thread for it | 
 
 
 
 
 
 | 187 | 
 // Return the thread id | 
 
 
 
 
 
 | 188 | 
 // PS2Link (C) 2003 Tord Lindstrom (pukko@home.se) | 
 
 
 
 
 
 | 189 | 
 //         (C) 2003 adresd (adresd_ps2dev@yahoo.com) | 
 
 
 
 
 
 | 190 | 
 //-------------------------------------------------------------- | 
 
 
 
 
 
 | 191 | 
 static int pkoLoadElf(char *path) | 
 
 
 
 
 
 | 192 | 
 { | 
 
 
 
 
 
 | 193 | 
         ee_thread_t th_attr; | 
 
 
 
 
 
 | 194 | 
         int ret=0; | 
 
 
 
 
 
 | 195 | 
         int pid; | 
 
 
 
 
 
 | 196 | 
  | 
 
 
 
 
 
 | 197 | 
         if(!strncmp(path, "host", 4)) ret = SifLoadElf(path, &elfdata); | 
 
 
 
 
 
 | 198 | 
         else if(!strncmp(path, "mc", 2)) ret = SifLoadElf(path, &elfdata); | 
 
 
 
 
 
 | 199 | 
         else if(!strncmp(path, "cdrom", 5)) ret = SifLoadElf(path, &elfdata); | 
 
 
 
 
 
 | 200 | 
         else if(!strncmp(path, "cdfs", 4)) ret = SifLoadElf(path, &elfdata); | 
 
 
 
 
 
 | 201 | 
         else if(!strncmp(path, "pfs0", 4)) ret = tLoadElf(path); | 
 
 
 
 
 
 | 202 | 
         else if(!strncmp(path, "vmc", 3)) ret = tLoadElf(path); | 
 
 
 
 
 
 | 203 | 
         else ret = SifLoadElf(path, &elfdata); | 
 
 
 
 
 
 | 204 | 
  | 
 
 
 
 
 
 | 205 | 
         FlushCache(0); | 
 
 
 
 
 
 | 206 | 
         FlushCache(2); | 
 
 
 
 
 
 | 207 | 
  | 
 
 
 
 
 
 | 208 | 
         dbgprintf("EE: LoadElf returned %d\n", ret); | 
 
 
 
 
 
 | 209 | 
  | 
 
 
 
 
 
 | 210 | 
         dbgprintf("EE: Creating user thread (ent: %x, gp: %x, st: %x)\n",  | 
 
 
 
 
 
 | 211 | 
                   elfdata.epc, elfdata.gp, elfdata.sp); | 
 
 
 
 
 
 | 212 | 
  | 
 
 
 
 
 
 | 213 | 
         if (elfdata.epc == 0) { | 
 
 
 
 
 
 | 214 | 
                 dbgprintf("EE: Could not load file\n"); | 
 
 
 
 
 
 | 215 | 
                 return -1; | 
 
 
 
 
 
 | 216 | 
         } | 
 
 
 
 
 
 | 217 | 
  | 
 
 
 
 
 
 | 218 | 
         th_attr.func = (void *)elfdata.epc; | 
 
 
 
 
 
 | 219 | 
 ////    th_attr.stack = userThreadStack; | 
 
 
 
 
 
 | 220 | 
 ////    th_attr.stack_size = sizeof(userThreadStack); | 
 
 
 
 
 
 | 221 | 
         th_attr.gp_reg = (void *)elfdata.gp; | 
 
 
 
 
 
 | 222 | 
         th_attr.initial_priority = 64; | 
 
 
 
 
 
 | 223 | 
  | 
 
 
 
 
 
 | 224 | 
         pid = 1; ////CreateThread(&th_attr); | 
 
 
 
 
 
 | 225 | 
         if (pid < 0) { | 
 
 
 
 
 
 | 226 | 
                 dbgprintf("EE: Create user thread failed %d\n", pid); | 
 
 
 
 
 
 | 227 | 
                 return -1; | 
 
 
 
 
 
 | 228 | 
         } | 
 
 
 
 
 
 | 229 | 
         dbgprintf("EE: Created user thread: %d\n", pid); | 
 
 
 
 
 
 | 230 | 
  | 
 
 
 
 
 
 | 231 | 
         return pid; | 
 
 
 
 
 
 | 232 | 
 } | 
 
 
 
 
 
 | 233 | 
 //-------------------------------------------------------------- | 
 
 
 
 
 
 | 234 | 
 //End of func:  static int pkoLoadElf(char *path) | 
 
 
 
 
 
 | 235 | 
 //-------------------------------------------------------------- | 
 
 
 
 
 
 | 236 | 
 // Clear user memory | 
 
 
 
 
 
 | 237 | 
 // PS2Link (C) 2003 Tord Lindstrom (pukko@home.se) | 
 
 
 
 
 
 | 238 | 
 //         (C) 2003 adresd (adresd_ps2dev@yahoo.com) | 
 
 
 
 
 
 | 239 | 
 //-------------------------------------------------------------- | 
 
 
 
 
 
 | 240 | 
 void wipeUserMem(void) | 
 
 
 
 
 
 | 241 | 
 { | 
 
 
 
 
 
 | 242 | 
         int i; | 
 
 
 
 
 
 | 243 | 
         for (i = 0x100000; i < 0x2000000 ; i += 64) { | 
 
 
 
 
 
 | 244 | 
                 asm ( | 
 
 
 
 
 
 | 245 | 
                         "\tsq $0, 0(%0) \n" | 
 
 
 
 
 
 | 246 | 
                         "\tsq $0, 16(%0) \n" | 
 
 
 
 
 
 | 247 | 
                         "\tsq $0, 32(%0) \n" | 
 
 
 
 
 
 | 248 | 
                         "\tsq $0, 48(%0) \n" | 
 
 
 
 
 
 | 249 | 
                         :: "r" (i) ); | 
 
 
 
 
 
 | 250 | 
         } | 
 
 
 
 
 
 | 251 | 
 } | 
 
 
 
 
 
 | 252 | 
 //-------------------------------------------------------------- | 
 
 
 
 
 
 | 253 | 
 //End of func:  void wipeUserMem(void) | 
 
 
 
 
 
 | 254 | 
 //-------------------------------------------------------------- | 
 
 
 
 
 
 | 255 | 
 // C standard strrchr func.. returns pointer to the last occurance of a | 
 
 
 
 
 
 | 256 | 
 // character in a string, or NULL if not found | 
 
 
 
 
 
 | 257 | 
 // PS2Link (C) 2003 Tord Lindstrom (pukko@home.se) | 
 
 
 
 
 
 | 258 | 
 //         (C) 2003 adresd (adresd_ps2dev@yahoo.com) | 
 
 
 
 
 
 | 259 | 
 //-------------------------------------------------------------- | 
 
 
 
 
 
 | 260 | 
 char *strrchr(const char *sp, int i) | 
 
 
 
 
 
 | 261 | 
 { | 
 
 
 
 
 
 | 262 | 
         const char *last = NULL; | 
 
 
 
 
 
 | 263 | 
         char c = i; | 
 
 
 
 
 
 | 264 | 
  | 
 
 
 
 
 
 | 265 | 
         while (*sp) | 
 
 
 
 
 
 | 266 | 
         { | 
 
 
 
 
 
 | 267 | 
                 if (*sp == c) | 
 
 
 
 
 
 | 268 | 
                 { | 
 
 
 
 
 
 | 269 | 
                         last = sp; | 
 
 
 
 
 
 | 270 | 
                 } | 
 
 
 
 
 
 | 271 | 
                 sp++; | 
 
 
 
 
 
 | 272 | 
         } | 
 
 
 
 
 
 | 273 | 
  | 
 
 
 
 
 
 | 274 | 
         if (*sp == c) | 
 
 
 
 
 
 | 275 | 
         { | 
 
 
 
 
 
 | 276 | 
                 last = sp; | 
 
 
 
 
 
 | 277 | 
         } | 
 
 
 
 
 
 | 278 | 
  | 
 
 
 
 
 
 | 279 | 
         return (char *) last; | 
 
 
 
 
 
 | 280 | 
 } | 
 
 
 
 
 
 | 281 | 
 //-------------------------------------------------------------- | 
 
 
 
 
 
 | 282 | 
 //End of func:  char *strrchr(const char *sp, int i) | 
 
 
 
 
 
 | 283 | 
 //-------------------------------------------------------------- | 
 
 
 
 
 
 | 284 | 
 // *** MAIN *** | 
 
 
 
 
 
 | 285 | 
 //-------------------------------------------------------------- | 
 
 
 
 
 
 | 286 | 
 int main(int argc, char *argv[]) | 
 
 
 
 
 
 | 287 | 
 { | 
 
 
 
 
 
 | 288 | 
         char s[256],fakepart[128], *ptr; | 
 
 
 
 
 
 | 289 | 
         int pid=-1; | 
 
 
 
 
 
 | 290 | 
  | 
 
 
 
 
 
 | 291 | 
 // Initialize | 
 
 
 
 
 
 | 292 | 
         SifInitRpc(0); | 
 
 
 
 
 
 | 293 | 
         dbginit_scr(); | 
 
 
 
 
 
 | 294 | 
         wipeUserMem(); | 
 
 
 
 
 
 | 295 | 
         dbgprintf("Welcome to Loader of LaunchELF v3.50\nPlease wait...loading.\n"); | 
 
 
 
 
 
 | 296 | 
  | 
 
 
 
 
 
 | 297 | 
         strcpy(s,argv[0]); | 
 
 
 
 
 
 | 298 | 
         dbgprintf("argv[0] = %s\n",s); | 
 
 
 
 
 
 | 299 | 
     /*if (argc==1) // Iritscen: Commented this out and changed "(argc==2)" to "(argc>=2)" below in order to allow add'l args | 
 
 
 
 
 
 | 300 | 
         {                                               // should be two params passed by menu | 
 
 
 
 
 
 | 301 | 
                 while(1);                               // leave this here for adding mc0, host or other | 
 
 
 
 
 
 | 302 | 
                                                         // to be added in future | 
 
 
 
 
 
 | 303 | 
         }*/ | 
 
 
 
 
 
 | 304 | 
         if (argc>=2)                            // if call came from hddmenu.elf | 
 
 
 
 
 
 | 305 | 
         {                                               // arg1=path to ELF, arg2=partition to mount | 
 
 
 
 
 
 | 306 | 
                 strcpy(partition,argv[1]); | 
 
 
 
 
 
 | 307 | 
                 dbgprintf("argv[1] = %s\n", partition); | 
 
 
 
 
 
 | 308 | 
                 strcpy(HDDpath,s); | 
 
 
 
 
 
 | 309 | 
         } | 
 
 
 
 
 
 | 310 | 
         dbgprintf("Loading %s\n",HDDpath); | 
 
 
 
 
 
 | 311 | 
         pid = pkoLoadElf(HDDpath); | 
 
 
 
 
 
 | 312 | 
         dbgprintf("pkoLoadElf returned %i\n",pid); | 
 
 
 
 
 
 | 313 | 
 ////    if (pid < 0) | 
 
 
 
 
 
 | 314 | 
 ////    { | 
 
 
 
 
 
 | 315 | 
 ////            dbgprintf("failed\n"); | 
 
 
 
 
 
 | 316 | 
 ////            dbgprintf("Could not execute file %s\n", HDDpath); | 
 
 
 
 
 
 | 317 | 
 ////            return -1; | 
 
 
 
 
 
 | 318 | 
 ////    } | 
 
 
 
 
 
 | 319 | 
         if(!strncmp(HDDpath, "pfs0", 4)) | 
 
 
 
 
 
 | 320 | 
         { | 
 
 
 
 
 
 | 321 | 
                 strcpy(fakepart,HDDpath); | 
 
 
 
 
 
 | 322 | 
                 ptr=strrchr(fakepart,'/'); | 
 
 
 
 
 
 | 323 | 
                 if(ptr==NULL) strcpy(fakepart,"pfs0:"); | 
 
 
 
 
 
 | 324 | 
                 else | 
 
 
 
 
 
 | 325 | 
                 { | 
 
 
 
 
 
 | 326 | 
                         ptr++; | 
 
 
 
 
 
 | 327 | 
                         *ptr='\0'; | 
 
 
 
 
 
 | 328 | 
                 } | 
 
 
 
 
 
 | 329 | 
                 ptr=strrchr(s,'/'); | 
 
 
 
 
 
 | 330 | 
                 if(ptr==NULL) ptr=strrchr(s,':'); | 
 
 
 
 
 
 | 331 | 
                 if(ptr!=NULL) | 
 
 
 
 
 
 | 332 | 
                 { | 
 
 
 
 
 
 | 333 | 
                         ptr++; | 
 
 
 
 
 
 | 334 | 
                         strcpy(HDDpath,"host:"); | 
 
 
 
 
 
 | 335 | 
                         strcat(HDDpath,ptr); | 
 
 
 
 
 
 | 336 | 
                 } | 
 
 
 
 
 
 | 337 | 
         } | 
 
 
 
 
 
 | 338 | 
          | 
 
 
 
 
 
 | 339 | 
 ////    FlushCache(0); | 
 
 
 
 
 
 | 340 | 
 ////    FlushCache(2); | 
 
 
 
 
 
 | 341 | 
          | 
 
 
 
 
 
 | 342 | 
         userThreadID = pid; | 
 
 
 
 
 
 | 343 | 
  | 
 
 
 
 
 
 | 344 | 
         // Iritscen: Copy extra arguments in argv[] to userArgs | 
 
 
 
 
 
 | 345 | 
         if (argc > 2) | 
 
 
 
 
 
 | 346 | 
         { | 
 
 
 
 
 
 | 347 | 
                 printf("uLaunchELF loader: Received %d launch argument(s) for the game:\n", argc - 2); | 
 
 
 
 
 
 | 348 | 
                 userArgs.argc = argc - 1; | 
 
 
 
 
 
 | 349 | 
                 userArgs.argv[0] = HDDpath; | 
 
 
 
 
 
 | 350 | 
                 int a; | 
 
 
 
 
 
 | 351 | 
                 for (a = 0; a < argc - 2; a++) | 
 
 
 
 
 
 | 352 | 
                 { | 
 
 
 
 
 
 | 353 | 
                         userArgs.argv[a + 1] = argv[a + 2]; | 
 
 
 
 
 
 | 354 | 
                         printf("   %s\n", argv[a + 2]); | 
 
 
 
 
 
 | 355 | 
                 } | 
 
 
 
 
 
 | 356 | 
         } | 
 
 
 
 
 
 | 357 | 
         userArgs.flag = (int)&userThreadID; | 
 
 
 
 
 
 | 358 | 
  | 
 
 
 
 
 
 | 359 | 
 ////    ret = StartThread(userThreadID, &userArgs); | 
 
 
 
 
 
 | 360 | 
 ////    if (ret < 0) | 
 
 
 
 
 
 | 361 | 
 ////    { | 
 
 
 
 
 
 | 362 | 
 ////            dbgprintf("failed\n"); | 
 
 
 
 
 
 | 363 | 
 ////            dbgprintf("EE: Start user thread failed %d\n", ret); | 
 
 
 
 
 
 | 364 | 
 ////            DeleteThread(userThreadID); | 
 
 
 
 
 
 | 365 | 
 ////            return -1; | 
 
 
 
 
 
 | 366 | 
 ////    } | 
 
 
 
 
 
 | 367 | 
 ////    SleepThread(); | 
 
 
 
 
 
 | 368 | 
          | 
 
 
 
 
 
 | 369 | 
         __asm__ __volatile__( | 
 
 
 
 
 
 | 370 | 
                 ".set  noreorder\n\t" | 
 
 
 
 
 
 | 371 | 
                 "jal     FlushCache\n\t" | 
 
 
 
 
 
 | 372 | 
                 "li      $a0, 0\n\t" | 
 
 
 
 
 
 | 373 | 
                 "jal     FlushCache\n\t" | 
 
 
 
 
 
 | 374 | 
                 "li      $a0, 2\n\t" | 
 
 
 
 
 
 | 375 | 
                 "lui     $sp, 0x000a\n\t" | 
 
 
 
 
 
 | 376 | 
                 "nop\n\t" | 
 
 
 
 
 
 | 377 | 
                 "addiu   $sp, $sp, 0x8000\n\t" | 
 
 
 
 
 
 | 378 | 
                 "nop\n\t" | 
 
 
 
 
 
 | 379 | 
                 ".set  reorder\n\t" | 
 
 
 
 
 
 | 380 | 
         ); | 
 
 
 
 
 
 | 381 | 
         ExecPS2((void *)elfdata.epc, (void *)elfdata.gp, userArgs.argc, userArgs.argv); | 
 
 
 
 
 
 | 382 | 
         return 0; | 
 
 
 
 
 
 | 383 | 
 } | 
 
 
 
 
 
 | 384 | 
 //-------------------------------------------------------------- | 
 
 
 
 
 
 | 385 | 
 //End of func:  int main(int argc, char *argv[]) | 
 
 
 
 
 
 | 386 | 
 //-------------------------------------------------------------- | 
 
 
 
 
 
 | 387 | 
 //End of file:  loader.c | 
 
 
 
 
 
 | 388 | 
 //-------------------------------------------------------------- |