Teil 6 - Multitasking — Änderungen 6460 → 7127

Zeile 33: Zeile 33:
  
 
Legen wir also einmal den Startzustand für die beiden Tasks fest, jeder bekommt seinen Stack und dort drin eine struct cpu_state:
 
Legen wir also einmal den Startzustand für die beiden Tasks fest, jeder bekommt seinen Stack und dort drin eine struct cpu_state:
−
<c>static char stack_a[4096];
+
<c>static uint8_t stack_a[4096];
−
static char stack_b[4096];
+
static uint8_t stack_b[4096];
  
 
/*
 
/*
Zeile 41: Zeile 41:
 
  * einen Einsprungspunkt.
 
  * einen Einsprungspunkt.
 
  */
 
  */
−
struct cpu_state* init_task(char* stack, void* entry)
+
struct cpu_state* init_task(uint8_t* stack, void* entry)
 
{
 
{
 
     /*
 
     /*
Zeile 55: Zeile 55:
 
         .ebp = 0,
 
         .ebp = 0,
 
         //.esp = unbenutzt (kein Ring-Wechsel)
 
         //.esp = unbenutzt (kein Ring-Wechsel)
−
         .eip = (unsigned long) entry,
+
         .eip = (uint32_t) entry,
  
 
         /* Ring-0-Segmentregister */
 
         /* Ring-0-Segmentregister */
Zeile 157: Zeile 157:
 
Aber fangen wir beim leichten Teil an. Stellen wir den Taskzustand auf Ring 3 um. Dazu brauchen wir jetzt zusätzlich zum Kernelstack jedes Tasks, der für den Prozessorzustand und die Ausführung der Interrupt-Handler benutzt wird, einen zweiten getrennten Stack für jeden Task, auf dem dieser beliebig arbeiten kann. Außerdem benutzen wir jetzt die Ring-3-Segmente aus der GDT:
 
Aber fangen wir beim leichten Teil an. Stellen wir den Taskzustand auf Ring 3 um. Dazu brauchen wir jetzt zusätzlich zum Kernelstack jedes Tasks, der für den Prozessorzustand und die Ausführung der Interrupt-Handler benutzt wird, einen zweiten getrennten Stack für jeden Task, auf dem dieser beliebig arbeiten kann. Außerdem benutzen wir jetzt die Ring-3-Segmente aus der GDT:
  
−
<c>static char user_stack_a[4096];
+
<c>static uint8_t user_stack_a[4096];
−
static char user_stack_b[4096];
+
static uint8_t user_stack_b[4096];
  
−
struct cpu_state* init_task(char* stack, char* user_stack, void* entry)
+
struct cpu_state* init_task(uint8_t* stack, uint8_t* user_stack, void* entry)
 
{
 
{
  
 
...
 
...
  
−
         .esp = (unsigned long) user_stack + 4096,
+
         .esp = (uint32_t) user_stack + 4096,
−
         .eip = (unsigned long) entry,
+
         .eip = (uint32_t) entry,
  
 
         /* Ring-3-Segmentregister */
 
         /* Ring-3-Segmentregister */
Zeile 193: Zeile 193:
 
Als nächstes legen wir das TSS an. Der Aufbau wird im Artikel [[Task State Segment]] beschrieben, wir brauchen davon nur die Felder esp0 und ss0. ss0 können wir konstant auf unser Ring-0-Datensegment setzen, esp0 muss für jeden Task angepasst werden.
 
Als nächstes legen wir das TSS an. Der Aufbau wird im Artikel [[Task State Segment]] beschrieben, wir brauchen davon nur die Felder esp0 und ss0. ss0 können wir konstant auf unser Ring-0-Datensegment setzen, esp0 muss für jeden Task angepasst werden.
  
−
<c>static unsigned long tss[32] = { 0, 0, 0x10 };
+
<c>static uint32_t tss[32] = { 0, 0, 0x10 };
  
 
...
 
...