哈工大-操作系统-HitOSlab-李治军-实验4-基于内核栈切换的进程切换

实验4-基于内核栈切换的进程切换

实验内容请查看蓝桥云课实验说明,实验的相关知识请查看我的上一篇文章

一、实验内容

1.schedule 与 switch_to

目前 Linux 0.11 中工作的schedule()函数是首先找到下一个进程的数组位置 next,而这个next就是 GDT中的 n,所以这个 next 是用来找到切换后目标 TSS段的段描述符的,一旦获得了这个 next值,直接调用上面剖析的那个宏展开 switch_to(next);就能完成 TSS 切换所示的切换了。

现在,我们不用 TSS进行切换,而是采用切换内核栈的方式来完成进程切换,所以在新的 switch_to 中将用到当前进程的PCB、目标进程的 PCB、当前进程的内核栈、目标进程的内核栈等信息。

因此需要将目前的 schedule() 函数(在 kernal/sched.c 中)做稍许修改,即将下面的代码:

if ((*p)->state == TASK_RUNNING && (*p)->counter > c)
    c = (*p)->counter, next = i; /* i = NR_TASKS ,NR_TASK应该是定义在其他头文件的一个宏?*/

//......

switch_to(next);

修改为:

if ((*p)->state == TASK_RUNNING && (*p)->counter > c)
    c = (*p)->counter, next = i, pnext = *p;

//.......

switch_to(pnext, _LDT(next));

这样,pnext就指向下个进程的PCB

schedule()函数中,当调用函数switch_to(pnext, _LDT(next))时,会依次将参数2 _LDT(next)、参数1 pnext、返回地址 }压栈。

当执行switch_to的返回指令ret时,就回弹出schedule()函数的}执行schedule()函数的返回指令}

2.编写switch_to汇编代码

为了将linux-0.11基于TSS切换内核线程的方式修改成基于PCB的方式,需要将原来放在 (/oslab/linux-0.11/include/linux/sched.h) 的switch_to注释掉,转而直接在 (/oslab/linux-0.11/kernel/system_call.s) 中添加由汇编代码编写的新的switch_to代码

switch_to:
    pushl %ebp
    movl %esp,%ebp
    pushl %ecx
    pushl %ebx
    pushl %eax
    movl 8(%ebp),%ebx
    cmpl %ebx,current
    je 1f
#切换PCB
    movl %ebx,%eax
	xchgl %eax,current
#重写TSS指针
    movl tss,%ecx
    addl $4096,%ebx
    movl %ebx,ESP0(%ecx)
#切换内核栈
    movl %esp,KERNEL_STACK(%eax
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值