............
extern void swtch(struct context *old, struct context *new);
struct context kmainContext; // 内核任务
struct context testContext0; // 任务0
struct context testContext1; // 任务1
// 任务0堆栈
uchar stack0[4096];
// 任务1堆栈
uchar stack1[4096];
void test0();
void test1();
/**
* 内核入口
*/
int kmain()
{
..........
// 上下文切换
// 初始化各任务上下文
testContext0.eip = (uint)test0;
testContext0.esp = (uint)stack0 + 4096;
testContext1.eip = (uint)test1;
testContext1.esp = (uint)stack1 + 4096;
// 由kmain,切换到test0
// 这个只是做一个测试,就不加特权级了。
// 这样看起来简单写
// 咱以后的进程切换就用这个
swtch(&kmainContext, &testContext0);
for(;;);
}
void test0()
{
while(1){
printf("A");
swtch(&testContext0, &testContext1);
printf("a");
}
}
void test1()
{
while(1){
printf("B");
swtch(&testContext1, &testContext0);
printf("b");
}
}
# void swtch(struct context *old, struct context *new);
# 切换进程上下文
.globl swtch
swtch:
# 旧的寄存器地址
movl 4(%esp), %eax
popl 0(%eax) # 保存旧的EIP(返回地址)
movl %esp, 4(%eax) # 保存esp
movl %ebx, 8(%eax) # 保存ebx
movl %ecx, 12(%eax) # 保存ecx
movl %edx, 16(%eax) # 保存edx
movl %esi, 20(%eax) # 保存esi
movl %edi, 24(%eax) # 保存edi
movl %ebp, 28(%eax) # 保存ebp
# 新的寄存器地址
movl 4(%esp), %eax
movl 28(%eax), %ebp # 载入ebp
movl 24(%eax), %edi # 载入edi
movl 20(%eax), %esi # 载入esi
movl 16(%eax), %edx # 载入edx
movl 12(%eax), %ecx # 载入ecx
movl 8(%eax), %ebx # 载入ebx
movl 4(%eax), %esp # 载入esp
pushl 0(%eax) # 载入新的EIP(返回地址)
ret