转自:http://blog.chinaunix.net/uid-587665-id-2732907.html



【0】写在前面

  • segment descriptors 构建保护模式下的最基本、最根本的执行环境。system descriptors 则构建保护模式下的核心组件:

  • 1、TSS descriptor 提供硬件级的进程切换机制

  • 2、LDT descriptor 供进程使用多个 descriptor
  • 3、Gate descriptor 提供 processor 权限级别的切换机制。

5.7.1、 TSS 提供的进程切换机制

  • TSS 是一段内存区域,存放进程相关的执行环境信息。初始化的 TSS 是由用户提供,进程切换时的保存信息由 processor 执行。

5.7.1.1、 三个元素构成 TSS 环境:

  • 1、 TSS descriptor:这个 descriptor 属于 system descriptor 类型,它的 S (system)位是 0。

    下面列出 TSS descriptors 的类型值:

    0001:  16-bit TSS
    0011: busy 16-bit TSS
    1001:  32-bit TSS
    1011: busy 32-bit TSS
    

      以上是 x86 下的 TSS descriptor 类型,分为 16 和 32 位 TSS,x64 的 long mode 下 32 位的 TSS descriptor 将变为 64 位 TSS descriptor。

  • 情景提示:

  • 关于 TSS 的 busy 与 available 状态:

    • 1、 TSS descriptor 的类型指明是 busy 与 available 状态。
    • 2、 TSS descriptor 的 busy 与 available 状态由 processor 去控制。即:由 processor 置为 busy 或 avaibable。 除了初始的 TSS descriptor 外。
    • TSS 的 busy 状态主要用来支持任务的嵌套。TSS descriptor 为 busy 状态时是不可进入执行的。同时防止 TSS 进程切换机制出现递归现象。
  • 2、 TSS selector 以及 TR(Task Register)寄存器

    • TR 寄存器的结构与 segment registers 是完全一致的,即:由软件可见的 selector 部分与 processor 可见的隐藏部分(信息部分)构成。

    • TR.selector 与 CS.selector 中的 selector 意义是完全一样的。其 descriptor 的加载也是一样的。

    • 即: TR.selector 在 GDT / LDT 中索引查找到 TSS descriptor 后,该 TSS descriptor 将被加载到 TR 寄存的隐藏部分。当然在加载到 TR 寄存器之前,要进行检查通过了才可加载到 TR 寄存器。若加载 non-TSS descriptor 进入 TR 则会产生 #GP 异常。

  • 3、 TSS 块(Task Status Segment)

    • 像 code segment 或 data segments 一样,最终的 TSS segment 由 TSS descriptor 来决定。 TSS descriptor 指出 TSS segment 的 base、limit 及 DPL 等信息。

    • TSS segment 存放 eflags 寄存器、GPRs 寄存器及相关的权限级别的 stack pointer (ss & sp)、CR3 等等信息。

5.7.1.2、 TSS 机制的建立

  • 对于多任务 OS 来说,TSS segment 是必不可少的,系统至少需要一个 TSS segment,但是现在的 OS 系统不使用 TSS 机制来进行任务的切换。

  • 情景提示:

    • TSS 存在的唯一理由是:需要提供 0 ~ 2 权限级别的 stack pointer,当发生 stack 切换时,必须使用 TSS 提供的相应的 stack pointer。
    • 但是:若提供空的 TSS segment,或者可以考虑以直接传递 stack pointer 的方式实现 stack 切换,即便是这样设计 processor 要读取 TSS segment 这一工作是必不可少的。
  • 下面的指令用来建立初始的 TSS segment:

    • LTR word ptr [TSS_Selector] /* 在 [TSS_selector] 提供 TSS selector */
      或:LTR ax /* 在 ax 寄存器里提供 TSS selector */

    • ltr 指令使用提供的 selector 在 GDT / LDT 里索引查找到 TSS descriptor 后,加载到 TR 寄存器里。初始的 TSS descriptor 必须设为 available 状态,否则不能加载到 TR。processor 加载 TSS descriptor 后,将 TSS descriptor 置为 busy 状态。

5.7.1.3、 TSS 进程切换的过程

  • 当前进程要切换另一个进程时,可以使用 2 种 selector 进行:使用 TSS selector 以及 Task gate selector(任务门符)。

    call 0x2b:0x00000000          /* 假设 0x2b 为 TSS selector */
    call 0x3b:0x00000000          /* 假设 0x3b 为 Task-gate  selector */
    
  • TSS 提供的硬件级进程切换机制较为复杂,大多数 OS 不使用 TSS 机制,是因为执行的效能太差了。上面的两条指令的 TSS 进程切换的过程如下:

  • 1、使用 TSS selector
      call 0x2b:0x00000000 /* 0x2b 为 TSS selector */
      这里使用 jmp 指令与 call 指令会有些差别,call 允许 TSS 进程切换的嵌套,jmp 不允许嵌套。

    • (1)processor 使用 TSS selector (0x2b) 在 GDT 索引查找第 5 个 descriptor

    • (2)processor 检查找到的 descriptor 类型是否是 TSS descriptor,不是的话将产生 #GP 异常。是否为 available TSS,若目标 TSS descriptor 是 busy 的话,同样将产生 #GP 异常。

    • (3)processor 进行另一项检查工作:权限的检查,CPL <= DPL 并且 selector.RPL <= DPL 即为通过,否则产生 #GP 异常。

    • (4)当前进程的执行环境被保存在当前进程的 TSS segment 中。

    • 情景提示:
        在这一步里,此时还没发生 TSS selector 切换,processor 把当前进程的环境信息保存在当前的 TSS segment 中。

    • (5)这里发生了 TSS selector 切换。新的 TSS selector 被加载到 TR.selector,而新的 TSS descriptor 也被加载到 TR 寄存的隐藏部分。

    • 情景提示:

      • (1)这里,processor 还要将旧的 TSS selector 保存在当前的 TSS segment(新加载的 TSS)中的 link 域。这个 TSS segment 中的 link 其实就是 old TSS selector 域,用来进程返回时获得原来的 TSS selector 。从而实现任务的嵌套机制。
      • (2)processor 将当前 eflags 寄存器的 NT(Nest Task)标志位置为 1,表明当前的进程是嵌套内层。
    • (6)processor 从当前的 TSS segment 取出新进程的执行环境,包括:各个 selector registers(segment registers)、GPRs、stack pointer (ss & sp)、CR3 寄存器以及 eflags 寄存器等。

    • 在这一步,在加载 selectors 进入 segment registers 之前,还必须经过相关的 selector & descriptor 的常规检查以及权限检查。通过之后才真正加载。否则同样产生 #GP 异常。

    • 情景提示:

      • processor 还要做另一项工作,就是:将新进程的 TSS descriptor 置为 busy 状态。使得新进程不能重入。
    • (7)processor 从当前的 CS:RIP 继续往下执行,完成这个 TSS 进程的切换。这个 CS: RIP 就是新加载的新进程的 cs : rip


  • 从上面的过程可以看出,使用 TSS 进程切换机制异常复杂,导致进程切换的效能太差了。比使用 call gate 以及 trap gate 慢上好多。若当中发生权限的改变,还要发生 stack 切换。
  • 进程的返回同样复杂。同样需要这么多步骤,总结来说,主要的时间消耗发生在新旧进程的信息保存方面。

  • 2、 使用 task gate selector

    • 另一种情况是使用 task gate selector 进行 TSS 进程切换,使用 task gate selector 除了可以 call/jmp 外,还可用在中断机制上,下面的两种情况:

        call 0x3b:0x00000000 /* 0x3b 为 task gate selector */
      或:int 0x3e /* 假设 0x3e 是 task gate 的向量 */

    • 这两种情形差不多,除了一些细微的差别外,不过是触发的机制不同而已。

    • processor 在 GDT 索引查找到的是一个 task gate descriptor,这个 task gate descriptor 中指出了目标的 TSS selector 。processor 从 task gate descriptor 里加载 TSS selector,剩下的工作和使用 TSS selector 进行切换进程是一致。

    • processor 访问 task gate descriptor 仅需对 task gate descriptor 作出权限检查:CPL <= DPL 并且 RPL <= DPL。在这里不需要作出对 TSS descriptor 的 DPL 权限进行检查。

    • gate descriptor 机制提供了一层间接的访问层,主要用来控制权限的切换。

  • 实际上:

    • 对于 call 0x2b:0x00000000 这条指令,processor 并不知道这个 selector 是 TSS selector 还是 task gate selector,在查找到 descriptor 后,processor 查看这个 descriptor 的 type 才能确定是 TSS selector 还是 task gate selector。
  • 最后需注意:

    • (1)使用 jmp 指令进行转移,processor 不会将 eflags 中 NT 标志位置 1
    • (2)使用中断机制下的 TSS 进程切换,processor 将不作任务的权限检查动作。

5.7.1.4、 TSS 进程的返回

  • 从 TSS 机制切换的进程在执行完后使用 iret 指令返回原进程进,同样会发生新旧 TSS segment 的更新动作。

  • 进程通过使用 ret 返回时,processor 将不会从嵌套内层返回到的嵌套外层进程,也就是不会返回原进程。processor 对 ret 指令的处理,只会从 stack pointer(ss : esp) 取返回地址。

  • 对于使用进程使用了 iret 中断返回指令时:
    • (1)processor 将会检查当前的 eflags.NT 标志位是否为 1,也就是检查当前进程是否处于嵌套的内层。
    • (2)eflags.NT = 1,processor 将从当前 TSS segment 中的 link(old TSS selector)域中取出原来进程的 TSS selector。
    • (3)processor 将不作任何的权限检查,TSS selector 被加载到 TR.selector,TSS descriptor 同时被加载到 TR 的隐藏部分。
    • (4)processor 将清除当前的 eflags.NT 为 0。若是使用 ret 指令返回的,processor 是不会清 eflags.NT 为 0
    • (5)从 TSS segment 中加载新的进程执行环境,从新的 CS:EIP 处继续执行。 将原来的 TSS descriptor 重新置为 available 状态,使得可以再次进入。

    • 由上可得,processor 遇到 ret 指令时,是不会对 eflags.NT 进行检查的。而使用 iret 指令,processor 将对 eflags.NT 进行检查。

x86 的 TSS 任务切换机制相关推荐

  1. Spark之Master主备切换机制原理

    Spark之Master主备切换机制原理

  2. 达梦数据库实时主备集群的同步机制和切换机制

    DM数据守护介绍 1. DM 数据守护(Data Watch) 是一种集成化的高可用.高性能数据库解决方案,是数据库异地容灾的首选方案.通过部署 DM 数据守护,可以在硬件故障(如磁盘损坏).自然灾害 ...

  3. Qt编写输入法源码V2019,未采用Qt系统层输入法框架,独创输入切换机制

    Qt编写输入法源码V2019 未采用Qt系统层输入法框架,独创输入切换机制. 纯QWidget编写,支持任何目标平台(亲测windows.linux.嵌入式linux等),支持任意Qt版本(亲测Qt4 ...

  4. NR BWP切换机制,切换时延

    目录 1. BWP概述 2. BWP切换机制 RRC based BWP切换 Timer based BWP切换 DCI based BWP切换 3. BWP切换时延 1. BWP概述 在之前的博客h ...

  5. 【中继协助频谱切换】基于中继协助的频谱切换机制的MATLAB仿真

    1.软件版本 MATLAB2013b 2.本算法理论知识 在认知无线电网络(Cognitive Radio Network,简称CRN)中引入协作通信可以提高系统的分集增益.CRN中,协作通信的模式主 ...

  6. f5双机配置_F5负载均衡器双机切换机制及配置

    文档来源为 : 从网络收集整理 .word 版本可编辑 . 欢迎下载支持 . 1 F5 负载均衡器双机切换触发机制及配置 1 F5 双机的切换触发机制 1.1 F5 双机的通信机制 F5 负载均衡器的 ...

  7. 【连载】从单片机到操作系统⑥——FreeRTOS任务切换机制详解

    大家晚上好,我是杰杰,最近挺忙的,好久没有更新了,今天周末就吐血更新一下吧! 前言 FreeRTOS是一个是实时内核,任务是程序执行的最小单位,也是调度器处理的基本单位,移植了FreeRTOS,则避免 ...

  8. m基于中继协助的认知无线电频谱切换机制的matlab仿真分析

    目录 1.算法描述 2.仿真效果预览 3.MATLAB部分代码预览 4.完整MATLAB程序 1.算法描述 认知无线电网络在进行频谱切换的时候,最为重要的问题是如何以最少的频谱切换次数实现频谱切换,同 ...

  9. f5双机配置_[整理]F5负载均衡器双机切换机制及配置.

    ------------- ------------- F5 负载均衡器双机切换触发机制及配置 1 F5 双机的切换触发机制 1.1 F5 双机的通信机制 F5 负载均衡器的主备机之间的心跳信息可以通 ...

最新文章

  1. 硬核!我的导师手写129页毕业论文,堪比打印!
  2. 今天做了一个复杂的table
  3. python字典赋值方法_python如何给字典的键对应的值为字典项的字典赋值
  4. .NET如何写正确的“抽奖”——数组乱序算法
  5. C#.Net工作笔记014---C#中internal的意思
  6. 【U-net】【粗读】Retinal blood vessel segmentation using fully convolutional network with transfer...
  7. 实现横向排列的几种方案
  8. MAC 上的 Live Writer : ecto
  9. Vivado2018.3手把手详细下载
  10. 怎么查期刊是核心、是EI,还是SCI,或者说有哪些不是吧?
  11. 微型计算机8086工作原理,8086到80486微型计算机系统原理与接口
  12. dell 服务器启用虚拟化,打开DELL R410服务器BIOS虚拟化步骤(图文教程)
  13. 利用 JavaScript 快速切换正体中文和简体中文
  14. Windows系统封装步骤
  15. php7米酷cms,米酷CMS6.2修改版 支持PHP7 独家首发 - 百码云
  16. L2TP连接尝试失败,因为安全层在初始化与远程计算机的协商时遇到一个处理错误
  17. OpenCV开发笔记(四十九):红胖子8分钟带你深入了解轮廓识别(图文并茂+浅显易懂+程序源码)
  18. 服务器热备份、虚拟,VMware虚拟机热备份的几种方法
  19. 电口以太网物理层一致性测试原理与过程
  20. 基于OFBiz的E-TICKET(在线咨询管理)模块

热门文章

  1. Frogs HDU - 5514
  2. 牛客网【每日一题】7月30日题目精讲—Xor Path
  3. P4022-[CTSC2012]熟悉的文章【广义SAM,dp,单调队列】
  4. P3703-[SDOI2017]树点涂色【LCT,线段树】
  5. P1337-[JSOI2004]平衡点/吊打XXX【模拟退火】
  6. nssl1477-赛【对顶堆,贪心】
  7. jzoj4051-序列统计【NTT】
  8. 【线段树】扇形面积并(P3997)
  9. 【矩阵乘法】生成树计数(luogu 2109/NOI 2007)
  10. YL杯超级篮球赛(jzoj 1325)