-
Notifications
You must be signed in to change notification settings - Fork 279
/
elfldr.c
120 lines (93 loc) · 2.42 KB
/
elfldr.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
/*
Copyright 2009-2010, jimmikaelkael <[email protected]>
Copyright 2009-2010, misfire <[email protected]>
Licenced under Academic Free License version 3.0
Review OpenUsbLd README & LICENSE files for further details.
*/
#include <tamtypes.h>
#include <iopcontrol.h>
#include <kernel.h>
#include <sifrpc.h>
#include <loadfile.h>
#include <string.h>
#include <stdio.h>
static inline void _strcpy(char *dst, const char *src)
{
memcpy(dst, src, strlen(src) + 1);
}
static inline void _strcat(char *dst, const char *src)
{
_strcpy(&dst[strlen(dst)], src);
}
static int _strncmp(const char *s1, const char *s2, int length)
{
const char *a = s1;
const char *b = s2;
while (length > 0) {
if ((*a == 0) || (*b == 0))
return -1;
if (*a++ != *b++)
return 1;
length--;
}
return 0;
}
static inline void BootError(char *filename)
{
char *argv[2];
argv[0] = "BootError";
argv[1] = filename;
ExecOSD(2, argv);
}
static inline void InitializeUserMemory(unsigned int start, unsigned int end)
{
unsigned int i;
for (i = start; i < end; i += 64) {
asm(
"\tsq $0, 0(%0) \n"
"\tsq $0, 16(%0) \n"
"\tsq $0, 32(%0) \n"
"\tsq $0, 48(%0) \n" ::"r"(i));
}
}
int main(int argc, char *argv[])
{
int result;
t_ExecData exd;
SifInitRpc(0);
exd.epc = 0;
//clear memory.
InitializeUserMemory(0x00100000, GetMemorySize());
FlushCache(0);
SifLoadFileInit();
result = SifLoadElf(argv[0], &exd);
SifLoadFileExit();
if (result == 0 && exd.epc != 0) {
//Final IOP reset, to fill the IOP with the default modules.
while (!SifIopReset("", 0)) {
};
FlushCache(0);
FlushCache(2);
while (!SifIopSync()) {
};
SifInitRpc(0);
//Load modules.
SifLoadFileInit();
SifLoadModule("rom0:SIO2MAN", 0, NULL);
SifLoadModule("rom0:MCMAN", 0, NULL);
SifLoadModule("rom0:MCSERV", 0, NULL);
SifLoadFileExit();
SifExitRpc();
if (_strncmp(argv[0], "pfs", 3) == 0) {
static char _argv[256];
_strcpy(_argv, "hdd0:+OPL:");
_strcat(_argv, argv[0]);
argv[0] = _argv;
}
ExecPS2((void *)exd.epc, (void *)exd.gp, argc, argv);
} else {
SifExitRpc();
}
BootError(argv[0]);
return 0;
}