Multitasking
Posted: Fri Dec 08, 2006 1:03 pm
I've been working on this for a while, and I can't quite get it right. It doesn't crash anymore, but it doesn't do anything. Here's the assembly part:
Here's the C part:
I'm pretty sure there's an obvious mistake somewhere in here, but I'm unable to find it. Any help would be appreciated.
Code: Select all
[GLOBAL hwint00]
[extern _timer_handler]
hwint00:
REG_SAVE
cli
call _timer_handler
mov dx,20h
mov al,20h
out dx,al
REG_RESTORE_MASTER
ret ; shouldn't get here, but...
%macro REG_SAVE 0
cld
pushad
push ds
push es
push fs
push gs
mov eax,[cPROC] ;put the adress of the struct of CURRENT PROCESS in eax.(the CONTENT of pointer p)
mov [eax],esp ;save esp in the location of esp in the CURRENT PROCESS-STRUCT.
lea eax,[kstackend] ; switch to the kernel's own stack.
mov esp,eax
%endmacro
%macro REG_RESTORE_MASTER 0
mov eax,[cPROC] ;put adress of struct of current process in eax.
mov esp,[eax] ;restore adress of esp.
mov ebx,[eax+8];put content of the k-stack field into ebx.
mov [cTSS+4],ebx ;update system tss.
mov al,0x20
out 0x20,al
pop gs
pop fs
pop es
pop ds
popad
iretd
%endmacro
Code: Select all
#include <system.h>
#define KSTACKTOP 1024
#define USTACKTOP 1024
typedef struct {
uint_t esp;
uint_t ss;
uint_t kstack;
uint_t ustack;
uint_t cr3;
ulong_t PADDING;
uint_t pid;
uchar_t name[32];
} pdata_t;
typedef struct {
ushort_t backlink, __blh;
uint_t esp0;
ushort_t ss0, __ss0h;
uint_t esp1;
ushort_t ss1, __ss1h;
uint_t esp2;
ushort_t ss2, __ss2h;
uint_t cr3;
uint_t eip;
uint_t eflags;
uint_t eax, ecx, edx, ebx;
uint_t esp, ebp, esi, edi;
ushort_t es, __esh;
ushort_t cs, __csh;
ushort_t ss, __ssh;
ushort_t ds, __dsh;
ushort_t fs, __fsh;
ushort_t gs, __gsh;
ushort_t ldt, __ldth;
ushort_t trace, bitmap;
} tss_t;
tss_t cTSS;
pdata_t processes[32];
pdata_t* cPROC;
uint_t procnum = 1;
unsigned char kstacks[32][KSTACKTOP];
unsigned char stacks[32][USTACKTOP];
void init_task( int task , unsigned epoint )
{
uint_t *stacksetup;
stacksetup=(uint_t*)&kstacks[task][KSTACKTOP]; //esp0
stacksetup-- ; //SS
*stacksetup--=0x0202; //flags
*stacksetup--=0x08; // CS
*stacksetup--=epoint; // Instruction pointer
*stacksetup--= 0; //error code
*stacksetup--=0x20; // interupt no.
*stacksetup--=0; //ebp
*stacksetup--=0; //esp
*stacksetup--=0; //edi
*stacksetup--=0; //esi
*stacksetup--=0; //edx
*stacksetup--=0; //ecx
*stacksetup--=0; //ebx
*stacksetup--=0; //eax
*stacksetup--=0x20; //ds
*stacksetup--=0x20; //es
*stacksetup--=0x20; //fs
*stacksetup= 0x20; //gs
//filling in the struct.
processes[task].esp=(uint_t)stacksetup;
processes[task].ss=0x10;
processes[task].kstack=(uint_t)&kstacks[task][KSTACKTOP];
processes[task].ustack=(uint_t)&stacks[task][USTACKTOP];
processes[task].PADDING = (ulong_t)"PUDDING!";
processes[task].pid = task;
}
void schedule()
{
//putch('s');
++procnum;
if (procnum > 3) {procnum = 1;}
cPROC = &processes[procnum];
}
void t1() {putch('1');}
void t2() {putch('2');}
void t3() {putch('3');}
void mtask_init()
{
init_task(1,(unsigned)t1);
init_task(2,(unsigned)t2);
init_task(3,(unsigned)t3);
}