00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include <ubixos/exec.h>
00031 #include <ubixos/sched.h>
00032 #include <ubixos/ld.h>
00033 #include <ubixos/kpanic.h>
00034 #include <ubixos/endtask.h>
00035 #include <vmm/vmm.h>
00036 #include <lib/kmalloc.h>
00037 #include <lib/kprintf.h>
00038 #include <lib/string.h>
00039 #include <assert.h>
00040
00041 #define STACK_ADDR 0xC800000
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 uInt32 execThread(void (* tproc)(void),uInt32 stack,char *arg) {
00055 kTask_t * newProcess = 0x0;
00056
00057 newProcess = schedNewTask();
00058 assert(newProcess);
00059 if (stack < 0x100000)
00060 kpanic("exec: stack not in valid area: [0x%X]\n",stack);
00061
00062
00063 newProcess->tss.back_link = 0x0;
00064 newProcess->tss.esp0 = 0x0;
00065 newProcess->tss.ss0 = 0x0;
00066 newProcess->tss.esp1 = 0x0;
00067 newProcess->tss.ss1 = 0x0;
00068 newProcess->tss.esp2 = 0x0;
00069 newProcess->tss.ss2 = 0x0;
00070 newProcess->tss.cr3 = (unsigned int)kernelPageDirectory;
00071 newProcess->tss.eip = (unsigned int)tproc;
00072 newProcess->tss.eflags = 0x206;
00073 newProcess->tss.esp = stack;
00074 newProcess->tss.ebp = stack;
00075 newProcess->tss.esi = 0x0;
00076 newProcess->tss.edi = 0x0;
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088 newProcess->tss.es = 0x10;
00089 newProcess->tss.cs = 0x08;
00090 newProcess->tss.ss = 0x10;
00091 newProcess->tss.ds = 0x10;
00092 newProcess->tss.fs = 0x10;
00093 newProcess->tss.gs = 0x10;
00094
00095 newProcess->tss.ldt = 0x18;
00096 newProcess->tss.trace_bitmap = 0x0000;
00097 newProcess->tss.io_map = 0x8000;
00098 newProcess->oInfo.vmStart = 0x6400000;
00099
00100 newProcess->imageFd = 0x0;
00101
00102
00103 asm volatile(
00104 "pusha \n"
00105 "movl %%esp,%%ecx \n"
00106 "movl %1,%%eax \n"
00107 "movl %%eax,%%esp \n"
00108 "pushl %%ebx \n"
00109 "pushl %%ebx \n"
00110 "pushl %%ebx \n"
00111 "movl %%esp,%%eax \n"
00112 "movl %%eax,%1 \n"
00113 "movl %%ecx,%%esp \n"
00114 "popa \n"
00115 :
00116 : "b" (arg),"m" (newProcess->tss.esp)
00117 );
00118
00119
00120 sched_setStatus(newProcess->id,READY);
00121
00122
00123 return((uInt32)newProcess);
00124 }
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142 void execFile(char *file,int argc,char **argv,int console) {
00143
00144 int i = 0x0;
00145 int x = 0x0;
00146 u_int32_t *tmp = 0x0;
00147
00148 fileDescriptor *tmpFd = 0x0;
00149 elfHeader *binaryHeader = 0x0;
00150 elfProgramHeader *programHeader = 0x0;
00151
00152
00153 _current = schedNewTask();
00154 assert(_current);
00155 _current->gid = 0x0;
00156 _current->uid = 0x0;
00157 _current->term = tty_find(console);
00158 if (_current->term == 0x0)
00159 kprintf("Error: invalid console\n");
00160
00161
00162 _current->term->owner = _current->id;
00163
00164
00165 _current->tss.cr3 = (uInt32)vmmCreateVirtualSpace(_current->id);
00166
00167
00168 asm volatile(
00169 "movl %0,%%eax \n"
00170 "movl %%eax,%%cr3 \n"
00171 : : "d" ((uInt32 *)(_current->tss.cr3))
00172 );
00173
00174
00175 tmpFd = fopen(file,"r");
00176
00177
00178 if (tmpFd == 0x0) {
00179 kprintf("Exec Format Error: Binary File Not Executable.\n");
00180 fclose(tmpFd);
00181 return;
00182 }
00183 if (tmpFd->perms == 0x0) {
00184 kprintf("Exec Format Error: Binary File Not Executable.\n");
00185 fclose(tmpFd);
00186 return;
00187 }
00188
00189
00190 binaryHeader = (elfHeader *)kmalloc(sizeof(elfHeader));
00191
00192
00193
00194 fread(binaryHeader,sizeof(elfHeader),1,tmpFd);
00195
00196
00197
00198 if ((binaryHeader->eIdent[1] != 'E') && (binaryHeader->eIdent[2] != 'L') && (binaryHeader->eIdent[3] != 'F')) {
00199 kprintf("Exec Format Error: Binary File Not Executable.\n");
00200 kfree(binaryHeader);
00201 fclose(tmpFd);
00202 return;
00203 }
00204 else if (binaryHeader->eType != 2) {
00205 kprintf("Exec Format Error: Binary File Not Executable.\n");
00206 kfree(binaryHeader);
00207 fclose(tmpFd);
00208 return;
00209 }
00210 else if (binaryHeader->eEntry == 0x300000) {
00211 kprintf("Exec Format Error: Binary File Not Executable.\n");
00212 kfree(binaryHeader);
00213 fclose(tmpFd);
00214 return;
00215 }
00216
00217
00218 programHeader = (elfProgramHeader *)kmalloc(sizeof(elfProgramHeader)*binaryHeader->ePhnum);
00219 fseek(tmpFd,binaryHeader->ePhoff,0);
00220
00221
00222 fread(programHeader,(sizeof(elfProgramHeader)*binaryHeader->ePhnum),1,tmpFd);
00223
00224
00225
00226 for (i=0;i<binaryHeader->ePhnum;i++) {
00227 if (programHeader[i].phType == 1) {
00228
00229
00230
00231
00232 for (x = 0x0;x < (programHeader[i].phMemsz);x += 0x1000) {
00233
00234 if (vmm_remapPage(vmmFindFreePage(_current->id),((programHeader[i].phVaddr & 0xFFFFF000) + x),PAGE_DEFAULT) == 0x0)
00235 K_PANIC("Remap Page Failed");
00236
00237 memset((void *)((programHeader[i].phVaddr & 0xFFFFF000) + x),0x0,0x1000);
00238 }
00239 _current->oInfo.vmStart = 0x80000000;
00240 _current->td.vm_daddr = (char *)(programHeader[i].phVaddr & 0xFFFFF000);
00241
00242 fseek(tmpFd,programHeader[i].phOffset,0);
00243 fread((void *)programHeader[i].phVaddr,programHeader[i].phFilesz,1,tmpFd);
00244 if ((programHeader[i].phFlags & 0x2) != 0x2) {
00245 kprintf("pH: [0x%X]\n",programHeader[i].phMemsz);
00246 for (x = 0x0;x < (programHeader[i].phMemsz);x += 0x1000) {
00247 if ((vmm_setPageAttributes((programHeader[i].phVaddr & 0xFFFFF000) + x,PAGE_PRESENT | PAGE_USER)) != 0x0)
00248 kpanic("Error: vmm_setPageAttributes failed, File: %s, Line: %i\n",__FILE__,__LINE__);
00249 }
00250 }
00251 }
00252 }
00253
00254
00255 _current->oInfo.vmStart = 0x80000000;
00256 _current->td.vm_daddr = (char *)(programHeader[i].phVaddr & 0xFFFFF000);
00257
00258
00259 for (x = 1;x < 100;x++) {
00260 vmm_remapPage(vmmFindFreePage(_current->id),STACK_ADDR - (x * 0x1000),PAGE_DEFAULT | PAGE_STACK);
00261 }
00262
00263
00264 vmm_remapPage(vmmFindFreePage(_current->id),0x5BC000,KERNEL_PAGE_DEFAULT | PAGE_STACK);
00265 vmm_remapPage(vmmFindFreePage(_current->id),0x5BB000,KERNEL_PAGE_DEFAULT | PAGE_STACK);
00266
00267
00268 _current->tss.back_link = 0x0;
00269 _current->tss.esp0 = 0x5BC000;
00270 _current->tss.ss0 = 0x10;
00271 _current->tss.esp1 = 0x0;
00272 _current->tss.ss1 = 0x0;
00273 _current->tss.esp2 = 0x0;
00274 _current->tss.ss2 = 0x0;
00275 _current->tss.eip = (long)binaryHeader->eEntry;
00276 _current->tss.eflags = 0x206;
00277 _current->tss.esp = STACK_ADDR - 12;
00278 _current->tss.ebp = STACK_ADDR;
00279 _current->tss.esi = 0x0;
00280 _current->tss.edi = 0x0;
00281
00282
00283 _current->tss.es = 0x30+3;
00284 _current->tss.cs = 0x28+3;
00285 _current->tss.ss = 0x30+3;
00286 _current->tss.ds = 0x30+3;
00287 _current->tss.fs = 0x30+3;
00288 _current->tss.gs = 0x30+3;
00289
00290 _current->tss.ldt = 0x18;
00291 _current->tss.trace_bitmap = 0x0000;
00292 _current->tss.io_map = 0x8000;
00293
00294 sched_setStatus(_current->id,READY);
00295
00296 kfree(binaryHeader);
00297 kfree(programHeader);
00298 fclose(tmpFd);
00299
00300 tmp = (uInt32 *)_current->tss.esp0 - 5;
00301 tmp[0] = binaryHeader->eEntry;
00302 tmp[3] = STACK_ADDR - 12;
00303
00304 tmp = (uInt32 *)STACK_ADDR - 2;
00305
00306 if (_current->id > 4)
00307 kprintf("argv[0]: [%s]\n",argv[0]);
00308 kprintf("argv: [0x%X]\n",argv);
00309 tmp[0] = (u_int32_t)argv;
00310 tmp[1] = (u_int32_t)argv;
00311
00312
00313
00314 asm volatile(
00315 "movl %0,%%eax \n"
00316 "movl %%eax,%%cr3 \n"
00317 : : "d" ((uInt32 *)(kernelPageDirectory))
00318 );
00319
00320
00321 return;
00322 }
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333 void sysExec(char *file,int argc,char **argv) {
00334 int i = 0x0;
00335 int x = 0x0;
00336 uInt32 *tmp = 0x0;
00337 uInt32 ldAddr = 0x0;
00338 uInt32 seg_size = 0x0;
00339 uInt32 seg_addr = 0x0;
00340 char *interp = 0x0;
00341
00342 fileDescriptor *tmpFd = 0x0;
00343 elfHeader *binaryHeader = 0x0;
00344 elfProgramHeader *programHeader = 0x0;
00345 elfSectionHeader *sectionHeader = 0x0;
00346 elfDynamic *elfDynamicS = 0x0;
00347
00348 tmpFd = fopen(file,"r");
00349 _current->imageFd = tmpFd;
00350
00351 if (tmpFd == 0x0) {
00352 return;
00353 }
00354 if (tmpFd->perms == 0) {
00355 kprintf("Exec Format Error: Binary File Not Executable.\n");
00356 fclose(tmpFd);
00357 return;
00358 }
00359
00360
00361
00362 if ((binaryHeader = (elfHeader *)kmalloc(sizeof(elfHeader))) == 0x0)
00363 endTask(_current->id);
00364 fread(binaryHeader,sizeof(elfHeader),1,tmpFd);
00365
00366
00367
00368 if ((binaryHeader->eIdent[1] != 'E') && (binaryHeader->eIdent[2] != 'L') && (binaryHeader->eIdent[3] != 'F')) {
00369 kprintf("Exec Format Error: Binary File Not Executable.\n");
00370 kfree(binaryHeader);
00371 fclose(tmpFd);
00372
00373 return;
00374 }
00375 else if (binaryHeader->eType != 2) {
00376 kprintf("Exec Format Error: Binary File Not Executable.\n");
00377 kfree(binaryHeader);
00378 fclose(tmpFd);
00379 return;
00380 }
00381 else if (binaryHeader->eEntry == 0x300000) {
00382 kprintf("Exec Format Error: Binary File Not Executable.\n");
00383 kfree(binaryHeader);
00384 fclose(tmpFd);
00385 return;
00386 }
00387
00388
00389 if ((programHeader = (elfProgramHeader *)kmalloc(sizeof(elfProgramHeader)*binaryHeader->ePhnum)) == 0x0)
00390 endTask(_current->id);
00391
00392 assert(programHeader);
00393 fseek(tmpFd,binaryHeader->ePhoff,0);
00394 fread(programHeader,(sizeof(elfProgramHeader)*binaryHeader->ePhnum),1,tmpFd);
00395
00396 if ((sectionHeader = (elfSectionHeader *)kmalloc(sizeof(elfSectionHeader)*binaryHeader->eShnum)) == 0x0)
00397 endTask(_current->id);
00398
00399 assert(sectionHeader);
00400 fseek(tmpFd,binaryHeader->eShoff,0);
00401 fread(sectionHeader,sizeof(elfSectionHeader)*binaryHeader->eShnum,1,tmpFd);
00402
00403
00404 for (i=0;i<binaryHeader->ePhnum;i++) {
00405 switch (programHeader[i].phType) {
00406 case PT_LOAD:
00407 seg_addr = trunc_page(programHeader[i].phVaddr);
00408 seg_size = round_page(programHeader[i].phMemsz + programHeader[i].phVaddr - seg_addr);
00409
00410
00411
00412
00413
00414 for (x = 0x0;x < (programHeader[i].phMemsz);x += 0x1000) {
00415
00416 if (vmm_remapPage(vmmFindFreePage(_current->id),((programHeader[i].phVaddr & 0xFFFFF000) + x),PAGE_DEFAULT) == 0x0)
00417 K_PANIC("Error: Remap Page Failed");
00418 memset((void *)((programHeader[i].phVaddr & 0xFFFFF000) + x),0x0,0x1000);
00419 }
00420
00421
00422 fseek(tmpFd,programHeader[i].phOffset,0);
00423 fread((void *)programHeader[i].phVaddr,programHeader[i].phFilesz,1,tmpFd);
00424 if ((programHeader[i].phFlags & 0x2) != 0x2) {
00425 for (x = 0x0;x < (programHeader[i].phMemsz);x += 0x1000) {
00426 if ((vmm_setPageAttributes((programHeader[i].phVaddr & 0xFFFFF000) + x,PAGE_PRESENT | PAGE_USER)) != 0x0)
00427 kpanic("Error: vmm_setPageAttributes failed, File: %s,Line: %i\n",__FILE__,__LINE__);
00428 }
00429 }
00430 kprintf("setting daddr\n");
00431 if (binaryHeader->eEntry >= programHeader[i].phVaddr && binaryHeader->eEntry < (programHeader[i].phVaddr + programHeader[i].phMemsz)) {
00432
00433 }
00434 else {
00435 _current->td.vm_dsize = seg_size >> PAGE_SHIFT;
00436 _current->td.vm_daddr = (char *)seg_addr;
00437 }
00438
00439 _current->oInfo.vmStart = ((programHeader[i].phVaddr & 0xFFFFF000) + 0xA900000);
00440 break;
00441 case PT_DYNAMIC:
00442
00443 elfDynamicS = (elfDynamic *)programHeader[i].phVaddr;
00444 fseek(tmpFd,programHeader[i].phOffset,0);
00445 fread((void *)programHeader[i].phVaddr,programHeader[i].phFilesz,1,tmpFd);
00446 break;
00447 case PT_INTERP:
00448 interp = (char *)kmalloc(programHeader[i].phFilesz);
00449 fseek(tmpFd,programHeader[i].phOffset,0);
00450 fread((void *)interp,programHeader[i].phFilesz,1,tmpFd);
00451 kprintf("Interp: [%s]\n",interp);
00452 ldAddr = ldEnable();
00453 break;
00454 default:
00455 break;
00456 }
00457 }
00458
00459
00460 if (elfDynamicS != 0x0) {
00461 for (i=0;i<12;i++) {
00462 if (elfDynamicS[i].dynVal == 0x3) {
00463 tmp = (uInt32 *)elfDynamicS[i].dynPtr;
00464 if (tmp == 0x0)
00465 kpanic("tmp: NULL\n");
00466 tmp[2] = (uInt32)ldAddr;
00467 tmp[1] = (uInt32)tmpFd;
00468 break;
00469 }
00470 }
00471 }
00472 _current->td.vm_dsize = seg_size >> PAGE_SHIFT;
00473 _current->td.vm_daddr = (char *)seg_addr;
00474
00475 vmm_cleanVirtualSpace(_current->td.vm_daddr + (_current->td.vm_dsize << PAGE_SIZE));
00476
00477
00478 tmp = (uInt32 *)_current->tss.esp0 - 5;
00479 tmp[0] = binaryHeader->eEntry;
00480 tmp[3] = STACK_ADDR - 12;
00481
00482 tmp = (uInt32 *)STACK_ADDR - 2;
00483 kprintf("argv: [0x%X]\n",argv);
00484 tmp[0] = (u_int32_t)argv;
00485 tmp[1] = (u_int32_t)argv;
00486
00487
00488 kfree(binaryHeader);
00489 kfree(programHeader);
00490
00491 return;
00492 }
00493
00494
00495
00496