⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 kernelmultitasker.c

📁 上一个上传的有问题,这个是好的。visopsys包括系统内核和GUI的全部SOURCE code ,还包括一些基本的docs文档。里面src子目录对应所有SOURCE code.对于想研究操作系统的朋
💻 C
📖 第 1 页 / 共 5 页
字号:
	      if (status < 0)	        {	          // Crap.  An error updating the descriptor.	          return (status);	        }	      // Now, fill the TSS (Task State Segment) for the process.  	      // destroy old TSS!	      kernelFree(Process->taskStateSegment);	      // set the new one	      Process->taskStateSegment = newTSS;	      Process->TSSsize = newTSSsize;	                 Process->max_io_port = portNum; 	      Process->IOMap = (unsigned char *) (&(((kernelTSS *)(Process->taskStateSegment))->IOMap));  	      // All done! Re-enable ints	      kernelProcessorRestoreInts(interrupts);	     	      // for Debug	      //kernelError(kernel_error,"TSS is growing ... now it's %d bytes",newTSSsize);    }    if (perm == PORT_VAL_BIT_TRUE)	ALLOW_PORT_IO(portNum,Process->IOMap)    else {	if (perm == PORT_VAL_BIT_FALSE) 	    NOT_ALLOW_PORT_IO(portNum,Process->IOMap) 	else	    return (status = ERR_BUG);    }	            // for Debug    p = (unsigned char *)(&((kernelTSS *)(Process->taskStateSegment))->IOMap);    a = GET_PORT_BIT(portNum,Process->IOMap);    b = GET_PORT_BIT(portNum, p);    kernelError(kernel_error,"Port Bit: %d , %d",a,b);        return (status = 0);	}//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////  Below here, the functions are exported for external use////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////int kernelMultitaskerInitialize(void){  // This function intializes the kernel's multitasker.  int status = 0;  unsigned cr0 = 0;  int count;    // Make sure multitasking is NOT enabled already  if (multitaskingEnabled)    return (status = ERR_ALREADY);  // Now we must initialize the process queue  for (count = 0; count < MAX_PROCESSES; count ++)    processQueue[count] = NULL;  numQueued = 0;  // Initialize the CPU for floating point operation.  We set  // CR0[EM]=0 (no emulation)  // CR0[MP]=1 (math present)  // CR0[NE]=1 (floating point errors cause exceptions)  kernelProcessorGetCR0(cr0);  cr0 = ((cr0 & ~0x04UL) | 0x22);  kernelProcessorSetCR0(cr0);  // We need to create the kernel's own process.    status = createKernelProcess();  // Make sure it was successful  if (status < 0)    return (status);  // Now start the scheduler  status = schedulerInitialize();  if (status < 0)    // The scheduler couldn't start    return (status);  // Create an "idle" thread to consume all unused cycles  status = spawnIdleThread();  // Make sure it was successful  if (status < 0)    return (status);  // Set up any specific exception handlers.  exceptionVector[EXCEPTION_DEVNOTAVAIL].handler = fpuExceptionHandler;  // Log a boot message  kernelLog("Multitasking started");  // Return success  return (status = 0);}int kernelMultitaskerShutdown(int nice){  // This function will shut down the multitasker and halt the scheduler,   // returning exclusive control to the kernel process.  If the nice  // argument is non-zero, this function will do a nice orderly shutdown,  // killing all the running processes gracefully.  If it is zero, the  // resources allocated to the processes will never be freed, and the  // multitasker will just stop.  Returns 0 on success, negative otherwise.   int status = 0;  // Make sure multitasking has been enabled  if (!multitaskingEnabled)    // We can't yield if we're not multitasking yet    return (status = ERR_NOTINITIALIZED);  // If we are doing a "nice" shutdown, we will kill all the running  // processes (except the kernel and scheduler) gracefully.  if (nice)    kernelMultitaskerKillAll();  // Set the schedulerStop flag to stop the scheduler  schedulerStop = 1;  // Yield control back to the scheduler, so that it can stop  kernelMultitaskerYield();  // Make note that the multitasker has been disabled  multitaskingEnabled = 0;  // Deallocate the stack used by the scheduler  kernelMemoryReleaseSystem(schedulerProc->userStack);  // Print a message  kernelLog("Multitasking stopped");    return (status = 0);}void kernelExceptionHandler(int exceptionNum, unsigned address){  // This code sleeps until woken up by an exception.  char message[256];  char *symbolName = NULL;  int count;  extern kernelSymbol *kernelSymbols;  extern int kernelNumberSymbols;  // We got an exception.    // If there's a handler for this exception type, call it  if (exceptionVector[exceptionNum].handler != NULL)    {      if (exceptionVector[exceptionNum].handler() >= 0)	// The exception was handled.  Return to the task.	return;    }  kernelCurrentProcess->state = proc_stopped;  // If the fault occurred while we were processing an interrupt,  // we should tell the PIC that the interrupt service routine is  // finished.  It's not really fair to kill a process because an  // interrupt handler is screwy, but that's what we have to do for  // the time being.  if (kernelProcessingInterrupt)    kernelPicEndOfInterrupt(0xFF);  if (kernelCurrentProcess == NULL)    // We have to make an error here.  We can't return to the program    // that caused the exception, and we can't tell the multitasker    // to kill it.  We'd better make a kernel panic.    kernelPanic("Exception handler unable to determine current process");  else if (!multitaskingEnabled || (kernelCurrentProcess == kernelProc))    sprintf(message, "The kernel has experienced %s %s exception",	    exceptionVector[exceptionNum].a,	    exceptionVector[exceptionNum].name);  else    sprintf(message, "Process \"%s\" caused %s %s exception",	    kernelCurrentProcess->processName, exceptionVector[exceptionNum].a,	    exceptionVector[exceptionNum].name);  if (multitaskingEnabled)    {      if (address >= KERNEL_VIRTUAL_ADDRESS)	{	  if (kernelSymbols)	    {	      // Find roughly the kernel function where the exception	      // happened	      for (count = 0; count < kernelNumberSymbols; count ++)		{		  if ((address >= kernelSymbols[count].address) &&		      (address <  kernelSymbols[count + 1].address))		    {		      symbolName = kernelSymbols[count].symbol;		      break;		    }		}	    }	  if (symbolName)	    sprintf((message + strlen(message)), " in function %s (%08x)",		    symbolName, address);	  else	    sprintf((message + strlen(message)), " at kernel address %08x",		    address);	}      else	sprintf((message + strlen(message)), " at application address %08x",		address);    }  if (kernelProcessingInterrupt)    sprintf((message + strlen(message)), " while processing interrupt %d",	    kernelPicGetActive());  if (!multitaskingEnabled || (kernelCurrentProcess == kernelProc))    // If it's the kernel, we're finished    kernelPanic(message);  else    {      kernelError(kernel_error, message);      if (kernelGraphicsAreEnabled())	kernelErrorDialog("Application Exception", message);    }  /*  // If the process was in kernel code do a stack trace  if (!kernelProcessingInterrupt && (address >= KERNEL_VIRTUAL_ADDRESS))    kernelStackTrace((kernelCurrentProcess->userStack +		      ((void *) kernelCurrentProcess->taskStateSegment.ESP -		       kernelCurrentProcess->userStack)),		     (kernelCurrentProcess->userStack +		      kernelCurrentProcess->userStackSize - sizeof(void *)));  */  // The scheduler may now dismantle the process  kernelCurrentProcess->state = proc_finished;  kernelProcessingInterrupt = 0;  // Yield control.  kernelMultitaskerYield();}void kernelMultitaskerDumpProcessList(void){  // This routine is used to dump an internal listing of the current  // process to the output.  kernelTextOutputStream *currentOutput = NULL;  kernelProcess *tmpProcess = NULL;  char buffer[1024];  int count;  // Make sure multitasking has been enabled  if (!multitaskingEnabled)    return;  // Get the current output stream  currentOutput = kernelTextGetCurrentOutput();  if (numQueued > 0)    {      kernelTextStreamPrintLine(currentOutput, "Process list:");      for (count = 0; count < numQueued; count ++)	{	  tmpProcess = processQueue[count];	  	  sprintf(buffer, "\"%s\"  PID=%d UID=%d priority=%d "		  "priv=%d parent=%d\n        %d%% CPU State=",		  (char *) tmpProcess->processName,		  tmpProcess->processId, tmpProcess->userId,		  tmpProcess->priority, tmpProcess->privilege,		  tmpProcess->parentProcessId, tmpProcess->cpuPercent);	  // Get the state	  switch(tmpProcess->state)	    {	    case proc_running:	      strcat(buffer, "running");	      break;	    case proc_ready:	      strcat(buffer, "ready");	      break;	    case proc_waiting:	      strcat(buffer, "waiting");	      break;	    case proc_sleeping:	      strcat(buffer, "sleeping");	      break;	    case proc_stopped:	      strcat(buffer, "stopped");	      break;	    case proc_finished:	      strcat(buffer, "finished");	      break;	    case proc_zombie:	      strcat(buffer, "zombie");	      break;	    default:	      strcat(buffer, "unknown");	      break;	    }	  kernelTextStreamPrintLine(currentOutput, buffer);	}    }  else    // This doesn't seem at all likely.    kernelTextStreamPrintLine(currentOutput, "No processes remaining");  kernelTextStreamNewline(currentOutput);  return;}int kernelMultitaskerCreateProcess(const char *name, int privilege,				   processImage *execImage){  // This function is called to set up an (initially) single-threaded  // process in the multitasker.  This is the routine used by external  // sources -- the loader for example -- to define new processes.  This   // new process thread we're creating will have its state set to "stopped"   // after this call.  The caller should use the   // kernelMultitaskerChangeThreadState routine to start the new thread.    // This function returns the processId of the new process on success,   // negative otherwise.  int status = 0;  int processId = 0;  kernelProcess *newProcess = NULL;  // next 3 lines added by Davide Airaghi  int orig_privilege = 0;  orig_privilege = privilege;  privilege &= ~ PRIVILEGE_KERNEL;    // Make sure multitasking has been enabled  if (!multitaskingEnabled)    return (status = ERR_NOTINITIALIZED);  // Make sure the parameters are valid  if ((name == NULL) || (execImage == NULL))    return (status = ERR_NULLPARAMETER);     // Make sure that an unprivileged process is not trying to create a  // privileged one  if ((kernelCurrentProcess->privilege == PRIVILEGE_USER) &&      (privilege == PRIVILEGE_SUPERVISOR))    {      kernelError(kernel_error, "An unprivileged process cannot create a "		  "privileged process");      return (status == ERR_PERMISSION);    }  // added by Davide Airaghi  privilege = orig_privilege;    // Create the new process  processId = createNewProcess(name, PRIORITY_DEFAULT, privilege, execImage,			       1); // create page directory  // Get the pointer to the new process from its process Id  newProcess = getProcessById(processId);  if (newProcess == NULL)    // We couldn't get access to the new process    return (status = ERR_NOCREATE);  // Create the process' environment  status =    kernelEnvironmentCreate(newProcess->processId, (variableList *)			    &(newProcess->environment), (variableList *)			    &(kernelCurrentProcess->environment));  if (status < 0)    // Couldn't create an environment structure for this process    return (status);  // Don't assign input or output streams to this process.  There are  // multiple possibilities here, and the caller will have to either block  // (which takes care of such things) or sort it out for themselves.  // Return whatever was returned by the previous call  return (processId);}int kernelMultitaskerSpawn(void *sta

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -