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,char *ap) {
00334 int i = 0x0;
00335 int x = 0x0;
00336 int argc = 0x0;
00337 uInt32 *tmp = 0x0;
00338 uInt32 ldAddr = 0x0;
00339 uInt32 seg_size = 0x0;
00340 uInt32 seg_addr = 0x0;
00341 char *interp = 0x0;
00342 char **argv = 0x0;
00343 char **argvNew = 0x0;
00344 char *args = 0x0;
00345
00346 fileDescriptor *tmpFd = 0x0;
00347 elfHeader *binaryHeader = 0x0;
00348 elfProgramHeader *programHeader = 0x0;
00349 elfSectionHeader *sectionHeader = 0x0;
00350 elfDynamic *elfDynamicS = 0x0;
00351 struct i386_frame *iFrame = 0x0;
00352
00353 tmpFd = fopen(file,"r");
00354 _current->imageFd = tmpFd;
00355
00356 if (tmpFd == 0x0) {
00357 return;
00358 }
00359 if (tmpFd->perms == 0) {
00360 kprintf("Exec Format Error: Binary File Not Executable.\n");
00361 fclose(tmpFd);
00362 return;
00363 }
00364
00365
00366
00367 if ((binaryHeader = (elfHeader *)kmalloc(sizeof(elfHeader))) == 0x0)
00368 endTask(_current->id);
00369 fread(binaryHeader,sizeof(elfHeader),1,tmpFd);
00370
00371
00372
00373 if ((binaryHeader->eIdent[1] != 'E') && (binaryHeader->eIdent[2] != 'L') && (binaryHeader->eIdent[3] != 'F')) {
00374 kprintf("Exec Format Error: Binary File Not Executable.\n");
00375 kfree(binaryHeader);
00376 fclose(tmpFd);
00377
00378 return;
00379 }
00380 else if (binaryHeader->eType != 2) {
00381 kprintf("Exec Format Error: Binary File Not Executable.\n");
00382 kfree(binaryHeader);
00383 fclose(tmpFd);
00384 return;
00385 }
00386 else if (binaryHeader->eEntry == 0x300000) {
00387 kprintf("Exec Format Error: Binary File Not Executable.\n");
00388 kfree(binaryHeader);
00389 fclose(tmpFd);
00390 return;
00391 }
00392
00393
00394 if ((programHeader = (elfProgramHeader *)kmalloc(sizeof(elfProgramHeader)*binaryHeader->ePhnum)) == 0x0)
00395 endTask(_current->id);
00396
00397 assert(programHeader);
00398 fseek(tmpFd,binaryHeader->ePhoff,0);
00399 fread(programHeader,(sizeof(elfProgramHeader)*binaryHeader->ePhnum),1,tmpFd);
00400
00401 if ((sectionHeader = (elfSectionHeader *)kmalloc(sizeof(elfSectionHeader)*binaryHeader->eShnum)) == 0x0)
00402 endTask(_current->id);
00403
00404 assert(sectionHeader);
00405 fseek(tmpFd,binaryHeader->eShoff,0);
00406 fread(sectionHeader,sizeof(elfSectionHeader)*binaryHeader->eShnum,1,tmpFd);
00407
00408
00409 for (i=0;i<binaryHeader->ePhnum;i++) {
00410 switch (programHeader[i].phType) {
00411 case PT_LOAD:
00412 seg_addr = trunc_page(programHeader[i].phVaddr);
00413 seg_size = round_page(programHeader[i].phMemsz + programHeader[i].phVaddr - seg_addr);
00414
00415
00416
00417
00418
00419 for (x = 0x0;x < (programHeader[i].phMemsz);x += 0x1000) {
00420
00421 if (vmm_remapPage(vmmFindFreePage(_current->id),((programHeader[i].phVaddr & 0xFFFFF000) + x),PAGE_DEFAULT) == 0x0)
00422 K_PANIC("Error: Remap Page Failed");
00423 memset((void *)((programHeader[i].phVaddr & 0xFFFFF000) + x),0x0,0x1000);
00424 }
00425
00426
00427 fseek(tmpFd,programHeader[i].phOffset,0);
00428 fread((void *)programHeader[i].phVaddr,programHeader[i].phFilesz,1,tmpFd);
00429 if ((programHeader[i].phFlags & 0x2) != 0x2) {
00430 for (x = 0x0;x < (programHeader[i].phMemsz);x += 0x1000) {
00431 if ((vmm_setPageAttributes((programHeader[i].phVaddr & 0xFFFFF000) + x,PAGE_PRESENT | PAGE_USER)) != 0x0)
00432 kpanic("Error: vmm_setPageAttributes failed, File: %s,Line: %i\n",__FILE__,__LINE__);
00433 }
00434 }
00435 kprintf("setting daddr\n");
00436 if (binaryHeader->eEntry >= programHeader[i].phVaddr && binaryHeader->eEntry < (programHeader[i].phVaddr + programHeader[i].phMemsz)) {
00437
00438 }
00439 else {
00440 _current->td.vm_dsize = seg_size >> PAGE_SHIFT;
00441 _current->td.vm_daddr = (char *)seg_addr;
00442 }
00443
00444 _current->oInfo.vmStart = ((programHeader[i].phVaddr & 0xFFFFF000) + 0xA900000);
00445 break;
00446 case PT_DYNAMIC:
00447
00448 elfDynamicS = (elfDynamic *)programHeader[i].phVaddr;
00449 fseek(tmpFd,programHeader[i].phOffset,0);
00450 fread((void *)programHeader[i].phVaddr,programHeader[i].phFilesz,1,tmpFd);
00451 break;
00452 case PT_INTERP:
00453 interp = (char *)kmalloc(programHeader[i].phFilesz);
00454 fseek(tmpFd,programHeader[i].phOffset,0);
00455 fread((void *)interp,programHeader[i].phFilesz,1,tmpFd);
00456 kprintf("Interp: [%s]\n",interp);
00457 ldAddr = ldEnable();
00458 break;
00459 default:
00460 break;
00461 }
00462 }
00463
00464
00465 if (elfDynamicS != 0x0) {
00466 for (i=0;i<12;i++) {
00467 if (elfDynamicS[i].dynVal == 0x3) {
00468 tmp = (uInt32 *)elfDynamicS[i].dynPtr;
00469 if (tmp == 0x0)
00470 kpanic("tmp: NULL\n");
00471 tmp[2] = (uInt32)ldAddr;
00472 tmp[1] = (uInt32)tmpFd;
00473 break;
00474 }
00475
00476
00477
00478
00479
00480 }
00481 }
00482 _current->td.vm_dsize = seg_size >> PAGE_SHIFT;
00483 _current->td.vm_daddr = (char *)seg_addr;
00484
00485 argv = ap;
00486
00487 if (argv[1] != 0x0) {
00488 argc = argv[0];
00489 args = (char *)vmmGetFreeVirtualPage(_current->id,1,VM_TASK);
00490 memset(args,0x0,0x1000);
00491 x = 0x0;
00492 argvNew = (char **)kmalloc(sizeof(char *) * argc);
00493 for (i = 0x0;i < argc;i++) {
00494 strcpy(args + x,argv[i + 1]);
00495 argvNew[i] = args + x;
00496 x += strlen(argv[i + 1]) + 1;
00497
00498
00499 }
00500 argv = argvNew;
00501 }
00502
00504 vmm_cleanVirtualSpace(_current->td.vm_daddr + (_current->td.vm_dsize << PAGE_SIZE));
00505
00506
00508 iFrame = _current->tss.esp0 - sizeof(struct i386_frame);
00509 iFrame->ebp = STACK_ADDR;
00510 iFrame->eip = binaryHeader->eEntry;
00511 iFrame->user_esp = STACK_ADDR - 12;
00512
00513
00514
00515 iFrame->user_esp = ((u_int32_t)STACK_ADDR) - (sizeof(u_int32_t) * (x + 1));
00516 tmp = iFrame->user_esp;
00517
00519 tmp[0] = argc;
00520 for (i = 0;i < argc;i++) {
00521 tmp[i + 1] = argv[i];
00522 }
00523
00524
00525
00526
00527
00528
00529
00530 kfree(argvNew);
00531
00532 kfree(binaryHeader);
00533 kfree(programHeader);
00534
00535 return;
00536 }
00537
00538
00539
00540