|
| 1 | +#include "loader.h" |
| 2 | +#include "dprintf.h" |
1 | 3 | #include "init.h" |
2 | 4 | #include <errno.h> |
3 | 5 | #include <iopcontrol.h> |
@@ -46,46 +48,101 @@ typedef struct { |
46 | 48 | #define ELF_MAGIC 0x464c457f |
47 | 49 | #define ELF_PT_LOAD 1 |
48 | 50 |
|
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[]) { |
52 | 53 | elf_header_t *eh; |
53 | 54 | elf_pheader_t *eph; |
54 | 55 | void *pdata; |
55 | 56 | int i; |
56 | 57 |
|
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; |
58 | 63 | if (_lw((uint32_t)&eh->ident) != ELF_MAGIC) |
59 | 64 | __builtin_trap(); |
60 | 65 |
|
61 | | - eph = (elf_pheader_t *)(boot_elf + eh->phoff); |
| 66 | + eph = (elf_pheader_t *)(loader_elf + eh->phoff); |
62 | 67 |
|
63 | 68 | // Scan through the ELF's program headers and copy them into RAM |
64 | 69 | for (i = 0; i < eh->phnum; i++) { |
65 | 70 | if (eph[i].type != ELF_PT_LOAD) |
66 | 71 | continue; |
67 | 72 |
|
68 | | - pdata = (void *)(boot_elf + eph[i].offset); |
| 73 | + pdata = (void *)(loader_elf + eph[i].offset); |
69 | 74 | memcpy(eph[i].vaddr, pdata, eph[i].filesz); |
70 | 75 | } |
71 | 76 |
|
72 | 77 | FlushCache(0); |
73 | 78 | FlushCache(2); |
74 | 79 |
|
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 | +} |
80 | 82 |
|
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}; |
82 | 90 |
|
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; |
85 | 102 | } |
86 | 103 |
|
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; |
89 | 108 |
|
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