diff --git a/src/sys/kernel/exec.c b/src/sys/kernel/exec.c index fff6ccf..254ec38 100644 --- a/src/sys/kernel/exec.c +++ b/src/sys/kernel/exec.c @@ -1,4 +1,4 @@ -/* +/***************************************************************************************** Copyright (c) 2002-2004 The UbixOS Project All rights reserved. @@ -51,15 +51,13 @@ *****************************************************************************************/ uInt32 execThread(void (* tproc)(void),uInt32 stack,char *arg) { kTask_t * newProcess = 0x0; + /* Find A New Thread */ newProcess = schedNewTask(); - - assert(newProcess); - + assert(newProcess); if (stack < 0x100000) kpanic("exec: stack not in valid area: [0x%X]\n",stack); /* Set All The Correct Thread Attributes */ - newProcess->tss.back_link = 0x0; newProcess->tss.esp0 = 0x0; newProcess->tss.ss0 = 0x0; @@ -74,6 +72,7 @@ newProcess->tss.ebp = stack; newProcess->tss.esi = 0x0; newProcess->tss.edi = 0x0; + newProcess->tss.es = 0x10; newProcess->tss.cs = 0x08; newProcess->tss.ss = 0x10; @@ -81,14 +80,14 @@ newProcess->tss.fs = 0x10; newProcess->tss.gs = 0x10; newProcess->tss.ldt = 0x18; + newProcess->tss.trace_bitmap = 0x0000; newProcess->tss.io_map = 0x8000; newProcess->oInfo.vmStart = 0x6400000; + newProcess->imageFd = 0x0; /* Set up default stack for thread here filled with arg list 3 times */ - - asm volatile( "pusha \n" "movl %%esp,%%ecx \n" @@ -105,17 +104,17 @@ : "b" (arg),"m" (newProcess->tss.esp) ); - /* Put new thread into the NEW state */ - sched_setStatus2(newProcess,NEW); + /* Put new thread into the READY state */ + sched_setStatus(newProcess->id,READY); /* Return with the new process ID */ - return(newProcess->id); - } + return((uInt32)newProcess); + } /***************************************************************************************** Function: void execFile(char *file); - Description: This Function Executes A File Into A New VM Space With Out + Description: This Function Executes A Kile Into A New VM Space With Out Having To Fork Notes: @@ -144,8 +143,8 @@ _current->uid = 0x0; _current->term = tty_find(console); if (_current->term == 0x0) - kprintf("Error: invalid console\n"); - + kpanic("Error: invalid console\n"); + /* Set tty ownership */ _current->term->owner = _current->id; @@ -164,48 +163,45 @@ /* If We Dont Find the File Return */ if (tmpFd == 0x0) { - kprintf("Exec Format Error: Binary File Not Executable.\n"); + // kprintf("Exec Format Error: Binary File Not Executable.\n"); fclose(tmpFd); return; } if (tmpFd->perms == 0x0) { - kprintf("Exec Format Error: Binary File Not Executable.\n"); + //kprintf("Exec Format Error: Binary File Not Executable.\n"); fclose(tmpFd); return; } /* Load ELF Header */ binaryHeader = (elfHeader *)kmalloc(sizeof(elfHeader)); - assert(binaryHeader); - //kprintf(">a:%i:0x%X:0x%X<",sizeof(elfHeader),binaryHeader,tmpFd); fread(binaryHeader,sizeof(elfHeader),1,tmpFd); - + //kprintf(">b<"); /* Check If App Is A Real Application */ if ((binaryHeader->eIdent[1] != 'E') && (binaryHeader->eIdent[2] != 'L') && (binaryHeader->eIdent[3] != 'F')) { - kprintf("Exec Format Error: Binary File Not Executable.\n"); + //kprintf("Exec Format Error: Binary File Not Executable.\n"); kfree(binaryHeader); fclose(tmpFd); return; } else if (binaryHeader->eType != 2) { - kprintf("Exec Format Error: Binary File Not Executable.\n"); + //kprintf("Exec Format Error: Binary File Not Executable.\n"); kfree(binaryHeader); fclose(tmpFd); return; } else if (binaryHeader->eEntry == 0x300000) { - kprintf("Exec Format Error: Binary File Not Executable.\n"); + //kprintf("Exec Format Error: Binary File Not Executable.\n"); kfree(binaryHeader); fclose(tmpFd); return; } + /* Load The Program Header(s) */ programHeader = (elfProgramHeader *)kmalloc(sizeof(elfProgramHeader)*binaryHeader->ePhnum); - assert(programHeader); fseek(tmpFd,binaryHeader->ePhoff,0); - //kprintf(">c:%i:0x%X:0x%X<",sizeof(elfProgramHeader)*binaryHeader->ePhnum,programHeader,tmpFd); fread(programHeader,(sizeof(elfProgramHeader)*binaryHeader->ePhnum),1,tmpFd); //kprintf(">d<"); @@ -301,7 +297,6 @@ *****************************************************************************************/ void sysExec(char *file,int argc,char **argv) { - int i = 0x0; int x = 0x0; uInt32 *tmp = 0x0; @@ -313,19 +308,15 @@ elfSectionHeader *sectionHeader = 0x0; elfDynamic *elfDynamicS = 0x0; - - _current = schedNewTask(); - tmpFd = fopen(file,"r"); _current->imageFd = tmpFd; - _current->term = tty_find(0); /* If We Dont Find the File Return */ if (tmpFd == 0x0) { kprintf("Couldn't open file %s\n",file); return; } if (tmpFd->perms == 0) { - kprintf("Exec Format Error: Binary File Not Executable.\n"); + //kprintf("Exec Format Error: Binary File Not Executable.\n"); fclose(tmpFd); return; } @@ -334,25 +325,26 @@ if ((binaryHeader = (elfHeader *)kmalloc(sizeof(elfHeader))) == 0x0) endTask(_current->id); - fread(binaryHeader,sizeof(elfHeader),1,tmpFd); - /* Set sectionHeader To Point To Loaded Binary To We Can Gather Info */ + //kprintf("A"); + fread(binaryHeader,sizeof(elfHeader),1,tmpFd); + //kprintf("B"); + /* Set sectionHeader To Point To Loaded Binary To We Can Gather Info */ /* Check If App Is A Real Application */ if ((binaryHeader->eIdent[1] != 'E') && (binaryHeader->eIdent[2] != 'L') && (binaryHeader->eIdent[3] != 'F')) { - kprintf("Exec Format Error: Binary File Not Executable.\n"); + //kprintf("Exec Format Error: Binary File Not Executable.\n"); kfree(binaryHeader); fclose(tmpFd); - return; } else if (binaryHeader->eType != 2) { - kprintf("Exec Format Error: Binary File Not Executable.\n"); + //kprintf("Exec Format Error: Binary File Not Executable.\n"); kfree(binaryHeader); fclose(tmpFd); return; } else if (binaryHeader->eEntry == 0x300000) { - kprintf("Exec Format Error: Binary File Not Executable.\n"); + //kprintf("Exec Format Error: Binary File Not Executable.\n"); kfree(binaryHeader); fclose(tmpFd); return; @@ -360,20 +352,15 @@ /* Load The Program Header(s) */ if ((programHeader = (elfProgramHeader *)kmalloc(sizeof(elfProgramHeader)*binaryHeader->ePhnum)) == 0x0) - { - endTask2(_current); - kpanic("fuck"); - } + endTask(_current->id); assert(programHeader); fseek(tmpFd,binaryHeader->ePhoff,0); fread(programHeader,(sizeof(elfProgramHeader)*binaryHeader->ePhnum),1,tmpFd); if ((sectionHeader = (elfSectionHeader *)kmalloc(sizeof(elfSectionHeader)*binaryHeader->eShnum)) == 0x0) - { - endTask2(_current); - kpanic("fuck2"); - } + endTask(_current->id); + assert(sectionHeader); fseek(tmpFd,binaryHeader->eShoff,0); fread(sectionHeader,sizeof(elfSectionHeader)*binaryHeader->eShnum,1,tmpFd); @@ -433,8 +420,6 @@ tmp = (uInt32 *)0x5DD000 - 2; tmp[0] = argc; tmp[1] = (uInt32)argv; - - sched_setStatus2(_current,NEW); /* Now That We Relocated The Binary We Can Unmap And Free Header Info */ kfree(binaryHeader); diff --git a/src/sys/kernel/sched.c b/src/sys/kernel/sched.c index 4e6759e..2a7c050 100644 --- a/src/sys/kernel/sched.c +++ b/src/sys/kernel/sched.c @@ -1,6 +1,36 @@ +/***************************************************************************************** + Copyright (c) 2002-2004 The UbixOS Project + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are + permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this list of + conditions, the following disclaimer and the list of authors. Redistributions in binary + form must reproduce the above copyright notice, this list of conditions, the following + disclaimer and the list of authors in the documentation and/or other materials provided + with the distribution. Neither the name of the UbixOS Project nor the names of its + contributors may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + $Id$ + +*****************************************************************************************/ + +#include #include #include -#include +#include #include #include #include @@ -11,63 +41,17 @@ #include #include #include + #include - -static kTask_t *taskList = NULL; +static kTask_t *taskList = 0x0; +static kTask_t *delList = 0x0; static uInt32 nextID = -1; -kTask_t *_current = NULL; -kTask_t *_usedMath = NULL; +kTask_t *_current = 0x0; +kTask_t *_usedMath = 0x0; static spinLock_t schedulerSpinLock = SPIN_LOCK_INITIALIZER; -static spinLock_t nextIDSpinLock = SPIN_LOCK_INITIALIZER; - -void LoadTaskState(uInt16 selector) -{ - //asm ("ltr %0": : "m" (selector)); - return; -} - -uInt16 StoreTaskState() -{ - uInt16 selector = 0x0; - //asm volatile("str %0": : "r" (selector)); - return selector; -} - -void Switch(uInt16 selector) -{ - asm ("lcall %0": : "m" (selector)); -} - -uInt16 kernel = 1; - -void SendTaskToProcessor(kTask_t *task, kProcessor *cpu) -{ - uInt32 memAddr = 0x0; - _current = task; - - memAddr = (uInt32)&(task->tss); - ubixGDT[4].descriptor.baseLow = (memAddr & 0xFFFF); - ubixGDT[4].descriptor.baseMed = ((memAddr >> 16) & 0xFF); - ubixGDT[4].descriptor.baseHigh = (memAddr >> 24); - ubixGDT[4].descriptor.access = '\x89'; - - /* enable interrupts, particularly the timer interrupt */ - //irqEnable(0x0); - - //kernel = StoreTaskState(); - //LoadTaskState(kernel); - //Switch(kernel); - asm("ljmp $0x20,$0\n"); - kprintf("WOOT!!\n"); - while (1); - - /* no interrupts can occur at the dispatch level */ - irqDisable(0x0); - return; -} /************************************************************************ @@ -79,141 +63,155 @@ 02/20/2004 - Approved for quality -08/07/2005 - begun rewrite as non-reentrant (Stephen A. Hodges) - ************************************************************************/ -int sched_init() -{ - taskList = (kTask_t *)kmalloc(sizeof(kTask_t)); - if(taskList == 0x0) - kpanic("Unable to create task list"); +int sched_init() { + taskList = (kTask_t *)kmalloc(sizeof(kTask_t)); + if(taskList == 0x0) + kpanic("Unable to create task list"); - taskList->id = nextID++; - //_current = NULL; - taskList->first = NULL; - taskList->last = NULL; - taskList->next = NULL; - taskList->prev = NULL; - /* Print out information on scheduler */ - kprintf("sched0 - Address: [0x%X]\n", taskList); + taskList->id = nextID++; + + /* Print out information on scheduler */ + kprintf("sched0 - Address: [0x%X]\n", taskList); - /* Return so we know everything went well */ - return(0x0); -} + /* Return so we know everything went well */ + return(0x0); + } -void sched() -{ - kTask_t *tmpTask = NULL; - kTask_t *delTask = NULL; - kProcessor *cpu = NULL; +void sched(){ + uInt32 memAddr = 0x0; + kTask_t *tmpTask = 0x0; + kTask_t *delTask = 0x0; + + if (!spinTryLock(&schedulerSpinLock)) + return; + + tmpTask = _current->next; + //outportByte(0xE9,_current->id + '0'); + schedStart: - /* no interrupts can occur at the dispatch level */ - irqDisable(0x0); + /* Yield the next task from the current prio queue */ + for (;tmpTask != 0x0; tmpTask = tmpTask->next) { + if (tmpTask->state > 0x0) { + _current = tmpTask; + if (_current->state == FORK) + _current->state = READY; + break; + } + else if (tmpTask->state == DEAD) + { + delTask = tmpTask; + tmpTask = tmpTask->next; + sched_deleteTask(delTask->id); + sched_addDelTask(delTask); + goto schedStart; + } + } - /* block reentrant schedule calls (there should be none anyways) */ - spinLock(&schedulerSpinLock); - - while(1) - { - - /* traverse the task queue */ - for (tmpTask = taskList->first ;tmpTask != NULL ; tmpTask = tmpTask->next) + /* Finished all the tasks, restarting the list */ + if (0x0 == tmpTask) { + tmpTask = taskList; + goto schedStart; + } + + + if (_current->state > 0x0) { + if (_current->oInfo.v86Task == 0x1) + irqDisable(0x0); + asm("cli"); + memAddr = (uInt32)&(_current->tss); + ubixGDT[4].descriptor.baseLow = (memAddr & 0xFFFF); + ubixGDT[4].descriptor.baseMed = ((memAddr >> 16) & 0xFF); + ubixGDT[4].descriptor.baseHigh = (memAddr >> 24); + ubixGDT[4].descriptor.access = '\x89'; + spinUnlock(&schedulerSpinLock); + asm("sti"); + asm("ljmp $0x20,$0\n"); + } + else { - switch(tmpTask->state) - { - case READY: - tmpTask->state = RUNNING; - kprintf("sending task to CPU\n"); - SendTaskToProcessor(tmpTask, cpu); - tmpTask->state = WAIT; - break; - case WAIT: - /* TODO: Sort priority list */ - tmpTask->state = READY; - break; - case FORK: - tmpTask->state = NEW; - break; - case NEW: - /* TODO: Add to wait list */ - tmpTask->state = WAIT; - break; - case RUNNING: - break; - case IDLE: - SendTaskToProcessor(tmpTask, cpu); - break; - case DEAD: - delTask = tmpTask; - - if (delTask->prev != 0x0) - delTask->prev->next = delTask->next; - if (tmpTask->next != 0x0) - delTask->next->prev = delTask->prev; - if (taskList == delTask) - taskList = delTask->next; - vmmFreeProcessPages(delTask->id); - if (delTask->imageFd != 0x0) - fclose(delTask->imageFd); - kfree(delTask); - break; - default: - kpanic("Unknown task state [%d] for task [%d]!\n", tmpTask->state, tmpTask->id); - break; - } + spinUnlock(&schedulerSpinLock); } - - /* finished all tasks */ - } - - return; + + return; } -kTask_t *schedNewTask() -{ + +kTask_t *schedNewTask() { kTask_t *tmpTask = (kTask_t *)kmalloc(sizeof(kTask_t)); - - if (tmpTask == NULL) - { - kprintf("Error: schedNewTask() - kmalloc failed trying to initialize a new task struct\n"); - return NULL; - } - - if(taskList->first == NULL) - { - taskList->first = tmpTask; - taskList->last = tmpTask; - } + if (tmpTask == 0x0) + kpanic("Error: schedNewTask() - kmalloc failed trying to initialize a new task struct\n"); memset(tmpTask,0x0,sizeof(kTask_t)); /* Filling in tasks attrs */ tmpTask->usedMath = 0x0; tmpTask->state = NEW; + spinLock(&schedulerSpinLock); tmpTask->id = nextID++; - taskList->last->next = tmpTask; - tmpTask->next = NULL; - tmpTask->prev = taskList->last; - taskList->last = tmpTask; + tmpTask->next = taskList; + tmpTask->prev = 0x0; + taskList->prev = tmpTask; + taskList = tmpTask; + + spinUnlock(&schedulerSpinLock); return(tmpTask); } +int sched_deleteTask(pidType id) { + kTask_t *tmpTask = 0x0; + + /* Checking each task from the prio queue */ + for (tmpTask = taskList; tmpTask != 0x0; tmpTask = tmpTask->next) { + if (tmpTask->id == id) { + if (tmpTask->prev != 0x0) + tmpTask->prev->next = tmpTask->next; + if (tmpTask->next != 0x0) + tmpTask->next->prev = tmpTask->prev; + if (taskList == tmpTask) + taskList = tmpTask->next; + + return(0x0); + } + } + return(0x1); + } + +int sched_addDelTask(kTask_t *tmpTask) { + tmpTask->next = delList; + tmpTask->prev = 0x0; + if (delList != 0x0) + delList->prev = tmpTask; + delList = tmpTask; + return(0x0); + } + +kTask_t *sched_getDelTask() { + kTask_t *tmpTask = 0x0; + + if (delList == 0x0) + return(0x0); + + tmpTask = delList; + delList = delList->next; + return(tmpTask); + } + + kTask_t * schedFindTask(uInt32 id) { kTask_t *tmpTask = 0x0; - spinLock(&schedulerSpinLock); for (tmpTask = taskList; tmpTask; tmpTask = tmpTask->next) { if (tmpTask->id == id) return(tmpTask); } - spinUnlock(&schedulerSpinLock); return(0x0); } @@ -230,13 +228,37 @@ 02/20/2004 - Approved for quality ************************************************************************/ - void -sched_yield() -{ - kpanic("sched_yield() is obsolete!\n"); +schedEndTask(pidType pid) { + endTask(_current->id); + sched_yield(); } +/************************************************************************ + +Function: int schedEndTask() + +Description: This function will yield a task + +Notes: + +02/20/2004 - Approved for quality + +************************************************************************/ + +void +sched_yield() { + sched(); + } + +/* +asm( + ".globl sched_yield \n" + "sched_yield: \n" + " cli \n" + " call sched \n" + ); +*/ /************************************************************************ @@ -247,8 +269,7 @@ Notes: ************************************************************************/ -int sched_setStatus(pidType pid,tState state) -{ +int sched_setStatus(pidType pid,tState state) { kTask_t *tmpTask = schedFindTask(pid); if (tmpTask == 0x0) return(0x1); @@ -256,15 +277,6 @@ return(0x0); } -int sched_setStatus2(kTask_t *task, tState state) -{ - - if(task == 0x0) - return 0x1; - task->state = state; - return 0x0; -} - /*** END ***/