Before i enable scheduler, i make special tss called lizard.
It is in ring3 and have KERNEL_PAGE_DIRECTORY loaded in cr3 register. When kernel is finishing initialization, it executes long jump to the lizard process and sets sched_enabled varible to 1 (this means that the scheduler is enabled:)
Code: Select all
struct intr_handler_frame {
UINT32 ds;
UINT32 es;
UINT32 fs;
UINT32 gs;
UINT32 edi;
UINT32 esi;
UINT32 ebp;
UINT32 old_esp;
UINT32 ebx;
UINT32 edx;
UINT32 ecx;
UINT32 eax;
UINT32 intr_index;
UINT32 intr_ecode;
UINT32 eip;
UINT32 cs;
UINT32 flags;
UINT32 esp;
UINT32 ss;
};
Code: Select all
__low_int_controller:
pushal
pushl %gs
pushl %fs
pushl %es
pushl %ds
movl $0x18, %eax
movw %ax, %es
movw %ax, %ds
movw %ax, %fs
movw %ax, %gs
movw %ax, %ss
call interrupt_controler
popl %ds
popl %es
popl %fs
popl %gs
popal
addl $8, %esp
iret
#define INTERRUPT_HANDLER(name,nr)\
.global name; \
name: \
cli; \
pushl $0; \
pushl $nr; \
jmp __low_int_controller;[code]
example:
INTERRUPT_HANDLER(scheduler,0x20)
Code: Select all
NORETURN interrupt_controler( UINT32 *stack ) {
struct intr_handler_frame *intr_frame = (struct intr_handler_frame *) &stack;
switch( intr_frame -> intr_index )
{
case 0x0: case 0x1: case 0x2: case 0x3: case 0x4: case 0x5: case 0x6: case 0x7: case 0x8: case 0x9: case 0xA: case 0xB: case 0xC: case 0xD: case 0xE: case 0xF: case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17: case 0x18: case 0x19: case 0x1A: case 0x1B: case 0x1C: case 0x1D: case 0x1E: case 0x1F:
valid_exception( intr_frame -> intr_index );
break;
case 0x20:
software_scheduler( intr_frame );
break;
case 0x21: case 0x22: case 0x23: case 0x24: case 0x25:
case 0x26: case 0x27: case 0x28: case 0x29: case 0x2a:
case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f:
IRQ_router( intr_frame -> intr_index - 0x20 );
break;
case 0x80:
syscalls_service(current_process, intr_frame -> edx);
break;
default:
printk("interrupt controler: unimplemented interrupt signal received!\n");
break;
}
}
/*****************SCHEDULER**********************/
Code: Select all
NORETURN software_scheduler( struct intr_handler_frame *frame ) {
if (sched_enabled == 1) {
/* saving process state */
current_process -> frame_ptr = frame;
/******* SCHEDULER ALOGHORITM CUTED ********/
/******* SCHEDULER ALOGHORITM CUTED ********/
current_process = current_process -> next;
frame = current_process -> frame_ptr;
lizard -> tss.esp0 = current_process -> travel_esp;
/* Is this is necesery? */
lizard -> tss.cs = frame -> cs;
lizard -> tss.ds = frame -> ds;
lizard -> tss.es = frame -> es;
lizard -> tss.fs = frame -> fs;
lizard -> tss.gs = frame -> gs;
lizard -> tss.ss0 = current_process -> travel_ss;
lizard -> tss.ss = frame -> ss;
asm("movl %0, %%eax\n"
"movl %%eax, %%cr3" :: "m" (current_process -> user_cr3));
asm("movl %0, %%esp\n"
"popl %%ds\n"
"popl %%es\n"
"popl %%fs\n"
"popl %%gs\n"
"popal\n"
"addl $8, %%esp\n"
"iret" :: "r" (current_process -> frame_ptr));
}
}
#define KERNEL_DS 0x18
#define USER_CS 0x20 |3
#define USER_DS 0x28 |3
AND I HAVE _BIG_ PROBLEM:
It works - tasks are switching very well, but sometimes (I have program called 'faulter'), when I executes faulter and select invalid operation called 'Protection Fault' (it execeutes two instructions 'cli' & 'hlt' - faulter works in RING3)
Code: Select all
/*******************FAULTER.C*************************/
#define sysCall() \
__asm__ __volatile__ ("lcall $0x023B,$0x00000000 \n\t")
int main( void )
{
char msg[2];
printk("\nWhat kind of fault would you like to execute?\n\n");
printk("1: memory fault\n");
printk("2: port fault\n");
printk("3: protection fault\n");
printk("4: code fault\n");
scanf(msg);
if ( !strcmp(msg,"1") ) {
printk("You selected memory fault! (0xFFFF)\n");
int *a = 0xFFFF;
*a = 1;
} else
if ( !strcmp(msg,"2") ) {
printk("You selected port fault!\n");
asm("movw $0x20, %ax\n"
"outw %ax, $0x20\n");
} else
if ( !strcmp(msg,"3") ) {
printk("You selected protection fault!\n");
asm("cli\n"
"hlt");
} else
if ( !strcmp(msg,"4") ) {
printk("You selected code fault!\n");
sysCall();
}
printk("Ooops, it works! - better update the kernel!\n");
}
/**********************************************************/
Ooops, it works! - better update the kernel!
and dump my exceptions handler code:
System Protection Fault on xx/xx/xx, at xx
PANIC: Memory Fault!
*** access volation at address: 0xXXXXXXX (this is betwen 2GiB-3GiB) ****
/*************************************************/
This is very strange, because it is happening only sometimes
Meaby I've forgotten about something?
Please, help me:)