| 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 | + | <c>static uint8_t stack_a[4096]; |
| − | static | + | static uint8_t stack_b[4096]; |
/* | /* | ||
| Zeile 41: | Zeile 41: | ||
* einen Einsprungspunkt. | * einen Einsprungspunkt. | ||
*/ | */ | ||
| − | struct cpu_state* init_task( | + | 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 = ( | + | .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 | + | <c>static uint8_t user_stack_a[4096]; |
| − | static | + | static uint8_t user_stack_b[4096]; |
| − | struct cpu_state* init_task( | + | struct cpu_state* init_task(uint8_t* stack, uint8_t* user_stack, void* entry) |
{ | { | ||
... | ... | ||
| − | .esp = ( | + | .esp = (uint32_t) user_stack + 4096, |
| − | .eip = ( | + | .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 | + | <c>static uint32_t tss[32] = { 0, 0, 0x10 }; |
... | ... | ||