Hey, thanks for the speedy replies, this problem is really annoying. I think im going to have to post some my code. Bellow is my first (and most simple attempt) to get the context switching to work. i have tried modifying it in several ways which produced diffrent results, but since none of them worked i think its better i just give you the most simple stuff.
This is a shortend copy of my code that sets up a new process, it creates the address space for the process, switches into it, then sets up the stack to mimic an interrupted process, updates fields in the processes structure, then switches back to the kernel address space.
Code: Select all
void processInitializeProcess(unsigned long entrypoint,char*name,ProcessStructure* p)
{
p->ID = 0;
p->ProcessName = name;
p->Priority = 5;
p->State = 0;
p->PageDirectoryAddress = createPageDirectory();
unsigned long oldpd = read_cr3();
write_cr3(p->PageDirectoryAddress);
unsigned long* stacksetup = (unsigned long*)((1022 << 22)+( 1022<< 12));
//mimic interupt stackframe
stacksetup--;
*stacksetup=0x0202;
stacksetup--;
*stacksetup=0x08;
stacksetup--;
*stacksetup=entrypoint;
//Mimics pushad
stacksetup--;
*stacksetup = 0;
stacksetup--;
*stacksetup = 0;
stacksetup--;
*stacksetup = 0;
stacksetup--;
*stacksetup = 0;
stacksetup--;
*stacksetup = 0;
stacksetup--;
*stacksetup = 0;
stacksetup--;
*stacksetup = 0;
stacksetup--;
*stacksetup = 0;
p->StackPointer = (unsigned long) stacksetup;
write_cr3(oldpd);
return;
}
i do this twice to create two processes one called testprocess, the other called idleprocess, both just sit in a loop printing to the screen. i can set either one to be the CurrentProcess then call the following and it will jump into it and start running, no problems so far.
Code: Select all
void StartMultiTasking()
{
CurrentProcessPageDirectory = CurrentProcess->PageDirectoryAddress;
write_cr3(CurrentProcess->PageDirectoryAddress);
asm ("movl %0, %%esp\n\t" : :"r"(CurrentProcess->StackPointer));
asm("popa\n\t");
asm("iret\n\t");
}
now i need to do a context switch, the following asm is called directly apon a timer interrupt.
Code: Select all
timer_stub:
cli
pushad
mov eax, esp
mov [CurrentProcessStack], eax
mov eax, cr3
mov [CurrentProcessPageDirectory], eax
call TaskHandler
mov eax,[CurrentProcessPageDirectory]
mov cr3,eax
mov esp,[CurrentProcessStack]
mov al,0x20
out 0x20,al
popad
sti
iret
and this is the task handler code called by the above asm.
Code: Select all
ProcessStructure* CurrentProcess;
unsigned int TimeSlice = 55;
static unsigned long CurrentStack;
static unsigned long CurrentPD;
unsigned long* CurrentProcessPageDirectory = & CurrentPD;
unsigned long* CurrentProcessStack = &CurrentStack;
void TaskHandler()
{
TimeSlice--;
//VGADriver::print("TICK");
if(TimeSlice > 0) return;
//VGADriver::print("TOCK");
CurrentProcess->PageDirectoryAddress = CurrentPD;
CurrentProcess->UStackPointer = CurrentStack;
CurrentProcess = CurrentProcess->nextProcess;
TimeSlice = 55;
//Check to see if current process is set to be the next process(which it is)
VGADriver::print(CurrentProcess->ProcessName);
CurrentPD = CurrentProcess->PageDirectoryAddress;
CurrentStack = CurrentProcess->UStackPointer;
return;
}
Very embarisingly the task switching code does nothing. It prints TICK TOCK and the process names as it should, but it never actually switches task. Various attempts have been made to fix it, some of which genneratd a genneral protection fault 0 exception, i expect the problem is in the asm cos thats what im worst at

. Pls could somebody unscramble this mess
