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