Skip to content

Commit 7aece93

Browse files
committed
mbr: update for the rewritten loader
1 parent 454b077 commit 7aece93

5 files changed

Lines changed: 128 additions & 29 deletions

File tree

mbr/include/loader.h

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,28 @@
22
#define _LOADER_H_
33
#include <stdint.h>
44

5-
// Loads and executes the ELF boot_elf points to
6-
// Based on PS2SDK elf-loader
7-
int LoadEmbeddedELF(int resetIOP, uint8_t *boot_elf, int argc, char *argv[]);
5+
typedef enum {
6+
ShutdownType_All, // Default
7+
ShutdownType_None, // NICHDD
8+
ShutdownType_HDD, // NIC
9+
} ShutdownType;
810

9-
// Loads ELF from file specified in argv[0]
10-
int LoadELFFromFile(int resetIOP, int argc, char *argv[]);
11+
typedef struct {
12+
int argc; // Argument count for the ELF binary
13+
char **argv; // ELF arguments; argv[0] must be the path to the binary even if elfMem is set
14+
15+
void *elfMem; // Optional: Memory location of the ELF binary when loading ELF from memory
16+
int elfSize; // Optional: Size of the ELF binary in memory
17+
18+
char *ioprpPath; // Optional: Path to the IOPRP binary. Will be ignored when ioprpMem is set
19+
void *ioprpMem; // Optional: Memory location of the IOPRP binary when loading IOPRP image from memory
20+
int ioprpSize; // Optional: Size of the IOPRP binary in memory
21+
22+
int resetIOP; // Indicates if IOP reset is needed (1 = yes). If used with IOPRP, it will be ignored
23+
ShutdownType dev9ShutdownType; // Type of shutdown to perform for DEV9
24+
} LoadOptions;
25+
26+
// Loads ELF using specified options
27+
int loadELF(LoadOptions *options);
1128

1229
#endif

mbr/src/disc.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,12 @@ void handlePS1Disc(char *titleID, char *titleVersion) {
125125
free(titleID);
126126
free(titleVersion);
127127
char *argv[] = {HOSD_DKWDRV_PATH};
128-
LoadELFFromFile(0, 1, argv);
128+
LoadOptions opts = {
129+
.argc = 1,
130+
.argv = argv,
131+
};
132+
loadELF(&opts);
133+
return;
129134
}
130135
DPRINTF("DKWDRV was not found, falling back to PS1DRV\n");
131136
}
@@ -149,7 +154,14 @@ void handlePS1Disc(char *titleID, char *titleVersion) {
149154
if (settings.flags & FLAG_PS1DRV_USE_VN) {
150155
DPRINTF("Starting PS1DRV via PS1VModeNeg with title ID %s and version %s\n", argv[0], argv[1]);
151156
sceSifExitCmd();
152-
LoadEmbeddedELF(0, ps1vn_elf, 2, argv);
157+
LoadOptions opts = {
158+
.elfMem = ps1vn_elf,
159+
.elfSize = size_ps1vn_elf,
160+
.argc = 2,
161+
.argv = argv,
162+
};
163+
loadELF(&opts);
164+
return;
153165
} else {
154166
char *argv[] = {titleID, titleVersion};
155167
DPRINTF("Starting PS1DRV with title ID %s and version %s\n", argv[0], argv[1]);

mbr/src/hdd.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,11 @@ void runFsck() {
7979
return;
8080

8181
umountPFS();
82-
LoadELFFromFile(0, 1, arg);
82+
LoadOptions opts = {
83+
.argc = 1,
84+
.argv = arg,
85+
};
86+
loadELF(&opts);
8387
}
8488

8589
// Mounts the partition specified in path

mbr/src/hdd_start.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,13 @@ int handlePATINFO(int partFd, AttributeAreaFile elf, int argc, char *argv[]) {
106106
sceSifInitRpc(0);
107107

108108
char *nargv[1] = {argv[2]};
109-
LoadEmbeddedELF(0, elfMem, 1, nargv);
110-
return 0;
109+
LoadOptions opts = {
110+
.elfMem = elfMem,
111+
.elfSize = elf.size,
112+
.argc = 1,
113+
.argv = nargv,
114+
};
115+
return loadELF(&opts);
111116
}
112117

113118
// Starts HDD application using data from the partition attribute area header
@@ -188,7 +193,11 @@ int startHDDApplication(int argc, char *argv[]) {
188193
if (!strncmp(bootPath, "pfs", 3)) {
189194
// Build the full path
190195
sprintf("%s:%s", bootPath, argv[2], bootPath);
191-
return LoadELFFromFile(0, argc, argv);
196+
LoadOptions opts = {
197+
.argc = argc,
198+
.argv = argv,
199+
};
200+
return loadELF(&opts);
192201
}
193202

194203
return -1;

mbr/src/loader.c

Lines changed: 75 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#include "loader.h"
2+
#include "dprintf.h"
13
#include "init.h"
24
#include <errno.h>
35
#include <iopcontrol.h>
@@ -46,46 +48,101 @@ typedef struct {
4648
#define ELF_MAGIC 0x464c457f
4749
#define ELF_PT_LOAD 1
4850

49-
// Loads and executes the ELF boot_elf points to
50-
// Based on PS2SDK elf-loader
51-
int LoadEmbeddedELF(int resetIOP, uint8_t *boot_elf, int argc, char *argv[]) {
51+
// Loads and executes the embedded loader with provided arguments
52+
int executeLoader(int argc, char *argv[]) {
5253
elf_header_t *eh;
5354
elf_pheader_t *eph;
5455
void *pdata;
5556
int i;
5657

57-
eh = (elf_header_t *)boot_elf;
58+
DPRINTF("Starting the embedded ELF loader with argc = %d\n", argc);
59+
for (i = 0; i < argc; i++)
60+
DPRINTF("argv[%d] = %s\n", i, argv[i]);
61+
62+
eh = (elf_header_t *)loader_elf;
5863
if (_lw((uint32_t)&eh->ident) != ELF_MAGIC)
5964
__builtin_trap();
6065

61-
eph = (elf_pheader_t *)(boot_elf + eh->phoff);
66+
eph = (elf_pheader_t *)(loader_elf + eh->phoff);
6267

6368
// Scan through the ELF's program headers and copy them into RAM
6469
for (i = 0; i < eh->phnum; i++) {
6570
if (eph[i].type != ELF_PT_LOAD)
6671
continue;
6772

68-
pdata = (void *)(boot_elf + eph[i].offset);
73+
pdata = (void *)(loader_elf + eph[i].offset);
6974
memcpy(eph[i].vaddr, pdata, eph[i].filesz);
7075
}
7176

7277
FlushCache(0);
7378
FlushCache(2);
7479

75-
if (resetIOP) {
76-
argc++;
77-
char **nargv = malloc(argc * sizeof(char *));
78-
for (i = 0; i < argc-1; i++)
79-
nargv[i] = argv[i];
80+
return ExecPS2((void *)eh->entry, NULL, argc, argv);
81+
}
8082

81-
nargv[argc-1] = "-iopreset";
83+
// Loads ELF from file specified in argv[0]
84+
int loadELF(LoadOptions *options) {
85+
int argPos = 4; // Account for "-la="
86+
int argc = 0;
87+
char loaderArg[9] = "-la=\0\0\0\0\0";
88+
char elfMemArg[22] = {0};
89+
char ioprpMemArg[22] = {0};
8290

83-
free(argv);
84-
argv = nargv;
91+
// Basic arguments
92+
if (options->resetIOP) {
93+
loaderArg[argPos++] = 'R';
94+
argc = 1;
95+
}
96+
if (options->dev9ShutdownType == ShutdownType_HDD) {
97+
loaderArg[argPos++] = 'N';
98+
argc = 1;
99+
} else if (options->dev9ShutdownType == ShutdownType_None) {
100+
loaderArg[argPos++] = 'D';
101+
argc = 1;
85102
}
86103

87-
return ExecPS2((void *)eh->entry, NULL, argc, argv);
88-
}
104+
// IOPRP
105+
if (options->ioprpMem || options->ioprpPath) {
106+
loaderArg[argPos++] = 'I';
107+
argc = (argc == 0) ? 2 : argc + 1;
89108

90-
// Loads ELF from file specified in argv[0]
91-
int LoadELFFromFile(int resetIOP, int argc, char *argv[]) { return LoadEmbeddedELF(resetIOP, loader_elf, argc, argv); }
109+
if (options->ioprpMem)
110+
sprintf(ioprpMemArg, "mem:%08lX:%08lX", (uint32_t)options->ioprpMem, (uint32_t)options->ioprpSize);
111+
}
112+
113+
// In-memory ELF
114+
if (options->elfMem) {
115+
loaderArg[argPos++] = 'E';
116+
argc = (argc == 0) ? 2 : argc + 1;
117+
118+
sprintf(elfMemArg, "mem:%08lX:%08lX", (uint32_t)options->elfMem, (uint32_t)options->elfSize);
119+
}
120+
121+
char **argv = options->argv;
122+
if (argc != 0) {
123+
argv = malloc((argc + options->argc) * sizeof(char *));
124+
// Copy the original arguments
125+
for (int i = 0; i < options->argc; i++)
126+
argv[i] = options->argv[i];
127+
128+
// Add loader arguments (ELF and IOPRP argument order is important)
129+
int argvOffset = argc;
130+
argc += options->argc;
131+
132+
// ELF argument
133+
if (elfMemArg[0] != '\0')
134+
argv[argc - (argvOffset--)] = elfMemArg;
135+
136+
// IOPRP argument
137+
if (ioprpMemArg[0] != '\0')
138+
argv[argc - (argvOffset--)] = ioprpMemArg;
139+
else if (options->ioprpPath)
140+
argv[argc - (argvOffset--)] = options->ioprpPath;
141+
142+
// Loader arguments
143+
argv[argc - argvOffset] = loaderArg;
144+
} else
145+
argc = options->argc;
146+
147+
return executeLoader(argc, argv);
148+
}

0 commit comments

Comments
 (0)