Hardware-Multitasking — Änderungen 8861 → 8930

Zeile 20: Zeile 20:
 
gdt_create_descriptor (
 
gdt_create_descriptor (
 
n, //die Nummer des Descriptor-Eintrags
 
n, //die Nummer des Descriptor-Eintrags
−
(DWORD) &task_state_segment, //Adresse
+
(uint32_t) &task_state_segment, //Adresse
 
sizeof(struct tss)-1, //Länge
 
sizeof(struct tss)-1, //Länge
 
0, //flags
 
0, //flags
Zeile 74: Zeile 74:
  
 
struct tss task_state_segments[NUM_TASKS];
 
struct tss task_state_segments[NUM_TASKS];
−
DWORD stacks[NUM_TASKS * 7]; // (1)
+
uint32_t stacks[NUM_TASKS * 7]; // (1)
  
 
/*** Hilfsfunktionen ***/
 
/*** Hilfsfunktionen ***/
  
−
void create_task ( DWORD n, //die ID/Nummer des Tasks
+
void create_task ( uint32_t n, //die ID/Nummer des Tasks
−
WORD cs, WORD ss, WORD ds,
+
uint16_t cs, uint16_t ss, uint16_t ds,
−
DWORD adr_code, DWORD adr_stack)
+
uint32_t adr_code, uint32_T adr_stack)
 
{
 
{
 
   if(n > NUM_TASKS) return;
 
   if(n > NUM_TASKS) return;
Zeile 90: Zeile 90:
 
   task_state_segments[n].eflags = 0x1600; // (4)
 
   task_state_segments[n].eflags = 0x1600; // (4)
 
   task_state_segments[n].ss0 = 0x10; // (2)
 
   task_state_segments[n].ss0 = 0x10; // (2)
−
   task_state_segments[n].esp0 = (DWORD) &stacks[n*7]; // (3)
+
   task_state_segments[n].esp0 = (uint32_t) &stacks[n*7]; // (3)
 
}
 
}
 
</c>
 
</c>
Zeile 110: Zeile 110:
 
     gdt_create_descriptor (
 
     gdt_create_descriptor (
 
i+TSS_SEL_BASE,
 
i+TSS_SEL_BASE,
−
(DWORD) &task_state_segment[i],
+
(uint32_TD) &task_state_segment[i],
 
sizeof(struct tss)-1,
 
sizeof(struct tss)-1,
 
0,
 
0,
Zeile 125: Zeile 125:
 
struct task
 
struct task
 
{
 
{
−
   BYTE present;
+
   uint8_t present;
−
   BYTE priority;
+
   uint8_t priority;
 
}__attribute__((packed));
 
}__attribute__((packed));
  
Zeile 144: Zeile 144:
  
 
<c>
 
<c>
−
DWORD current_task_id=0;
+
uint32_t current_task_id=0;
−
WORD tss_sel;
+
uint16_t tss_sel;
 
void scheduler()
 
void scheduler()
 
{
 
{
Zeile 157: Zeile 157:
 
}
 
}
 
</c>
 
</c>
−
Jetzt muss zu diesem Task geswechselt werden, indem zu dessen TSS-Selektor gesprungen wird. Es empfiehlt sich diesen Teil in Assembler zu schreiben, da die ISR auch aus einem Assemblerstub heraus aufgerufen werden sollte. Dieser sieht dann so aus:
+
Jetzt muss zu diesem Task gewechselt werden, indem zu dessen TSS-Selektor gesprungen wird. Es empfiehlt sich diesen Teil in Assembler zu schreiben, da die ISR auch aus einem Assemblerstub heraus aufgerufen werden sollte. Dieser sieht dann so aus:
  
 
<asm>
 
<asm>
Zeile 214: Zeile 214:
  
 
Wie bereits erwähnt ist es möglich, auch das Scheduling zum Teil von der Hardware ausführen zu lassen. Dafür muss man den PIT-Interrupt als Task-Gate anlegen, die auf das TSS des nächsten Tasks zeigt. Dadurch wechselt die CPU automatisch zum nächsten Task.
 
Wie bereits erwähnt ist es möglich, auch das Scheduling zum Teil von der Hardware ausführen zu lassen. Dafür muss man den PIT-Interrupt als Task-Gate anlegen, die auf das TSS des nächsten Tasks zeigt. Dadurch wechselt die CPU automatisch zum nächsten Task.
−
Dann setzt man Bit 0 im letzten DWORD jeder TSS (Debug-Trap-Bit), wodurch jedes mal eine Debugexception nach einem Task-Swich ausgelöst wird, in der man dann das Task-Gate auf den nächsten Task zeigen lässt.
+
Dann setzt man Bit 0 im letzten DWord jeder TSS (Debug-Trap-Bit), wodurch jedes mal eine Debugexception nach einem Task-Switch ausgelöst wird, in der man dann das Task-Gate auf den nächsten Task zeigen lässt.
 
Diese Methode ist allerdings sehr kompliziert, man kommt dennoch nicht um etwas Software-Scheduling herum, und ausprobiert habe ich es auch noch nicht.
 
Diese Methode ist allerdings sehr kompliziert, man kommt dennoch nicht um etwas Software-Scheduling herum, und ausprobiert habe ich es auch noch nicht.