Code: Select all
uint32_t phys_addr = pte & ~0xFFF;
Code: Select all
uint32_t phys_addr = pte & ~0xFFF;
Code: Select all
if (runningTask->pid == 0 || pid < 0) return;
if (!process_getProcess(pid)) {
printf("process_wait: no such process %d, system halted\n",pid);
return;
}
struct process *p = process_getProcess(pid);
p->state = 2;
// update pointer
process_yield();
Code: Select all
void process_exit(int pid,int exitCode) {
process_getProcess(pid)->state = 1;
}
Code: Select all
struct process *process_getProcess(int pid) {
return process_findID(pid);
}
Code: Select all
struct process *process_findID(int id) {
clist_head_t *c = clist_find(task_list,process_findIdDispatcher,id);
if (c) {
return (struct process *)c->data;
}
return NULL;
}
Code: Select all
// send end of interrupt to interrupt controller
io_writePort(PIC_SLAVE_COMMAND , 0x20);
io_writePort(PIC_MASTER_COMMAND , 0x20);
struct process *next_task = NULL;
// update clocks
clocks++;
// don't save context on first switch
if (!fswitch || runningTask->state == PROCESS_RUNNING) {
runningTask->esp = stack;
}
if (!fswitch) {
if (!runningTask) {
next_task = process_findByStatus(PROCESS_RUNNING);
} else {
next_task = process_findNextByStatus(PROCESS_RUNNING,runningTask->lAddr);
}
}
if (next_task == NULL) {
// first switch
next_task = process_findByStatus(PROCESS_RUNNING);
}
if (next_task == NULL) {
printf("Next task null\n");
return stack;
}
if (runningTask->state == PROCESS_KILLING) {
if (runningTask->parent != 0) { // idle task hasn't waiting for any pid
struct process *parent = process_findID(runningTask->parent);
if (parent->state != PROCESS_WAIPID) {
printf("Cannot unlock parent: Parent didn't waiting for any child PID: %d\n",runningTask->pid);
} else {
parent->state = PROCESS_RUNNING;
fswitch = true;
return idle->esp;
}
curTasks--;
arch_destroyStack(runningTask->esp);
pmml_free(runningTask->esp);
pmml_free((void *)runningTask->dir);
if (runningTask->kernelESP != 0) {
pmml_free((void *)runningTask->kernelESP);
}
if (runningTask->page_start != 0) {
pmml_freePages((void *)runningTask->page_start,runningTask->pages);
}
clist_delete_entry(task_list,(clist_head_t *)runningTask->lAddr);
pmml_free(runningTask);
}
}
if (next_task->wait_time != 0) {
next_task->wait_time--;
fswitch = true;
return stack;
}
tss_set_stack(0x10,next_task->kernelESP);
vmm_switch((int *)next_task->dir);
fswitch = false;
runningTask = next_task;
return runningTask->esp;
}
It jumps to 0x10 because that's the "last" thing that was stored on the stack. Inspect it to make sure it's not corrupted.WinExperements wrote:but if this function returns(it's must return key if it pressed) it's jumps to 0x0000010 why?
How i can fill correctly it, because i fill it with some parameters to my user startup function, that switches to user mode and jumps to the entry point, but after the restoring it from the saved state, it's switches to kernel mode. Do i need to change my switch function?Octocontrabass wrote:When you initialize the task, fill the stack with values that will make the task return to ring 3 when you switch to it.
As I understand it, the context switch should be called in an IRQ or system call that will return to ring 3? Or what?Octocontrabass wrote:Task switches only happen in ring 0. If the task itself is meant to run in ring 3, then the saved/restored state should be inside an IRQ or syscall handler that will eventually return to ring 3.
Code: Select all
void arch_saveContext(struct process *forWho,registers_t *stack) {
registers_t *f = (registers_t *)forWho->esp;
f->eax = stack->eax;
f->ecx = stack->ecx;
f->edx = stack->edx;
f->ebx = stack->ebx;
f->ebp = stack->ebp;
f->esi = stack->esi;
f->edi = stack->edi;
f->eip = stack->eip;
f->eflags = stack->eflags;
f->useresp = stack->useresp;
}