multitasking
Posted: Sun Sep 06, 2009 11:26 pm
hi everyone.
here is my problem, i just can't get task switching right.I m trying to implement software-based task switching, but it just doesn't work, it get stucks on the first task, i m pretty sure it's the interrupt stack frame that's buggy, and i did googled and search the forums, but i m so frustrated and confused, i m just going nowhere.
i set up an idt with a stub for each interrupt with an (eventual) error code and int number
then a general stub is called
eventually calling sys_timer and scheduler
scheduler just go round robin with 2 tasks right now
context save (context restore just the opposite) :
tasks are just vga_putc('A');
so i know it s running at first. tasks are kernel land, set up with stacks (esp, esp0 but the last is not used i guess), int on, no ldt, etc... pit is 1mhz
i know it's stupid, but there's so much to do and to learn, i m just lost. if i forgot to detail anything, just ask.
thanks to anyone bothering reading this, or answering and sorry for eventual bad english (and bad code).
here is my problem, i just can't get task switching right.I m trying to implement software-based task switching, but it just doesn't work, it get stucks on the first task, i m pretty sure it's the interrupt stack frame that's buggy, and i did googled and search the forums, but i m so frustrated and confused, i m just going nowhere.
i set up an idt with a stub for each interrupt with an (eventual) error code and int number
Code: Select all
__declspec(naked) void int_1()
{
_asm push 0;
_asm push 1;
_asm jmp int_stub;
}
Code: Select all
__declspec(naked) void int_stub()
{
__asm
{
pushad;
push ds;
push es;
push fs;
push gs;
mov ax, KDATA_SEGMENT;
mov ds, ax;
mov es, ax;
mov gs, ax;
mov ax, KPCR_SEGMENT;
mov fs, ax;
mov eax, esp;
push eax;
mov eax, int_handler;
call eax;
pop eax;
pop gs;
pop fs;
pop es;
pop ds;
popad;
add esp, 8;
iretd;
}
}
Code: Select all
void sys_timer(PREGS regs)
{
tick_count++;
vga_count++;
if(vga_count==16)
{
vga_count = 0;
vga_flip();
}//*/
task_scheduler(regs);
}
Code: Select all
void task_scheduler(PREGS regs)
{
PKTHREAD pcur_thread = task_get_current_thread();
PKTHREAD pnext_thread = pcur_thread->next;
PKPCR kpcr = cpu_getkpcr();
task_save_regs(pcur_thread, regs);
pcur_thread->quantum = TASK_DEFAULT_QUANTUM;
task_set_current_thread(pnext_thread);
task_load_regs(pnext_thread, regs);
pcur_thread->state = THREAD_STATE::runnable;
pnext_thread->state = THREAD_STATE::running;
}
Code: Select all
void task_save_regs(PKTHREAD pthread, PREGS regs)
{
pthread->tss.ds = (WORD)regs->ds;
pthread->tss.es = (WORD)regs->es;
pthread->tss.fs = (WORD)regs->fs;
pthread->tss.gs = (WORD)regs->gs;
pthread->tss.cs = (WORD)regs->cs;
pthread->tss.ss = (WORD)regs->ss;
pthread->tss.eax = regs->eax;
pthread->tss.ecx = regs->ecx;
pthread->tss.edx = regs->edx;
pthread->tss.ebx = regs->ebx;
pthread->tss.esi = regs->esi;
pthread->tss.edi = regs->edi;
pthread->tss.esp = regs->esp;
pthread->tss.ebp = regs->ebp;
pthread->tss.eip = regs->eip;
pthread->tss.eflags = regs->eflags;
}
so i know it s running at first. tasks are kernel land, set up with stacks (esp, esp0 but the last is not used i guess), int on, no ldt, etc... pit is 1mhz
i know it's stupid, but there's so much to do and to learn, i m just lost. if i forgot to detail anything, just ask.
thanks to anyone bothering reading this, or answering and sorry for eventual bad english (and bad code).