Hallo,
ich erweitere meinen Kernel gerade um die Multitaskingfunktion. Dabei bin ich diesem Tutorial gefolgt. Alles funktioniert einwandfrei. Das Problem ist nur folgendes: Sobald Task a gestartet ist und den Bildschirm vollspamt wird kein Interrupt mehr ausgelöst (ausser die Exceptions). Ich verwende zu Testzwecken momentan noch den Tastatur-IRQ zum Schedulen. Aber wenn ich auf eine Taste drücke sollte doch trotzdem ein Interrupt ausgelöst werden oder nicht? Dem PIC wird auch ein EOI gesendet für den richtigen IRQ.
Hier meine pm.c:
ich erweitere meinen Kernel gerade um die Multitaskingfunktion. Dabei bin ich diesem Tutorial gefolgt. Alles funktioniert einwandfrei. Das Problem ist nur folgendes: Sobald Task a gestartet ist und den Bildschirm vollspamt wird kein Interrupt mehr ausgelöst (ausser die Exceptions). Ich verwende zu Testzwecken momentan noch den Tastatur-IRQ zum Schedulen. Aber wenn ich auf eine Taste drücke sollte doch trotzdem ein Interrupt ausgelöst werden oder nicht? Dem PIC wird auch ein EOI gesendet für den richtigen IRQ.
Hier meine pm.c:
Code: [Auswählen]
/*
* pm.c
*
* Created on: 30.12.2012
* Author: pascal
*/
#include "pm.h"
static uint64_t nextPID;
static int64_t currentTask;
static uint64_t numTasks;
static ihs_t *TaskStates[2];
//Testweise
void task_a()
{
asm("sti");
while(1)
printf("A1A");
}
void task_b()
{
asm("sti");
while(1)
printf("B2B");
}
static uint8_t stack_a[4096];
static uint8_t stack_b[4096];
//Ende Test
/*
* Prozessverwaltung initialisieren
*/
void pm_Init()
{
nextPID = 1; // 0 = Kernel
TaskStates[0] = pm_InitTask(stack_a, task_a);
TaskStates[1] = pm_InitTask(stack_b, task_b);
numTasks = 2;
currentTask = -1;
}
/*
* Task initialisieren
* Parameter: stack = Adresse zum Stack des Tasks
* entry = Einsprungspunkt
*/
ihs_t *pm_InitTask(uint8_t *stack, void *entry)
{
/*
* CPU-Zustand für den neuen Task festlegen
*/
ihs_t new_state = {
.cs = 0x08,
.ss = 0x10,
.es = 0x10,
.ds = 0x10,
.gs = 0x10,
.fs = 0x10,
.rip = (uint64_t)entry,
//IRQs einschalten (IF = 1)
.rflags = 0x202
};
ihs_t *state = (void*)(stack + 4096 - sizeof(new_state));
*state = new_state;
state->rsp = (uint64_t)state;
return state;
}
/*
* Scheduler. Gibt den Prozessorzustand des nächsten Tasks zurück. Der aktuelle
* Prozessorzustand wird als Parameter übergeben und gespeichert, damit er
* beim nächsten Aufruf des Tasks wiederhergestellt werden kann.
*/
ihs_t *pm_Schedule(ihs_t *cpu)
{
if(currentTask >= 0)
TaskStates[currentTask] = cpu;
currentTask++;
currentTask %= numTasks;
cpu = TaskStates[currentTask];
return cpu;
}

Übersicht
Wiki
Hilfe
Suche
Einloggen
Registrieren
Drucken


Gespeichert