当前位置:网站首页>任务切换的细节
任务切换的细节
2022-07-23 11:10:00 【raindayinrain】
在一个多任务环境中,可同时存在多个任务。每个任务有各自的局部描述符表(LDT)和任务状态段(TSS)。在局部描述符表中存放着专属于任务局部空间的段的描述符。可在多个任务之间切换,使它们轮流执行,从一个任务切换到另一个任务时,具体的切换过程是由处理器固件负责进行的。
所谓多任务系统,指能同时执行两个以上任务的系统。任务调度主要是操作系统的责任,处理器只负责具体的切换过程,包括保护前一个任务的现场。
有两种基本的任务切换方式,一种是协同式的,从一个任务切换到另一个任务,需当前任务主动请求暂时放弃执行权,或在通过调用门请求操作系统服务时,由操作系统"趁机"将控制转移到另一个任务。这种方式依赖任务"自律"。
另一种是抢占式,这种方式下,可安装一个定时器中断,并在中断服务程序中实施任务切换。硬件中断信号总会定时出现,不管处理器当时在做什么,中断都会适时发生,而任务切换也就能顺利进行。这种情况下,每个任务都能获得平等的执行机会。且,即使一个任务失控,也不会导致其他任务没有机会执行。
15.1.本章代码清单
15.2.任务切换前的设置
所有任务共享一个全局空间,这是内核或操作系统提供的,包含了系统服务程序和数据;同时,每个任务还有自己的局部空间,每个任务的功能都不一样,所以,局部空间包含的是一个任务区别于其他任务的私有代码和数据。
在一个任务内,全局空间和局部空间具有不同的特权级别。使用门,可在任务内将控制从3特权级的局部空间转移到0特权级的全局空间,以使用内核或操作系统提供的服务。
任务切换是以任务为单位的,是指离开一个任务,转到另一个任务中去执行。任务转移相对来说要复杂的多,当一个任务正在执行时,处理器的各个部分都和该任务息息相关:段寄存器指向该任务所使用的内存段;通用寄存器保存着该任务的中间结果,等等。
离开当前任务,转到另一个任务开始执行时,要保存旧任务的各种状态,并恢复新任务的运行环境。
即要执行任务切换,系统中需至少有两个任务,且已经有一个正在执行中。一开始,处理器是在任务的全局空间执行的,当前特权级别是0,然后,我们通过一个虚假的调用门返回,使处理器回到任务的局部空间执行,当前特权级别降为3。
事实上这样没必要。首先,处理器刚进入保护模式时,以0特权级运行的,且执行的一般是操作系统代码,也需是0特权级别的。其次,任务不一定非得是3特权级别的,也可是0特权级别的。特别是,操作系统除了为每一个任务提供服务外,也会有一个作为任务而独立存在的部分,且是0特权级别的任务,以完成一些管理和控制功能,比如提供一个界面和用户进行交互。
计算机加电后,一旦进入保护模式,就直接创建和执行操作系统的0特权级任务。然后,可从该任务切换到其他任务。
既然如此,这一章,首先要创建0特权级别的操作系统(内核)任务。
内核任务,一般作用是创建其他任务,管理它们,所以称作任务管理器,或叫程序管理器。
任务状态段(TSS)是一个任务存在的标志,没有它,就无法执行任务切换,因为任务切换时需要保存旧任务的各种状态数据。
程序管理器任务没有自己的LDT,任务可以没有自己的LDT,这是允许的。程序管理器可以将自己所使用的段描述符安装在GDT中。另外,程序管理器任务是运行在0特权级别上的,不需要创建额外的栈。因为除了从门返回外,不能将控制从高特权级的代码段转移到低特权级的代码段。
在GDT中创建TSS的描述符,必须创建TSS的描述符,且只能安装在GDT中。
为表明当前正在任务中执行,要做的最后一个工作是将当前任务的TSS选择子传送到任务寄存器TR中。
15.3.任务切换的方法
对多任务的支持是现代处理器的标志之一。为此,Intel处理器提供了多种方法,以灵活地在各个任务之间实施切换。
处理器并没有提供额外的指令用于任务切换。事实上,用的都是我们熟悉的老指令和老手段,但扩展了它们的功能,使之除了能继续执行原有的功能外,也能用于实施任务切换操作。
第一种任务切换的方法是借助于中断,这也是现代抢占式多任务的基础。
我们知道,实模式下,内存最低地址端的1KB是中断向量表,保存着256个中断处理过程的段地址和偏移地址。当中断发生时,处理器把中断号乘以4,作为表内索引号访问中断向量表,从相应位置取出中断处理过程的段地址和偏移地址,并转移到那里执行。
在保护模式下,中断向量表不再使用,取而代之的,是中断描述符表。
它类似GDT,LDT,用于保存描述符。唯一不同的地方是,它保存的是门描述符,包括中断门,陷阱门,任务门。
当中断发生时,处理器用中断号乘以8(因为每个描述符占8字节),作为索引访问中断描述符表,取出门描述符。门描述符中有中断处理过程的代码段选择子和段内偏移量,这和调用门是一样的。接着,转移到相应的位置去执行。
一般的中断处理可以使用中断门和陷阱门。中断门和陷阱门允许在任务内实施中断处理,转到全局空间去执行一些系统级的管理工作,本质上,也是任务内的控制转移行为。
但是,中断发生时,如该中断号对应的门是任务门,则,性质就截然不同了,必须进行任务切换。即,要中断当前任务的执行,保护当前任务的现场,并转换到另一个任务去执行。
任务门描述符格式
不使用(占据16位) P DPL 00101 不使用(占据8位) TSS选择子(占据16位) 不使用(占据16位)
任务门描述符中的P位指示该门是否有效,当P位为"0"时,不允许通过此门实施任务切换;DPL是任务门描述符的特权级,但对因中断而发起的任务切换不起作用,处理器不按特权级施加任何保护。但这并不意味着DPL字段没用处,当以非中断的方式通过任务门实施任务切换时,它就有用了。
当中断发生时,处理器用中断号乘以8作为索引访问中断描述符表。当它发现这是一个任务门(描述符)时,就知道应当发起任务切换。于是,它取出任务门描述符;再从任务门描述符中取出新任务的TSS选择子;接着,再用TSS选择子访问GDT,取出新任务的TSS描述符。
在转到新任务执行前,处理器要先把当前任务的状态保存起来。当前任务的TSS是由任务寄存器TR的当前内容指向的,所以,处理器要把每个寄存器的"快照"保存到由TR指向的TSS中。然后,处理器访问新任务的TSS,从中恢复各个寄存器的内容,包括通用寄存器,标志寄存器EFLAGS,段寄存器,指令指针寄存器EIP,栈指针寄存器ESP,及局部描述符表寄存器(LDTR)等。
最终,任务寄存器TR指向新任务的TSS,而处理器旋即开始执行新的任务。一旦新任务开始执行,处理器固件会自动将其TSS描述符的B位置"1",表示该任务的状态为忙。
当中断发生时,可执行常规的中断处理过程,也可进行任务切换。尽管性质不同,但都用iret指令返回。前者是返回到同一任务内的不同代码段;后者是返回到被中断的那个任务。
32位处理器的EFLAGS有NT位(位14),意思是嵌套任务标志。每个任务的TSS中都有一个任务链接域(指向前一个任务的指针),可以填写为前一个任务的TSS描述符选择子。如当前任务EFLAGS寄存器的NT位是"1",则表示当前正在执行的任务嵌套于其他任务内,且能通过TSS任务链接域的指针返回到前一个任务。
保留设置为0(占据10位) ID 空 空 空 空 空 0 NT IOPL OF DF IF TF SF ZF 0 AF 0 PF 1 CF
因中断而引发任务切换时,取决于当前任务(旧任务)是否嵌套于其他任务内,其EFLAGS寄存器的NT位可能是"0",也可能是"1"。处理器不会改变它,而是和其他寄存器一道,写入TSS中保护起来。另外,当前任务(旧任务)肯定处于"忙"状态,其TSS描述符的B位一定是"1",在任务切换后同样保持不变。
对新任务的处理是,要把老任务的TSS选择子填写到新任务TSS中的任务链接域,同时,将新任务EFLAGS寄存器的NT位置"1",以允许返回到前一任务继续执行。同时,还要把新任务TSS描述符的B位置"1"。
可使用iret指令从当前任务返回到前一个任务,前提是当前任务EFLAGS寄存器的NT位必须是"1"。无论任何时候处理器碰到iret指令,都要检查NT位,如此位是0,表明是一般的中断过程,按一般的中断返回处理,即,中断返回是任务内的(中断处理过程虽然属于操作系统,但属于任务的全局空间);如此位是1,则表明当前任务之所以能执行,是因为中断了别的任务。因此,应返回原先被中断的任务继续执行。此时,由处理器固件把当前任务EFLAGS寄存器的NT位改为"0",并把TSS描述符的B位改为"0"。在保存了当前任务的状态之后,接着,用新任务(被中断的任务)的TSS恢复现场。
除了因中断引发的任务切换外,还可用远过程调用CALL,或远跳转指令JMP直接发起任务切换。此时,CALL和JMP指令的操作数是任务的TSS描述符选择子或任务门。
call 0x0010:0x00000000
jmp 0x0010:0x00000000
当处理器执行这两条指令时,首先用指令中给出的描述符选择子访问GDT,分析它的描述符类型。如是一般的代码段描述符,就按普通的段间转移规则执行;如是调用门,按调用门的规则执行;如是TSS描述符,或任务门,则执行任务切换。
此时,指令中32位偏移量被忽略,因为执行任务切换时,所有处理器的状态都可从TSS中获得。注意,任务门描述符可安装在中断描述符表中,也可安装在全局描述符表或局部描述符表中。
如是用于发起任务切换,call和jmp也有不同之处。使用call指令发起的任务切换类似于因中断发起的任务切换。即,由call指令发起的任务切换是嵌套的,当前任务(旧任务)TSS描述符的B位保持原来的"1"不变 ,EFLAGS寄存器的NT位也不发生变化;新任务TSS描述符的B位置"1",EFLAGS寄存器的NT位也置"1",表示此任务嵌套于其他任务中。同时,TSS任务链接域的内容改为旧任务的TSS描述符选择子。
假设任务1是整个系统中的第一个任务。当任务1开始执行时,其TSS描述符的B位是"1",EFLAGS寄存器的NT位是"0",不嵌套于其他任务。
当从任务1切换到任务2后,任务1仍然为"忙",EFLAGS寄存器的NT位不变(在其TSS中);任务2也变为"忙",EFLAGS寄存器的NT位变为"1",表示嵌套于任务1中。同时,任务1的TSS描述符选择子也被复制到任务2的TSS中(任务链接域)。
最后是从任务2转到任务3执行。任务2保持"忙", EFLAGS寄存器的NT不变(在其TSS中);任务3成为当前任务,其TSS描述符的B位变为"1",EFLAGS寄存器的NT位也变成"1",同时,其TSS任务链接域指向任务2。
用CALL指令发起的任务切换,可通过iret指令返回到前一个任务。此时,旧任务TSS描述符的B位,及EFLAGS寄存器的NT位都恢复到"0"。
和call不同,使用jmp指令发起的任务切换,不会形成任务间的嵌套关系。执行任务切换时,当前任务(旧任务)TSS描述符的B位清零,变为非忙状态,EFLAGS寄存器的NT位不变;新任务TSS描述符的B位置"1",进入忙的状态,EFLAGS寄存器的NT位保持从TSS中加载时的状态不变。
任务是不可重入的。
任务不可重入的本质是,执行任务切换时,新任务的状态不能为忙。
第一种情形,执行任务切换时,新任务不能是当前任务自己。因为如允许,处理器不好执行现场的保护和恢复。
第二种情形,不允许使用CALL指令从任务3切换到任务2和任务1上。如不禁止这样,任务之间的嵌套关系将会因为TSS任务链接域的破坏而错乱。
处理器是通过TSS描述符的B位来检测重入的。因中断,iret,call和jmp指令发起任务切换时,处理器固件会检测新任务TSS描述符的B位,如为"1",则不允许执行这样的切换。
---next
边栏推荐
- go : gin Urlencoded 格式
- C # calculate the number of times a character appears in the string
- 《快速掌握QML》第四章 事件处理
- STL deque
- Solve the problem that kotlin writes the Android project compilation report execution failed for task ': app:kaptdebugkotlin'. Exception
- Error | cannot read property '_ normalized‘ of undefined
- Idea starts multiple projects at once
- 2022最NB的JVM基础到调优笔记,吃透阿里P6小case
- Find the source code of the thesis
- 对专利的学习
猜你喜欢

Error | cannot read property '_ normalized‘ of undefined

centos7 中彻底卸载mysql

Idea starts multiple projects at once
![[200 opencv routines] 225. Fourier descriptor for feature extraction](/img/4b/1f373505ffd5c0dbaa5c20431c4b42.png)
[200 opencv routines] 225. Fourier descriptor for feature extraction
![[ctfhub] the data of JWT header and payload are transmitted in clear text. If sensitive information is contained in it, sensitive information will be leaked. Try to find the flag. Format is flag{}](/img/d0/133d628a304f5c6b5f0d514c9fe222.jpg)
[ctfhub] the data of JWT header and payload are transmitted in clear text. If sensitive information is contained in it, sensitive information will be leaked. Try to find the flag. Format is flag{}

The official redis visualization tool is coming. The needle doesn't poke

重磅 | CertiK:2022年第二季度Web3.0行业安全报告发布(附PDF下载链接)

麒麟V10源码编译qtCreator4.0.3记录

C语言经典例题-将输入的两位数转成英文

7.13WEB安全作业
随机推荐
JSD-2204-会话管理-过滤器-Day19
第一篇 项目基本情况介绍
[pyGame practice] playing poker? Win or lose? This card game makes me forget to eat and sleep.
Exploration and practice of Ali multimodal knowledge atlas
Jsd-2204 session management filter day19
2022最NB的JVM基础到调优笔记,吃透阿里P6小case
Analysis of data governance
工业物联网中的时序数据
Redis bloom filter
Axure advanced
(BFS) template + example (maze, eight digits)
查找论文源代码
Redis 删除Key命令会导致阻塞么?
Deep understanding of L1 and L2 regularization
RTA is a new way to accurately launch advertisements?
Les raccourcis clavier liés à l'onglet ne peuvent pas être utilisés après la mise à jour du vscode
Safe operation 7.22
VSCode 更新後與tab相關快捷鍵無法使用
第二篇 如何设计一个RBAC权限系统
centos7 中彻底卸载mysql