PLAESE HELP OUT distinguish the error in the code that causes a page faullt and messes the registers up!! =[
I also use these:
Code:
global writeto_cr3
writeto_cr3:
mov eax, [esp+4]
mov cr3, eax
ret
global or_cr0
or_cr0:
mov eax, cr0
or eax, 0x80000000
mov cr0, eax
ret
global readfrom_cr2 ; for page faults
readfrom_cr2:
mov eax, cr2
ret
and my current code (i just copied this code now for a tutorial because im so exhausted =[)
Code:
#include "task.h"
#include "mm.h"
#include "screen.h"
#include "hardware.h"
typedef struct{ //Simple structure for a thread
unsigned int esp0; //Stack for kernel
unsigned int esp3; //Stack for process
} Thread;
Thread Threads[2]; //Space for our simple threads. Just 2!
int CurrentTask = -1; //The thread currenlty running (-1 == none)
int first = 0;
void initialize_multitasking(void)
{
CreateTask(0, idle);
CreateTask(1, idle);
unsigned int divisor = 1193180 / 50;
outport(0x43, 0x36);
outport(0x40, divisor & 0xFF);
outport(0x40, (divisor >> 8) & 0xFF);
outport(0x21, 0x00); // enable interrupts from IRQ 0-7 (PIT will now start working)
}
void idle()
{
puts("IDLE");
for(;;) ;
}
void idle2()
{
puts("idle");
for(;;) ;
}
//This will create a task
//It will make a stack that looks like it has all
//of the stuff of an IRQ handler 'pushed' on it
void CreateTask(int id, void (*thread)()){
unsigned int *stack;
Threads[id].esp0 = (unsigned int)malloc(0x1000) + 4096; //This allocates 4kb of memory, then puts the pointer at the end of it
stack = (unsigned int* )Threads[id].esp0; //This makes a pointer to the stack for us
//First, this stuff is pushed by the processor
*--stack = 0;
*--stack = 0;
*--stack = 0x0202; //This is EFLAGS
*--stack = 0x08; //This is CS, our code segment
*--stack = (unsigned int)thread; //This is EIP
//Next, the stuff pushed by 'pusha'
*--stack = 0; //EDI
*--stack = 0; //ESI
*--stack = 0; //EBP
*--stack = 0; //Just an offset, no value
*--stack = 0; //EBX
*--stack = 0; //EDX
*--stack = 0; //ECX
*--stack = 0; //EAX
//Now these are the data segments pushed by the IRQ handler
*--stack = 0x10; //DS
*--stack = 0x10; //ES
*--stack = 0x10; //FS
*--stack = 0x10; //GS
Threads[id].esp0 = (unsigned int)stack; //Update the stack pointer
}
//Switch between our two tasks
//Notice how we get the old esp from the ASM code
//It's not a pointer, but we actually get the ESP value
//That way we can save it in our task structure
int TaskSwitch(unsigned int OldEsp){
if(CurrentTask != -1){ //Were we even running a task?
Threads[CurrentTask].esp0 = OldEsp; //Save the new esp for the thread
//Now switch what task we're on
if(CurrentTask == 0) CurrentTask = 1;
else CurrentTask = 0;
} else{
CurrentTask = 0; //We just started multi-tasking, start with task 0
}
unsigned int a = Threads[CurrentTask].esp0;
outport(0x20, 0x20);
// return a;
return OldEsp; //Return new stack pointer to ASM
}
Code:
extern TaskSwitch
extern putdec
global IRQ0
IRQ0:
pusha
push ds
push es
push fs
push gs
mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
push esp
call TaskSwitch
;push eax
;call putdec
;pop eax
mov esp, eax
pop gs
pop fs
pop es
pop ds
popa
iret