12
12
#include <kernel/sched.h>
13
13
#include <kernel/logger.h>
14
14
#include <kernel/elf.h>
15
+ #include <kernel/modules.h>
16
+
17
+ int execmve (Thread * , void * , const char * * , const char * * );
15
18
16
19
/* execveMemory(): executes a program from memory
17
20
* params: ptr - pointer to the program in memory
@@ -107,7 +110,7 @@ pid_t execveMemory(const void *ptr, const char **argv, const char **envp) {
107
110
return pid ;
108
111
}
109
112
110
- /* execve(): executes a program from a file
113
+ /* execve(): replaces the current program, executes a program from a file
111
114
* params: t - parent thread structure
112
115
* params: name - file name of the program
113
116
* params: argv - arguments to be passed to the program
@@ -118,3 +121,101 @@ pid_t execveMemory(const void *ptr, const char **argv, const char **envp) {
118
121
int execve (Thread * t , const char * name , const char * * argv , const char * * envp ) {
119
122
return 0 ; /* todo */
120
123
}
124
+
125
+ /* execrdv(): replaces the current program, executes a program from the ramdisk
126
+ * this is only used before file system drivers are loaded
127
+ * params: t - parent thread structure
128
+ * params: name - file name of the program
129
+ * params: argv - arguments to be passed to the program
130
+ * returns: should not return on success
131
+ */
132
+
133
+ int execrdv (Thread * t , const char * name , const char * * argv ) {
134
+ schedLock ();
135
+ setScheduling (false);
136
+
137
+ // load from ramdisk
138
+ int64_t size = ramdiskFileSize (name );
139
+ if (size <= sizeof (ELFFileHeader )) {
140
+ setScheduling (true);
141
+ schedRelease ();
142
+ return -1 ;
143
+ }
144
+
145
+ void * image = malloc (size );
146
+ if (!image ) {
147
+ setScheduling (true);
148
+ schedRelease ();
149
+ return -1 ;
150
+ }
151
+
152
+ if (ramdiskRead (image , name , size ) != size ) {
153
+ setScheduling (true);
154
+ schedRelease ();
155
+ return -1 ;
156
+ }
157
+
158
+ return execmve (t , image , argv , NULL );
159
+ }
160
+
161
+ /* execmve(): helper function that replaces the current running program from memory
162
+ * params: t - parent thread structure
163
+ * params: image - image of the program in memory
164
+ * params: argv - arguments to be passed to the program
165
+ * params: envp - environmental variables
166
+ * returns: should not return on success
167
+ */
168
+
169
+ int execmve (Thread * t , void * image , const char * * argv , const char * * envp ) {
170
+ // create the new context before deleting the current one
171
+ // this guarantees we can return on failure
172
+ void * newctx = calloc (1 , PLATFORM_CONTEXT_SIZE );
173
+ if (!newctx ) {
174
+ free (image );
175
+ setScheduling (true);
176
+ schedRelease ();
177
+ return -1 ;
178
+ }
179
+
180
+ if (!platformCreateContext (newctx , PLATFORM_CONTEXT_USER , 0 , 0 )) {
181
+ free (newctx );
182
+ free (image );
183
+ setScheduling (true);
184
+ schedRelease ();
185
+ return -1 ;
186
+ }
187
+
188
+ void * oldctx = t -> context ;
189
+ t -> context = newctx ;
190
+
191
+ threadUseContext (t -> tid ); // switch to our new context
192
+
193
+ // parse the binary
194
+ uint64_t highest ;
195
+ uint64_t entry = loadELF (image , & highest );
196
+ free (image );
197
+ if (!entry || !highest ) {
198
+ t -> context = oldctx ;
199
+ free (newctx );
200
+ setScheduling (true);
201
+ schedRelease ();
202
+ return -1 ;
203
+ }
204
+
205
+ if (platformSetContext (t , entry , highest , argv , envp )) {
206
+ t -> context = oldctx ;
207
+ free (newctx );
208
+ setScheduling (true);
209
+ schedRelease ();
210
+ return -1 ;
211
+ }
212
+
213
+ // TODO: here we've successfully loaded the new program, but we also need
214
+ // to free up memory used by the original program
215
+ free (oldctx );
216
+
217
+ schedAdjustTimeslice ();
218
+ setScheduling (true);
219
+ schedRelease ();
220
+ return 0 ; // return to syscall dispatcher; the thread will not see this return
221
+ }
0 commit comments