您的位置:首页 > 其它

一步一步实现一个简单的OS(试验任务切换)

2016-03-12 11:54 363 查看
............

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






内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: