Stack Switching After Task Switch
Posted: Mon Feb 11, 2013 1:00 pm
Hi, please could you please help, I have been stuck on software task switching for a while now. I have managed to get my tasks to switch by using a interrupt and then just save and restore EIP (and other regs). This has proved to work but I noticed that I would get random errors when changing to tasks that call other functions, by random I mean Page Fault, or GPF, or Invalid Opcode. I also noticed that the EIP when the error happens is why off any of my code (ie 0x4c). I assume this has to do with stack corruption as each task does not have its own stack because I have never managed to be able to set ESP on return from a interrupt. I have come up with the idea to get the interrupt to set EIP to an intermediary function which changes that stack pointer then jumps to the real code of the current task. See the code below.
This called when the interrupt is fired.
This is called when the interrupt returns and should switch the stack, this works, and jump to the EIP of the current task, this also works.
The problem is that when the task comes around for the second time a page fault occurs because due to a read operation at a huge (random) address
I want to work towards solving this problem so I do not expect the code needed to fix this. Any help would be greatly appreciated
Code: Select all
void TASKING_switch(CPU_REGISTERS *regs)
{
if(bEnabled) //Have we enabled tasking yet?
{
if(task_switched == 1)
{
debug_serial_write("Old EIP =");
debug_serial_write(regs->eip);
debug_serial_write("\n\r");
memcpy(¤t_task->Regs, regs, sizeof(CPU_REGISTERS));
current_task = current_task->Next;
if(current_task == 0)
current_task = task_list_head;
}
konsole_write("Switching Task\n\r");
memcpy(regs, ¤t_task->Regs, sizeof(CPU_REGISTERS));
regs->eip = (DWORD)do_switch;
task_switched = 1;
}
}
Code: Select all
void do_switch(void)
{
HAL_set_esp(current_task->Regs.esp);
jmpPtr jmp = (jmpPtr)current_task->Regs.eip;
jmp();
}
The problem is that when the task comes around for the second time a page fault occurs because due to a read operation at a huge (random) address
I want to work towards solving this problem so I do not expect the code needed to fix this. Any help would be greatly appreciated