Autor Thema: Multitasking: Task wird nicht gewechselt  (Gelesen 2131 mal)

OsDevNewbie

  • Beiträge: 282
    • Profil anzeigen
    • YourOS Kernel
Gespeichert
« am: 30. December 2012, 19:02 »
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:
/*
 * 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;
}
Viele Grüsse
OsDevNewbie

Ein Computer ohne Betriebsystem ist nicht mehr wert als ein Haufen Schrott.
Ein Computer ist eine Maschine, die einem Lebewesen das kostbarste klaut, was sie selber nicht hat:
DIE ZEIT DES LEBENS

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 30. December 2012, 19:16 »
Du musst nach jedem Tastaturinterrupt den Tastaturpuffer (I/O-Port 0x60) auslesen, sonst werden keine weiteren Interrupts von der Tastatur ausgelöst. Außerdem musst du (wie auch beim Timerinterrupt) den Interrupt beim PIC bestätigen.
Dieser Text wird unter jedem Beitrag angezeigt.

OsDevNewbie

  • Beiträge: 282
    • Profil anzeigen
    • YourOS Kernel
Gespeichert
« Antwort #2 am: 30. December 2012, 23:02 »
ah danke das habe ich vergessen, das mit dem Tastaturbuffer. Es funktioniert jetzt.
Viele Grüsse
OsDevNewbie

Ein Computer ohne Betriebsystem ist nicht mehr wert als ein Haufen Schrott.
Ein Computer ist eine Maschine, die einem Lebewesen das kostbarste klaut, was sie selber nicht hat:
DIE ZEIT DES LEBENS

 

Einloggen