[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;
}