I have a little problem with task switching (I hope).
My system works without paging on ring 0 only and using 32 bits architecture.
The objective is create a task management for kernel in this first time. The paging and user-mode will be in the future.
My problem appear when the task will change for the new context on schedule function.
After the schedule function execute all tasks and assign the new context, BOCHS show me a (general protection fault) message. task's and schedule function doesn't execute anymore.
Bellow you can find the main functions about this problem.
I no have ideia how to solve this problem, someone can help-me to fix?
Thank in advance.
k_main.c
Code: Select all
/////////////////////////////////////////////////
// Author: Rafael Angelo Gardini
// File: k_main.c
// Description: Kernel main
// Last update: 21/06/2012
/////////////////////////////////////////////////
#include "../headers/io/stdio.h"
#include "../headers/io/video.h"
#include "../headers/memory/mm.h"
#include "../headers/process/process.h"
#include "../headers/system/fpu.h"
#include "../headers/system/gdt.h"
#include "../headers/system/idt.h"
#include "../headers/system/irq.h"
#include "../headers/system/isr.h"
#include "../headers/system/kernel.h"
#include "../headers/system/timer.h"
#ifndef K_MAIN
void task0(void)
{
k_printf("task0\n");
for(;;);
}
void task1(void)
{
k_printf("task1\n");
for(;;);
}
void task2(void)
{
k_printf("task2\n");
for(;;);
}
void task3(void)
{
k_printf("task3\n");
for(;;);
}
void k_main()
{
k_cli_irq();
k_install_memory();
k_install_video();
k_install_gdt();
k_install_idt();
k_install_irq();
k_install_isr();
k_install_fpu();
k_install_timer();
k_install_process();
k_info_kernel();
k_sti_irq();
//---------------------------------------------
k_create_process(task0);
k_create_process(task1);
k_create_process(task2);
k_create_process(task3);
//---------------------------------------------
k_enable_schedule_process();
k_loop_kernel();
}
#endif
Code: Select all
/////////////////////////////////////////////////
// Author: Rafael Angelo Gardini
// File: process.h
// Description: Process functions
// Last update: 30/09/2013
/////////////////////////////////////////////////
#include "../../headers/io/stdio.h"
#include "../../headers/memory/mm.h"
#include "../../headers/process/process.h"
#include "../../headers/system/irq.h"
#ifndef PROCESS
#define PROCESS
void k_install_process()
{
process.storepid = 0;
process.enable = 0;
process.running = MEMORY_NULL;
process.task = MEMORY_NULL;
k_printf("Install process management sucess...\n");
}
int k_create_stack(void (*task)(void))
{
int stackptr = (int)k_malloc(STACK_SIZE) + STACK_SIZE ;
unsigned int * stack = (unsigned int*)stackptr;
*--stack = 0x202;
*--stack = 0x08;
*--stack = (unsigned int) task;
*--stack = 0;
*--stack = 0;
*--stack = 0;
*--stack = 0;
*--stack = 0;
*--stack = 0;
*--stack = 0;
*--stack = 0;
*--stack = 0x10;
*--stack = 0x10;
*--stack = 0x10;
*--stack = 0x10;
return (unsigned int) stack;
}
void k_create_process(void (*task)(void))
{
k_cli_irq();
TASK * newtask = (TASK *) k_malloc(sizeof(TASK));
newtask->stack = k_create_stack(task);
newtask->status = STOPPED;
newtask->task = task;
newtask->pid = process.storepid;
k_printf("CREATE PID [%d] STACK: [%d] TASK: [%d]\n", newtask->pid, newtask->stack, newtask->task);
if (process.task == MEMORY_NULL)
{
process.task = newtask;
process.task->next = MEMORY_NULL;
}
else
{
newtask->next = process.task;
process.task = newtask;
}
process.storepid++;
k_sti_irq();
}
void k_enable_schedule_process()
{
process.enable = 1;
}
int k_schedule_process(int context)
{
if (process.task == MEMORY_NULL)
{
return context;
}
if (process.running == MEMORY_NULL)
{
process.running = process.task;
}
else
{
process.running->stack = context;
if (process.running->next != MEMORY_NULL)
{
process.running = process.running->next;
}
else
{
process.running = process.task;
}
}
k_printf("PID %d CONTEXT: %d STACK %d\n", process.running->pid, context, process.running->stack);
return process.running->stack;
}
void k_kill_process(int pid)
{
TASK * index = MEMORY_NULL;
for (index = process.task; index != MEMORY_NULL; index = index->next)
{
if (pid == index->pid)
{
index->status = KILLED;
}
}
}
#endif
Code: Select all
[BITS 32]
extern k_schedule_process
global k_switch_process
k_switch_process:
pusha
push ds
push es
push fs
push gs
mov eax, 0x10
mov ds, eax
mov es, eax
mov fs, eax
mov gs, eax
mov eax, esp
push eax
call k_schedule_process
mov esp, eax
mov al, 0x20
out 0x20, al
pop gs
pop fs
pop es
pop ds
popa
iret
bochs.img