ViewVC Help
View File | Revision Log | View Changeset | Root Listing
root/Oni2/ps2launchargs/source/uLaunchELF/loader/loader.c
Revision: 1101
Committed: Wed Feb 7 05:08:54 2018 UTC (7 years, 8 months ago) by iritscen
Content type: text/x-csrc
File size: 11517 byte(s)
Log Message:
Added following to ps2launchargs:\n-Source code.\n-DLL needed to run ps2client.\n-Instructions for building uLaunchELF.

File Contents

# Content
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 //--------------------------------------------------------------

Properties

Name Value
svn:executable *