linux进程切换分析,Linux2.6进程切换经典分析

本文档详细介绍了linux2.6中的进程切换schdule()的执行过程,对于内核初学者是一个好的入门资料,对于开发人员来讲也是一个不错的参考资料,好不好大家自己看看吧!

Linux内核进程切换

本文主要参考了Understanding The Linux Kernel 和水木精华区的分析进程切换宏 switch_to 。感谢相关的作者!本文中有部分内容直接从上面提到的文章中重复,仅仅是为了方便大家阅读。本文中提到的所有内核代码可以到Linux Cross Reference上查阅。欢迎转载本文,转载请保留这份声明。

本文仅讨论内核进程的切换,而不涉及进程的调度算法。详细讲了switch_to这个宏。 文中涉及到的Linux内核源码,如没有特别指出,均指2.6.26版本的源码。

首先简单提一下这个宏和函数的被调用关系:

schedule() --> context_switch() --> switch_to --> __switch_to()

这里面,schedule是主调度函数,涉及到一些调度算法,这里不讨论。当schedule()需要暂停A进程的执行而继续B进程的执行时,就发生了进程之间的切换。进程切换主要有两部分:1、切换全局页表项;2、切换内核堆栈和硬件上下文。这个切换工作由context_switch()完成。其中switch_to和__switch_to()主要完成第二部分。更详细的,__switch_to()主要完成硬件上下文切换,switch_to主要完成内核堆栈切换。

阅读switch_to时请注意:这是一个宏,不是函数,它的参数prev, next, last不是值拷贝,而是它的调用者context_switch()的局部变量。局部变量是通过%ebp寄存器来索引的,也就是通过n(%ebp),n是编译时决定的,在不同的进程的同一段代码中,同一局部变量的n是相同的。在switch_to中,发生了堆栈的切换,即ebp发生了改变,所以要格外留意在任一时刻的局部变量属于哪一个进程。关于__switch_to()这个函数的调用,并不是通过普通的call来实现,而是直接jmp,函数参数也并不是通过堆栈来传递,而是通过寄存器来传递。 在下文中提到一些局部变量和寄存器值,为了不引起混淆,在名字后面加上_X,表示是X进程的成员。如esp_A表示进程A的esp的值,prev_B,表示进程B中的prev变量,等等。

switch_to切换主要有以下三部分:

1-99-jpg_6_0_______-642-0-0-642.jpg

上面的四个步骤中,有三个是在switch_to宏中完成,硬件上下文切换由__switch_to()函数完成。

下面来具体看switch_to从A进程切换到B进程的步骤。

step1:复制两个变量到寄存器:

[prev] "a" (prev)

[next] "d" (next)

即:

eax <== prev_A 或 eax <==%p(%ebp_A)

edx <== next_A 或 edx <==%n(%ebp_A)

这里prev和next都是A进程的局部变量。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值