void freeFrame(MEM_LOC frame) { //If paging isn't enabled we are not going to be able to free a frame of virtual memory //and the stacks location is virtual (Cannot be accessed without paging) if (paging_enabled == 0) { return; } //Anything under used_mem_end is identity mapped (Physical Address == Virtual Address) //never remap it. if (frame < used_mem_end + PAGE_SIZE) { return; } if (getCurrentProcess() != 0) { usedListRemove(getCurrentProcess(), frame); } //Run out of stack space *Shock Horror* Allocate this frame to the end //of the stack (Giving another 4kb (4096 bytes) of stack space) if (phys_mm_smax <= phys_mm_slock) { map((POINTER) phys_mm_smax, (POINTER) frame, MEMORY_RESTRICTED_ACCESS); phys_mm_smax += PAGE_SIZE; } else { //Add the frame to the end of the frame stack MEM_LOC* stack = (MEM_LOC*) phys_mm_slock; *stack = frame; phys_mm_slock += sizeof(uint32_t); } }
void startSleepProcess(Process *process) { if (process!=null && (*process).status == STATUS_PROCESS_RUNNING) { Process *currentProcess = getCurrentProcess(); removeProcess(process); if (process == currentProcess) { currentProcess = getCurrentProcess(); short currentProcessNum = (*currentProcess).tssSelector; switchProcess(0, currentProcessNum); } } return; }
HIDDEN void IOIntHandler(unsigned int devAddr, unsigned int devCommand) { unsigned int cpuID = getPRID(); memaddr *devCommandReg; // Esegue una V sul semaforo del device, risvegliando il primo processo bloccato unsigned char unlockedProcess = devSemV(devAddr); if(unlockedProcess == FALSE) saveRetDevStatus(devAddr); mutexLock(getDevDbMutex()); /* Mando l'ack dell'interrupt */ devCommandReg = (memaddr *) devCommand; *devCommandReg = DEV_C_ACK; mutexUnlock(getDevDbMutex()); if(getCurrentProcess(cpuID) != NULL) // RILANCIO IL PROCESSO CHE ESEGUIVA SULLA CPU currentProcessRestart(cpuID, FALSE); else { processInterleave(NULL); currentProcessRestart(cpuID, TRUE); } }
void Process:: unmap(void* start, long long length) { Monitor::Synchronized method(monitor); const void* end; Map* map; end = static_cast<const u8*>(start) + length; start = Page::trunc(start); end = Page::round(end); if (end <= start) // check wrap around { return; } if (getCurrentProcess() == this) { load(); // flush TLB } Map::List::Iterator iter = mapList.begin(); while ((map = iter.next())) { if (end <= map->start) { break; } if (map->end <= start) { continue; } if (start <= map->start && map->end <= end) { mmu->unset(map->start, map->length, map->pageable, map->offset); iter.remove(); delete map; continue; } if (map->start < start) { mmu->unset(start, (u8*) map->end - (u8*) start, map->pageable, map->offset + ((u8*) start - (u8*) map->start)); map->end = start; } if (end < map->end) { mmu->unset(end, (u8*) map->end - (u8*) end, map->pageable, map->offset + ((u8*) end - (u8*) map->start)); map->start = end; } map->length = (u32*) map->end - (u32*) map->start; } }
HIDDEN void intervalIntHandler(state_t *int_oldarea) { unsigned int cpuID = getPRID(); // Sblocca tutti i processi in coda sul semaforo dello pseudoClock flushPseudoClock(); // Risetta il timer di pseudoClock setPseudoClockTimer(); if(getCurrentProcess(cpuID) != NULL) // RILANCIO IL PROCESSO CHE ESEGUIVA SULLA CPU currentProcessRestart(cpuID, FALSE); else { processInterleave(NULL); currentProcessRestart(cpuID, TRUE); } }
void Process:: kill() { if (getCurrentProcess() == this) { exit(1); // NOT REACHED HERE } // Cancel all the threads. Monitor::Synchronized method(monitor); Thread* thread; List<Thread, &Thread::linkProcess>::Iterator iter = threadList.begin(); while ((thread = iter.next())) { ASSERT(thread != Thread::getCurrentThread()); thread->setCancelState(es::CurrentThread::CANCEL_ENABLE); thread->setCancelType(es::CurrentThread::CANCEL_DEFERRED); thread->cancel(); } }
void intHandler(void) { unsigned int timeStamp = GET_TODLOW; unsigned int prid = getPRID(); state_t *ints_oldarea; pcb_t* current = getCurrentProcess(prid); if(prid == 0) ints_oldarea = (state_t *) INT_OLDAREA; else ints_oldarea = getNewOldAreaPtr(prid, INT_OLDAREA_INDEX); // Aggiorno i tempi di esecuzione del processo updateProcessExecTime(timeStamp, current); // Aggiorno lo stato del processore nel pcb updatePcbCPUState(ints_oldarea, current); /* selezione del gestore per gli interrupt giusto */ if(CAUSE_IP_GET(ints_oldarea->cause, 1)) /* interrupt processor local timer */ { pltIntHandler(current); } else if (CAUSE_IP_GET(ints_oldarea->cause, 2)) { intervalIntHandler(ints_oldarea); /* interval timer interrupt */ } else if (CAUSE_IP_GET(ints_oldarea->cause, 7)) /* int terminali */ { unsigned int dBA = dev_search(devCalc(4)); /* calcolo se l'int è del sub-device trasmettitore, ricevitore o entrambi */ if (((*(memaddr *) dBA + 0x8) >= ILLEGAL_OPCODE) || ((*(memaddr *) dBA + 0x8) <= CHAR_TRASM)) IOIntHandler(dBA + 0x8, dBA + 0xc); if (((*(memaddr *) dBA) >= ILLEGAL_OPCODE) || ((*(memaddr *) dBA) <= CHAR_RECV)) IOIntHandler(dBA, dBA + 0x4); } }
/** * Execute process */ void executeProcess () { process* proc = 0; int entryPoint = 0; unsigned int procStack = 0; /* get running process */ proc = getCurrentProcess(); if (proc->id==PROC_INVALID_ID) return; if (!proc->pageDirectory) return; /* get esp and eip of main thread */ entryPoint = proc->threads[0].frame.eip; procStack = proc->threads[0].frame.esp; /* switch to process address space */ __asm cli pmmngr_load_PDBR ((physical_addr)proc->pageDirectory); /* execute process in user mode */ __asm { mov ax, 0x23 ; user mode data selector is 0x20 (GDT entry 3). Also sets RPL to 3 mov ds, ax mov es, ax mov fs, ax mov gs, ax ; ; create stack frame ; push 0x23 ; SS, notice it uses same selector as above push [procStack] ; stack push 0x200 ; EFLAGS push 0x1b ; CS, user mode code selector is 0x18. With RPL 3 this is 0x1b push [entryPoint] ; EIP iretd } }
void syscallRequestRunNewProcess(const char* executablePath) { createNewProcess(executablePath, getCurrentProcess()->executionDirectory); }
void renameCurrentProcess(const char* str) { setProcessName(getCurrentProcess(), str); }
void syscallRequestExit(int returnValue) { getCurrentProcess()->returnValue = returnValue; schedulerKillCurrentProcess(); }
/** * Create process * \param appname Application file name * \ret Status code */ int createProcess (char* appname) { IMAGE_DOS_HEADER* dosHeader = 0; IMAGE_NT_HEADERS* ntHeaders = 0; FILE file; pdirectory* addressSpace = 0; process* proc = 0; thread* mainThread = 0; unsigned char* memory = 0; unsigned char buf[512]; uint32_t i = 0; /* open file */ file = volOpenFile (appname); if (file.flags == FS_INVALID) return 0; if (( file.flags & FS_DIRECTORY ) == FS_DIRECTORY) return 0; /* read 512 bytes into buffer */ volReadFile ( &file, buf, 512); if (! validateImage (buf)) { volCloseFile ( &file ); return 0; } dosHeader = (IMAGE_DOS_HEADER*)buf; ntHeaders = (IMAGE_NT_HEADERS*)(dosHeader->e_lfanew + (uint32_t)buf); /* get process virtual address space */ // addressSpace = vmmngr_createAddressSpace (); addressSpace = vmmngr_get_directory (); if (!addressSpace) { volCloseFile (&file); return 0; } /* map kernel space into process address space. Only needed if creating new address space */ //mapKernelSpace (addressSpace); /* create PCB */ proc = getCurrentProcess(); proc->id = 1; proc->pageDirectory = addressSpace; proc->priority = 1; proc->state = PROCESS_STATE_ACTIVE; proc->threadCount = 1; /* create thread descriptor */ mainThread = &proc->threads[0]; mainThread->kernelStack = 0; mainThread->parent = proc; mainThread->priority = 1; mainThread->state = PROCESS_STATE_ACTIVE; mainThread->initialStack = 0; mainThread->stackLimit = (void*) ((uint32_t) mainThread->initialStack + 4096); mainThread->imageBase = ntHeaders->OptionalHeader.ImageBase; mainThread->imageSize = ntHeaders->OptionalHeader.SizeOfImage; memset (&mainThread->frame, 0, sizeof (trapFrame)); mainThread->frame.eip = ntHeaders->OptionalHeader.AddressOfEntryPoint + ntHeaders->OptionalHeader.ImageBase; mainThread->frame.flags = 0x200; /* copy our 512 block read above and rest of 4k block */ memory = (unsigned char*)pmmngr_alloc_block(); memset (memory, 0, 4096); memcpy (memory, buf, 512); /* load image into memory */ for (i=1; i <= mainThread->imageSize/512; i++) { if (file.eof == 1) break; volReadFile ( &file, memory+512*i, 512); } /* map page into address space */ vmmngr_mapPhysicalAddress (proc->pageDirectory, ntHeaders->OptionalHeader.ImageBase, (uint32_t) memory, I86_PTE_PRESENT|I86_PTE_WRITABLE|I86_PTE_USER); /* load and map rest of image */ i = 1; while (file.eof != 1) { /* allocate new frame */ unsigned char* cur = (unsigned char*)pmmngr_alloc_block(); /* read block */ int curBlock = 0; for (curBlock = 0; curBlock < 8; curBlock++) { if (file.eof == 1) break; volReadFile ( &file, cur+512*curBlock, 512); } /* map page into process address space */ vmmngr_mapPhysicalAddress (proc->pageDirectory, ntHeaders->OptionalHeader.ImageBase + i*4096, (uint32_t) cur, I86_PTE_PRESENT|I86_PTE_WRITABLE|I86_PTE_USER); i++; } /* Create userspace stack (process esp=0x100000) */ void* stack = (void*) (ntHeaders->OptionalHeader.ImageBase + ntHeaders->OptionalHeader.SizeOfImage + PAGE_SIZE); void* stackPhys = (void*) pmmngr_alloc_block (); /* map user process stack space */ vmmngr_mapPhysicalAddress (addressSpace, (uint32_t) stack, (uint32_t) stackPhys, I86_PTE_PRESENT|I86_PTE_WRITABLE|I86_PTE_USER); /* final initialization */ mainThread->initialStack = stack; mainThread->frame.esp = (uint32_t)mainThread->initialStack; mainThread->frame.ebp = mainThread->frame.esp; /* close file and return process ID */ volCloseFile(&file); return proc->id; }