用户态和内核态的切换

Q1:CPU为什么要切换特权级?
可执行程序的代码可分成两部分
(1)3特权级的用户程序
(2)0特权级的内核程序
在执行可执行程序时,需要在这两种代码间进行切换。但是OS内核代码的特权级高于用户程序,因此需要切换特权级。

Q2:执行高特权级代码的方式?
(1)利用一致性代码段,这种方式可以让指令指针跳转到高特权级的代码段,但是并不会改变当前的CPL,不会提高CPU特权级。
(2)利用系统调用,通过门结构提高CPU的特权级,这也是唯一提高CPU特权级的方式,共有4种门结构,中断门,调用门,任务门,陷阱门,现代操作系统通常使用中断门来实现系统调用

Q3:系统调用的分类:
在这里插入图片描述
任务门和调用门都可以通过call和jmp指令直接调用,其中call指令可实现向高特权级代码段转移,jmp只能平级转移。

Q4:从用户态到内核态的切换过程?
eflags寄存器:
在这里插入图片描述
关键位:
IF:限制外部设备的中断,避免中断嵌套
NT:任务嵌套标志位
TF:陷阱标志位,为0表示禁止单步执行
中断发生后NT和TF会被置0,如果对应的是中断门,IF也会被置0。

(一)向目标代码段转移
( 1 ) 将参数压入目前3特权级所在的栈中
( 2 ) 在门描述符中获取到转移目标代码段的DPL,如果DPL<CPL,说明目标代码段是特权级更高
如果是向更高的特权级转移:
( 3 )在TSS中找到更高特权级的栈段选择子和偏移,检查DPL和TYPE,如果未通过处理器引发异常
( 4 ) 将旧栈指针SS和ESP压入到新栈当中
( 5 ) 将原栈中压入的参数复制到新栈当中
( 6 ) 将原CS和IP压入到新栈当中
4,5,6步骤如下图A,B,C所示:
在这里插入图片描述
(7)将CS更新为门描述符中的代码段选择子,将EIP更新为门描述符中的偏移量
如果是平级转移:
(3)直接将CS和EIP压入当前3特权级的栈中

(二)从目标代码段返回
(1) 当在指令中遇到retf时,处理器对栈中CS的RPL与当前的CPL进行比较,判断是否需要改变处理器的特权级
(2) 对栈中的CS_old和EIP_old对应代码段的DPL进行特权级检查,检查通过将CS_old和EIP_old弹出恢复
(3) 如果特权级发生变化,再恢复SS和ESP

TSS:
存储任务环境的数据结构,包括任务在不同特权级下的栈地址(TSS只记录0, 1, 2特权级下的栈地址,因为处理器在向高特权级转移时,会自动将低特权级的栈指针压入高特权级所在的栈中),TR寄存器存储TSS在内存中的地址。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值