linux 内核的 switch_to原理

switch_to:这是一个宏,有三个参数prev,next,last

局部变量prev,next:指向进程描述符的内存地址

首先明确的是:last和prev是同一个,用last只是为了理解方便,完全可以用两个参数prev,next。因为last就是prev

switch_to宏用于进程切换,给定了前一个进程结构体指针prev,以及需要切换到的进程结构体指针next,从prev切换到next.
但是,实际上,switch_to宏有三个参数,除了上面说的两个参数之外,还有一个last参数.而且使用switch_to宏的时候传入的prev和last都是同一个值,比如会这么调用这个宏:
switch_to(prev,next,prev).

这是为什么呢?

考虑一种场景,进程A切换到进程B,因为每个进程的空间是不同的,所以在切换之前,进程A的空间里prev=A,next=B,last=A.
一段时间之后,需要切换回到进程A,假设当前进程是C,那么对于C而言prev=C,next=A,last=C.

对比前后两种场景:
进程A切换前:prev=A,next=B,last=A
进程C切换前:prev=C,next=A,last=C

这时开始从进程C切换到进程A,注意到在切换之前switch_to宏将prev存放到了eax寄存器中,也就是在进程C切换到进程A之前,eax=C
切换之后,很显然,来到了进程A的空间,因此prev,next,last指针要回到进程A被切换出去之前的指向,因此prev=A,next=B,last=A,而eax的数据保持不变(这是在eax的内容覆盖A进程的堆栈的prev之前的情况)
在switch_to宏返回之前,将eax寄存器的数据存放到last中,因此,last=eax=C,其实也就是prev=C

注意,在宏里面,出现last的地方实质上就是prev。

当从C转回A的时候,A怎么知道它的上一个进程是哪一个呢?
    为了使你好理解,现在做如下假设:
    加入没有last这个参数,那么switch变成:switch_to(prev, next);
     这时候返回A进程后,prev指向它自己,next指向B,那么如何知道A的上一个进程是谁呢?就是不能够获取C的描述符。
    这时候我们加上last,switch_to(prev, next, prev);,最后一个参数是一个输出参数,那么当switch_to执行完毕后,prev就会变成进程C的描述符。
    这是通过movl %eax, last来实现的。
    关键的一点来了,为什么这个eax存的是C的描述符呢,这是由于在从C->A中的时候,movl prev, %eax,这个prev就是C。

我个人认为这样做是为了便于理解,不然的话,switch_to(prev, next);也可以实现上述功能,直接把prev这个参数即当输入参数,又当输出参数就可以了。

时间: 2024-08-24 13:19:44

linux 内核的 switch_to原理的相关文章

linux内核分析———SLAB原理及实现

linux内核分析---SLAB原理及实现 Slab原理及实现 1. 整体关系图 ! 注:SLAB,SLOB,SLUB都是内核提供的分配器,其前端接口都是一致的,其中SLAB是通用的分配器,SLOB针对微小的嵌入式系统,其算法较为简单(最先适配算法),SLUB是面向配备大量物理内存的大规模并行系统,通过也描述符中未使用的字段来管理页组,降低SLUB本身数据结构的内存开销. 2. 相关数据结构 2.1 缓存kmem_cache (/mm/slab.c) struct kmem_cache { st

《Linux内核分析》期中总结

                             <Linux内核分析>期末总结                                                                            20135109 高艺桐 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000  一.博客地址汇总 第一周学习笔记计算机是如何工作的 第二周学习笔记深入理解计算机 第三

2017-2018-1 20179205《Linux内核原理与设计》第九周作业

<Linux内核原理与设计>第九周作业 视频学习及代码分析 一.进程调度时机与进程的切换 不同类型的进程有不同的调度需求,第一种分类:I/O-bound 会频繁的进程I/O,通常会花费很多时间等待I/O操作的完成:CPU-bound 是计算密集型,需要大量的CPU时间进行运算,使得其他交互式进程反应迟钝,因此需要不同的算法来使系统的运行更高效,以及CPU的资源最大限度的得到使用.第二种分类包括批处理进程(batch process):实时进程(real-time process)以及交互式进程

Linux内核设计第一周 ——从汇编语言出发理解计算机工作原理

Linux内核设计第一周 ——从汇编语言出发理解计算机工作原理 作者:宋宸宁(20135315) 一.实验过程 图1 编写songchenning5315.c文件 图2 将c文件汇编成32位机器语言 图3 将.s文件中的链接语句删除,获得最后的汇编代码 二.分析堆栈变化情况 三.总结 阐明对“计算机是如何工作的”的理解. ①计算机是依据冯诺依曼体存储结构,依据其核心思想——存储程序计算机工作模型,按程序编排的顺序,一步一步地取出指令,自动地完成指令规定的操作. ②从硬件的角度看,是通过总线连接C

Linux内核设计(第二周)——操作系统工作原理

Linux内核设计(第二周)--操作系统工作原理 by苏正生 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.学习笔记总结 1.函数调用堆栈 (1).函数调用堆栈. 堆栈是C语言程序运行时必须的一个记录调用路径和参数的空间. cpu内部已经集成好的功能,pop,push,enter-- 函数调用构架 传递参数,通过堆栈 保存返回值,%eax 提供局部变量空间 -- C语言编译器对堆栈

Linux内核设计(第一周)——从汇编语言出发理解计算机工作原理

Linux内核设计(第一周)--从汇编语言出发理解计算机工作原理 计算机工作原理 汇编指令 C语言代码汇编分析 by苏正生 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 从2月22日起,本学期的linux课程开始了.通过这两天的学习,觉得孟宁老师讲的真不错,条理清晰,举例适当.本周从计算机工作原理出发,回顾了冯诺依曼计算机结构,也回顾了汇编寄存器.汇编指令.C语言程序的汇编分析技巧,很

linux内核奇遇记之md源代码解读之十五bitmap原理

转载请注明出处:http://blog.csdn.net/liumangxiong 为人不识陈近南,走遍江湖也枉然.做raid不识bitmap,通通都是走过场. 那么bitmap究竟是何许人物,能够在raid5的场子里混得风生水起呢?话说最早raid5是没有bitmap这位门客的,突然有一天跑raid5的系统异常掉电了,客户发现异常掉电之后再写数据就出现了数据不一致的情况.查来查去发现raid5本身设计就有一个缺陷:raid5每次写至少要写两个磁盘,写过程中异常掉电的时候就会发现一个磁盘写完成而

20169217 《Linux内核原理与分析》 第十一周作业

首先更新一下第一次实验关于堆栈的分析,这里我直接手写拍的图片. 这里再补充一点,第5步的call f 实际上等于 pushl %eip,movl f %eip,也就是将f的eip地址压栈,call g原理相同.leave等于movl %ebp,%esp,popl %ebp 也就是将ebp出栈,epb指向自己所存储值的栈,再将ebp的值付给esp,实现栈的释放.   接下来是实验: 2014年9月24日,Bash中发现了一个严重漏洞shellshock,该漏洞可用于许多系统,并且既可以远程也可以在

Linux内核原理-pid namespace

前言 这几晚在看进程相关的内核原理,正好看到了pid这块,看起来不是很复杂,但是引入了pid namespace后增加了一些数据结构,看起来不是那么清晰了,参考了Linux内核架构这本书,看完后感觉还没有理解.所以就在网上找了一些文章参考,其中我发现了一篇质量相当不错的文章,为什么说质量不错呢主要是因为笔者在博文中并没有乱贴代码一桶,也没有按照常规的代码分析,而是以一种追踪溯源的方法还原了整个pid的框架,读了这篇文章后感觉甚好,因此有了本文,本文算不上原创,只是在此基础上将自己的理解重新进行了