Linux内核的进程切换(上)
2015-08-19 11:30
549 查看
硬件上下文概念
尽管每个进程都可以拥有属于自己的地址空间,但所有进程必须共享CPU寄存器。因此在,在恢复一个进程执行之前,内核必须确保每个寄存器装入了挂起进程时的值。而这些必须装入的寄存器中的数据就称为硬件上下文。任务状态段
80X86体系结构:包括一个特殊的段类型,叫任务状态段(TSS),作用是存放硬件上下文。段是x86的概念,在保护模式下,段选择符参与寻址,段选择符在段寄存器中,而tss段则在tr寄存器中。当进程切换的时候就将
intel的建议:
为每一个进程准备一个独立的tss段,进程切换的时候切换tr寄存器使之指向该进程对应的tss段,然后在任务切换时(比如涉及特权级切换的中断)使用该段保留所有的寄存器。
Linux设计:
Linux内核并没有遵从Itel的建议为每个进程设置一个TSS,而是为每个CPU设置了一个TSS,tr寄存器保存该段。
进程切换 概念篇
按照Intel的设计思路,进程切换的硬件上下文要保存在TSS中,这是可以的,因为每个进程都有TSS,然而Linux中每个CPU有一个TSS,所有进程共享一个TSS,那么切换进程时的硬件上下文保存在哪里呢?答案是进程描述符中。在linux中,进程描述符有一个thread_struct类型的字段thread,只要进程被切换出去,内核就把硬件上下文保存在这个结构里面,这个结构里面包含了大部分的CPU寄存器,但是不不包括eax、ebx等等这些通用寄存器,它们的值放在哪里呢?自然是内核栈中啦!进程切换只发生在内核态,执行切换之前,用户进程使用的所有寄存器保存在内核堆栈中,这也包括ss和esp这对寄存器。小总结:
执行进程切换时,硬件上下文保存在两个地方:
task_struct的thread字段:这里保存了大部分的寄存器,如esp,eip。
内核态堆栈:状态寄存器、通用寄存器,如eax,ebx…
那么现在有个问题,既然Linux既然使用thread_struct保存硬件上下文,为什么要为每个CPU设计一个TSS呢?
理由有二:
当80x86的CPU从用户态切换到内核态时候需要找到内核态堆栈的地址,地址去哪里找呢?就是TSS中。进程切换时,只更新tss段中的esp0/ss0字段,使其指向新进程的内核栈。
当用户态进程师徒通过一个in或者out访问一个端口的时候,CPU需要访问存放在TSS中的I/O许可权位图已检查进程是否有访问端口的权利。
由于进程切换不更换TSS本身,也就是根本不更换TR的内容。这是因为,改变TSS中SS0和ESP0所化的开销比通过装入TR以更换一个TSS要小得多。因此,在Linux内核中,TSS并不是属于某个进程的资源,而是全局性的公共资源。在多处理机的情况下,尽管内核中确实有多个TSS,但是每个CPU仍旧只有一个TSS,并且使用init_tass数组表示多个TSS,如果有N个CPU,那么数组的长度是N。
上述理由说明了在Linux中TSS的作用。到目前为止还有2个问题没有阐述清楚,即进程切换的时候,Linux是如何更新tss的内容的?thread_struct结构体到底长什么样子?下面就来解答这些问题。
执行进程切换
从本质上说,每个进程切换由两步组成:切换页全局目录以安装一个新的地址空间。
切换内核态堆栈和硬件上下文,因为硬件上下文提供了内核执行新进程所需要的所有信息,包括CPU寄存器。
其中第一步是进程地址空间的内容,这里不再描述,有兴趣的可以看深入理解Linux内核的第九章,我们重点关注的是第二步,这步是由switch_to宏执行,切换的具体过程放在下篇介绍吧。
参考文章:
/article/1394960.html
http://oss.org.cn/kernel-book/ch05/5.4.1.htm
相关文章推荐
- Linux 环境进程间通信(六) 套接口
- Linux环境进程间通信(五): 共享内存
- Ubuntu Linux 安装 .7z 解压和压缩文件
- linux查看当前ssh登陆的ip
- Linux各版本内核源码下载地址
- Linux编程C++内存管理之内存分配详解
- Linux环境进程间通信(四) 信号灯
- Linux环境进程间通信(三)消息队列
- Linux环境进程间通信(二): 信号
- 深入理解Linux内核-I/O体系结构和设备驱动程序
- linux下的Source命令的基本功能
- Linux 内存查看
- Linux环境进程间通信(一)
- linux下检查内存泄露的工具--mtrace
- centos为openJDK设置系统变量
- Linux下开机启动sh文件
- CentOS 安装单机性能检测软件 Monitorix
- 深刻理解Linux进程间通信(IPC)
- Linux常用命令/知识
- ps aux命令显示的状态列中的Ss+,Rsl,R+,S<sl含义