i create a TSS for the system to use, install it into my gdt, load it with ltr.
I set the PIC to gennerate intterupts at regular intervals and have a handler that catches them, pushes registers,saves stack position, checks to see if it should switch task, loads cr3,loads stack position,pops registers then ireturns.
i create two processes, fill in some generic details for both, and create a page directory for both.
I switch into each processes Address space and setup there stack to mimmic a interrupt followed by pushad instructions (Ie make the stack look like its been the result of a timer interrupt). The code i use for this is the following:
Code: Select all
//Used when creating a process, function replicates the stack from that would have resulted from a Timer Interrupt.
void processInitializeProcess(unsigned long entrypoint,char*name,ProcessStructure* p)
{
unsigned long oldpd = read_cr3();
write_cr3(p->PageDirectoryAddress);
unsigned long* stacksetup = (unsigned long*)((1022 << 22)+( 1022<< 12));
//mimic interupt stackframe
stacksetup--;
*stacksetup = 0x23;//ss
stacksetup--;
*stacksetup = ((1022 << 22)+( 510<< 12));//esp
stacksetup--;
*stacksetup=0x0202; //eflags
stacksetup--;
*stacksetup= 0x1b;//a user level CS, 0x08 was ring 0, put it back in and the whole thing works
stacksetup--;
*stacksetup=entrypoint;//ip
//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;
//push segments
stacksetup--;
*stacksetup=0x23;
stacksetup--;
*stacksetup=0x23;
stacksetup--;
*stacksetup=0x23;
stacksetup--;
*stacksetup=0x23;
p->KStackPointer = (unsigned long) stacksetup;
write_cr3(oldpd);
return;
}
Code: Select all
VGADriver::putStr("Starting Multitasking with Process: ");
VGADriver::print(CurrentProcess->ProcessName);
write_cr3(CurrentProcess->PageDirectoryAddress);
asm ("movl %0, %%esp\n\t" : :"r"(CurrentProcess->KStackPointer));
asm("pop %ds\n\t");
asm("pop %es\n\t");
asm("pop %fs\n\t");
asm("pop %gs\n\t");
asm("popa\n\t");
asm("iret\n\t");
Code: Select all
00024214632i[CPU0 ] >> push ebp : 55
00024214632p[CPU0 ] >>PANIC<< exception(): 3rd (10) exception with no resolution
00024214632i[CPU0 ] CPU is in protected mode (active)
00024214632i[CPU0 ] CS.d_b = 32 bit
00024214632i[CPU0 ] SS.d_b = 32 bit
00024214632i[CPU0 ] | EAX=00000000 EBX=00000000 ECX=00000000 EDX=00000000
00024214632i[CPU0 ] | ESP=ff9fe000 EBP=00000000 ESI=00000000 EDI=00000000
00024214632i[CPU0 ] | IOPL=0 id vip vif ac vm RF nt of df IF tf sf zf af pf cf
00024214632i[CPU0 ] | SEG selector base limit G D
00024214632i[CPU0 ] | SEG sltr(index|ti|rpl) base limit G D
00024214632i[CPU0 ] | CS:001b( 0003| 0| 3) 00000000 000fffff 1 1
00024214632i[CPU0 ] | DS:0023( 0004| 0| 3) 00000000 000fffff 1 1
00024214632i[CPU0 ] | SS:0023( 0004| 0| 3) 00000000 000fffff 1 1
00024214632i[CPU0 ] | ES:0023( 0004| 0| 3) 00000000 000fffff 1 1
00024214632i[CPU0 ] | FS:0023( 0004| 0| 3) 00000000 000fffff 1 1
00024214632i[CPU0 ] | GS:0023( 0004| 0| 3) 00000000 000fffff 1 1
00024214632i[CPU0 ] | EIP=00900053 (00900053)
00024214632i[CPU0 ] | CR0=0xe0000011 CR1=0 CR2=0x00900000
00024214632i[CPU0 ] | CR3=0x01b9c000 CR4=0x00000000
00024214632i[CPU0 ] >> push ebp : 55
00024214632i[CMOS ] Last time is 1222986078 (Thu Oct 2 23:21:18 2008)
00024214632i[XGUI ] Exit
Thanks for your time,
Pinky
(P.S I had a post on this issue over a year ago but due to the elapsed time period and my better understanding of the problem i felt a new post was appropriate but i would like to thank althoughs that helped me then)