[Prev][Next][Index][Thread]

Problems coding a scheduler




/*
 * Hi again,
 * We have some problems making a scheduler using the OSKIT tool.
 * We are trying to learn how to make a scheduler as a task
 * gate(we know it's not the best way to code a scheduler). 
 * We have two processes and a scheduler. The scheduler call the 
 * processes and everything seems to work fine. But after a while(just
 * a few seconds on a 80386, more time in a pentium which is really weird)  																  
 * the scheduler schedule one process with the IF off, so the scheduler
 * is never called back again. 
 * The same happens when we code the scheduler as an interrupt gate.
 * What have we done wrong? 
 * Thank you.
 *
 *                                     Juan Carlos Perez
 *                                     Imobac Exposito
 *                                     Vicente Exposito
 *                                     Jose Fresnadillo
 * 
 *                                     La Laguna University
 *                                     La Laguna, Canary Island
 *                                     Spain 
 */


#include <oskit/machine/base_cpu.h>
#include <oskit/x86/pmode.h>
#include <oskit/x86/base_gdt.h>
#include <oskit/machine/base_vm.h>
#include <stdio.h>
#include <oskit/x86/tss.h>
#include <oskit/x86/base_tss.h>
#include <oskit/dev/dev.h>
#include <oskit/x86/proc_reg.h>
#include <oskit/x86/base_idt.h>
#include <oskit/debug.h>
#include <oskit/x86/pio.h>
#include <oskit/x86/pc/pit.h>
#include <oskit/x86/pc/base_irq.h>
#include <oskit/x86/base_trap.h>
#include <oskit/x86/pc/pic.h>


#define USER_TSS1 0x58
#define USER_TSS2 0x60
#define USER_TSS3 0x68


CODE32

struct x86_tss user_base_tss1;
struct x86_tss user_base_tss2;
struct x86_tss user_base_tss3;

long stack1[100];
long stack2[100];
long stack3[100];

/*
 * PROCESS1.-
 * 
 */
void process1(){
   while(1)
	  printf("P1: eFlags: %#x \n", get_eflags());
}
/*
 * PROCESS2.-
 * 
 */
void process2(void){
   while (1)
	  printf("P2: eFlags %#x\n", get_eflags());
}




/*
 * SCHEDULER.-
 * 
 */ 
void scheduler(void){

   while(1){   
	  printf("Process 1 \n");
	  base_gdt[USER_TSS1 / 8].access &= ~ACC_TSS_BUSY;
	  outb(0x20, 0x20);
	  asm(".byte 0xea, 0x00, 0x0, 0x00, 0x00, 0x58, 0x00");   
	  printf("Process 2\n");
	  base_gdt[USER_TSS2 / 8].access &= ~ACC_TSS_BUSY;
	  outb(0x20, 0x20);	  
	  asm(".byte 0xea, 0x00, 0x0, 0x00, 0x00, 0x60, 0x00");
   }
   
   /*just in case*/
   asm("iret");
}




/* 
 * MAIN PROGRAM.-
 * 
 */

void main(void) {
   
   /* Make sure we're not already in protected mode.  */
   if (i16_get_msw() & CR0_PE)
	 printf("The processor is in protected mode environment.\n");
   
   base_gdt_init();
   base_gdt_load();
   base_tss_init();
   base_tss_load();
   
   fill_descriptor(&base_gdt[USER_TSS1 / 8],
				   &user_base_tss1, sizeof(user_base_tss1) - 1,
				   ACC_PL_K | ACC_TSS | ACC_P, 0);

   fill_descriptor(&base_gdt[USER_TSS2 / 8],
				   &user_base_tss2, sizeof(user_base_tss2) - 1,
				   ACC_PL_K | ACC_TSS | ACC_P, 0);
   
   fill_descriptor(&base_gdt[USER_TSS3 / 8],
				   &user_base_tss3, sizeof(user_base_tss3) - 1,
				   ACC_PL_K | ACC_TSS | ACC_P, 0);
   
   base_tss.eflags = base_tss.eflags | 0x202;
   
   user_base_tss1.eip = &process1;
   user_base_tss1.cs  = KERNEL_CS;
   user_base_tss1.es  = KERNEL_DS;
   user_base_tss1.ds  = KERNEL_DS;
   user_base_tss1.ss  = KERNEL_DS;
   user_base_tss1.fs  = KERNEL_DS;
   user_base_tss1.gs  = KERNEL_DS;   
   user_base_tss1.ss0 = KERNEL_DS;   
   user_base_tss1.ss1 = KERNEL_DS;   
   user_base_tss1.ss2 = KERNEL_DS;   
   user_base_tss1.esp = sizeof(stack1) * 100 + (long)stack1;   
   user_base_tss1.esp0 = sizeof(stack1) * 100 + (long)stack1;
   user_base_tss1.esp1 = sizeof(stack1) * 100 + (long)stack1;      
   user_base_tss1.esp2 = sizeof(stack1) * 100 + (long)stack1;   
   user_base_tss1.io_bit_map_offset = sizeof(user_base_tss1);
   user_base_tss1.ldt = 0;
   user_base_tss1.eflags = 0x202;
   base_gdt[USER_TSS1 / 8].access &= ~ACC_TSS_BUSY;

   user_base_tss2.eip = (long)&process2;
   user_base_tss2.cs  = KERNEL_CS;
   user_base_tss2.es  = KERNEL_DS;
   user_base_tss2.ds  = KERNEL_DS;
   user_base_tss2.ss  = KERNEL_DS;
   user_base_tss2.fs  = KERNEL_DS;
   user_base_tss2.gs  = KERNEL_DS;
   user_base_tss2.ss0 = KERNEL_DS;
   user_base_tss2.ss1 = KERNEL_DS;
   user_base_tss2.ss2 = KERNEL_DS;
   user_base_tss2.esp = sizeof(stack2) * 100 + (long)stack2;
   user_base_tss2.esp0 = sizeof(stack2) * 100 + (long)stack2;
   user_base_tss2.esp1 = sizeof(stack2) * 100 + (long)stack2;      
   user_base_tss2.esp2 = sizeof(stack2) * 100 + (long)stack2;   
   user_base_tss2.io_bit_map_offset = sizeof(user_base_tss2);
   user_base_tss2.ldt = 0;
   user_base_tss2.eflags = 0x202;   
   base_gdt[USER_TSS2 / 8].access &= ~ACC_TSS_BUSY;
   
   user_base_tss3.eip = (long)&scheduler;
   user_base_tss3.cs  = KERNEL_CS;
   user_base_tss3.es  = KERNEL_DS;
   user_base_tss3.ds  = KERNEL_DS;
   user_base_tss3.ss  = KERNEL_DS;
   user_base_tss3.fs  = KERNEL_DS;
   user_base_tss3.gs  = KERNEL_DS;
   user_base_tss3.ss0 = KERNEL_DS;
   user_base_tss3.ss1 = KERNEL_DS;
   user_base_tss3.ss2 = KERNEL_DS;
   user_base_tss3.esp = sizeof(stack3) * 100 + (long)stack3;   
   user_base_tss3.esp0 = sizeof(stack3) * 100 + (long)stack3;
   user_base_tss3.esp1 = sizeof(stack3) * 100 + (long)stack3;      
   user_base_tss3.esp2 = sizeof(stack3) * 100 + (long)stack3;   
   user_base_tss3.io_bit_map_offset = sizeof(user_base_tss3);
   user_base_tss3.ldt = 0;
   user_base_tss3.eflags = 0x2;
   base_gdt[USER_TSS3 / 8].access &= ~ACC_TSS_BUSY;


   
   
   
   
   osenv_intr_disable();
   
   fill_gate(&base_idt[irq_master_base + 0], 0, USER_TSS3, 
			 ACC_TASK_GATE | ACC_PL_K, 0);

   pit_init(100);
   osenv_irq_enable(0);
   osenv_intr_enable();   
   
   
   
   
   
   while (1)
	 ;
	 
   return;
}