1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
// http://hosted.cjmovie.net/TutMultitask.htm
//
//
#include "kernel.h"
#include "../lib/logger/log.h" // logger facilities
#define FOOLOS_MODULE_NAME "task"
int started;
void task_test1()
{
uint16_t c1;
while(1)
{
c1++;
asm("cli");
PutString("task1: %03d", 0,560,0xffffff, c1/100);
asm("sti");
}
}
void task_test2()
{
uint16_t c2;
while(1)
{
c2++;
asm("cli");
PutString("task2: %03d", 0,580,0xffffff, c2/100);
asm("sti");
}
}
//////////////
//
typedef struct{ //Simple structure for a thread
unsigned int esp0; //Stack for kernel
unsigned int esp3; //Stack for process
} Thread;
Thread Threads[2]; //Space for our simple threads. Just 2!
int CurrentTask = -1; //The thread currenlty running (-1 == none)
void task_create(int pid,void(*thread)())
{
unsigned int *stack;
Threads[pid].esp0 = pmmngr_alloc_block();
stack = (unsigned int*)Threads[pid].esp0+4000; //This makes a pointer to the stack for us
log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"new task : stack: 0x%08X ", stack);
//First, this stuff is pushed by the processor
*--stack = 0x0202; //This is EFLAGS
*--stack = 0x08; //This is CS, our code segment
*--stack = (uint32_t)thread; //This is EIP
//Next, the stuff pushed by 'pusha'
*--stack = 0; //EDI
*--stack = 0; //ESI
*--stack = 0; //EBP
*--stack = 0; //Just an offset, no value
*--stack = 0; //EBX
*--stack = 0; //EDX
*--stack = 0; //ECX
*--stack = 0; //EAX
//Now these are the data segments pushed by the IRQ handler
/*
*--stack = 0x10; //DS
*--stack = 0x10; //ES
*--stack = 0x10; //FS
*--stack = 0x10; //GS
*/
Threads[pid].esp0 = (uint32_t)stack; //Update the stack pointer
};
uint32_t task_switch_next(uint32_t oldesp)
{
if(started!=0xabcde) return oldesp;
if(CurrentTask != -1){ //Were we even running a task?
Threads[CurrentTask].esp0 =oldesp; //Save the new esp for the thread
//Now switch what task we're on
if(CurrentTask == 0)CurrentTask = 1;
else CurrentTask = 0;
} else{
CurrentTask = 0; //We just started multi-tasking, start with task 0
}
uint32_t esp=0;
log(FOOLOS_MODULE_NAME,FOOLOS_LOG_FINE,"oldesp: 0x%08X saved / next task: %d (esp: 0x%08X) ",oldesp, CurrentTask,Threads[CurrentTask].esp0);
return Threads[CurrentTask].esp0; //Return new stack pointer to ASM
}
void stack_trace(uint32_t *stack,int size)
{
for(int i=size;i>=0;i--)
{
log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"stack: 0x%08X -> 0x%08X", stack, *stack);
stack++;
}
}
void task_init()
{
log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"init multitasking.");
task_create(0,task_test1);
task_create(1,task_test2);
started=0xabcde;
}
|