操作系统篇-调用门与特权级(CPL、DPL和RPL)
|| 版权声明:本文为博主原创文章,未经博主允许不得转载。
一、前言
在前两篇文章(《操作系统篇-浅谈实模式与保护模式》和《操作系统篇-分段机制与GDT|LDT》)中,我们提到过特权级与调用门,特别是在说到保护模式时,我们提到了内存的保护,“保护”这两个字的含义何在呢?不同权级之间是如何相互访问,如何通讯,如何保护,这些东西都跟调用门和不同代码段的特权级紧密相关。本文主要探讨的就是,保护模式下的调用门与特权级,在阅读本文之前,建议大家先看看blog的之前几篇文章(当然,在本文中也会提到之前讲过的一些知识),熟悉一些基本结构与原理,对本文的理解将会大大加深。
二、特权级
a.概念
关于特权级,我们在《操作系统篇-分段机制与GDT|LDT》的描述符结构中有提到过。在分段机制中,特权级总共有4个特权级别,从高到低分别是0、1、2、3,数字越小表示的特权级别越大。如下图所示:

较为核心的代码和数据将被放在特权级较高的层级中。处理器将用这样的机制来避免低特权级的任务在不被允许的情况下访问位于高特权级的段中。如果处理器检测到一个访问请求是不合法的,将会产生常规保护错误。有时候也将高特权级称为内层,低特权级称为外层。
b.CPL、DPL和RPL
(1)CPL
CPL是当前执行的程序或任务的特权级。它被存储在CS和SS的第0位和第1位上。通常情况下,CPL代表代码所在的段的特权级。当程序转移到不同特权级的代码段时,处理器将改变CPL。只有0和3两个值,分别表示用户态和内核态。
(2)DPL
DPL表示段或门的特权级。它被存储在段描述符或者门描述符的DPL字段中(《操作系统篇-分段机制与GDT|LDT》中有提到),当当前代码段试图访问一个段或者门(这里大家先把门看成跟段一样,下面我们会介绍),DPL将会和CPL以及段或者门选择子的RPL相比较,根据段或者门类型的不同,DPL将会区别对待。
RPL是通过段选择子的第0和第1位表现出来的。RPL是代码中根据不同段跳转而确定,以动态刷新CS里的CPL,在代码段选择符中。而且RPL对每个段来说不是固定的,两次访问同一段时的RPL可以不同。操作系统往往用RPL来避免低特权级应用程序访问高特权级段内的数据,即便提出访问请求的段有足够的特权级,如果RPL不够也是不行的,当RPL的值比CPL大的时候,RPL将起决定性作用。也就是说,RPL相当于附加的一个权限控制,只有当RPL>DPL的时候,才起到实际的限制作用。
三、调用门
a.结构
调用门用于在不同特权级之间实现受控的程序控制转移,通常仅用于使用特权级保护机制的操作系统中。本质上,它只是一个描述符,一个不同于代码段和数据段的描述符,可以安装在GDT或者LGT中,但是不能安装在IDT(中断描述符表)中。它主要是定义了目标代码对应段的选择子、入口地址的偏移和一些属性等。结构跟代码段以及数据段描述符大不相同。结构如下图所示:

一个门描述了由一个选择子和一个偏移所指定的线性地址,程序正是通过这个地址进行转移的。
b.通过调用门访问代码段
调用门的访问一般通过call、jmp指令的操作数提供的一个远指针,该指针中的段选择子用于指定调用门,CPU会使用调用门中的偏移值实现跳转。如下图:

通过调用门进行程序的转移控制时,CPU会检查以下这几个字段:1.当前代码段的CPL;2.调用门描述符中的DPL;3.调用门描述符中的RPL;4.目的代码描述符的DPL;5.目标代码段描述符中的一致性标志C(一致与非一致下面会提到)。如下图:

对于call和jmp指令,有着不同的优先级检查规则的:
对call来说:当前CPL<=调用门描述符DPL,RPL<=调用门描述符DPL,当前CPL>=目的代码段描述符DPL;
对jmp来说:除了跟call的“当前CPL<=调用门描述符DPL,RPL<=调用门描述符DPL”一样外,如果目的代码段的一致的话,CPL>=目的代码段的DPL,而如果目的代码段是非一致的话,CPL=目的代码段的DPL。
另外,只有call指令可以将代码通过调用门转移到特权级更高的非一致性代码之中。对于非一致性代码的成功转移,CPL被目的代码的DPL刷新,会引起堆栈切换;对于一致性代码,不会刷新,也不会切换。
调用门的作用是,让一个代码段中的过程被不同特权级的程序访问。通常用于低特权级代码来访问高特权级的代码段。
c.一致代码段与非一致代码段
什么是一致代码段:简单理解,就是操作系统拿出来被共享的代码段,可以被低特权级的用户直接调用访问的代码。向特权级更高的一致性代码段的控制转移,允许程序以当前特权级继续执行。通常这些共享代码,是"不访问"受保护的资源和某些类型异常处理。对于一致性代码来说,特权级高的程序不允许访问特权级低的数据:即是说核心态不允许调用用户态的数据;特权级低的程序可以访问到特权级高的数据.但是特权级不会改变:用户态还是用户态。
代码段可以是一致性的或者非一致性的。那什么是非一致性代码段呢?可以理解为,为了避免低特权级的访问而被操作系统保护起来的系统代码。向不同特权级的非一致代码段转移将导致一般保护异常,除非使用了任务门或者调用门。产生一致性代码和非一致性代码的主要原因是:单纯的0-3特权级只能保证高特权级可以访问特权级的东西,而低特权级的段有时候要访问内核数据段,此时就需要一些灵活策略。对于非一致代码段来说,只允许同级间访问,绝对禁止不同级访问:核心态不用用户态,而用户态也不使用核心态。
通常低特权代码必须通过"门"来实现对高特权代码的访问和调用。不访问保护措施的系统工具和某些异常类型的处理过程需要放在一致性代码段中。需要防止低特权级程序访问的工具要放在非一致代码段中。
每当调用门用于把程序控制转移到一个更高级别的非一致性代码段时,CPU会自动切换到目的代码段特权级的堆栈去。每个任务只能定义最多4个栈,分别对应4个特权级。每个栈都位于不同的段中,并且使用段选择符和段中偏移值指定。堆栈的切换我们在后期的文章会配合例子来讲解。
操作系统篇-调用门与特权级(CPL、DPL和RPL)的更多相关文章
- Linux从头学13:想彻底搞懂“系统调用”的底层原理?建议您别错过这篇【调用门】
作 者:道哥,10+年嵌入式开发老兵,专注于:C/C++.嵌入式.Linux. 关注下方公众号,回复[书籍],获取 Linux.嵌入式领域经典书籍:回复[PDF],获取所有原创文章( PDF 格式). ...
- Linux从头学12:读完这篇【特权级】文章,你就比别人更“精通”操作系统!
作 者:道哥,10+年嵌入式开发老兵,专注于:C/C++.嵌入式.Linux. 关注下方公众号,回复[书籍],获取 Linux.嵌入式领域经典书籍:回复[PDF],获取所有原创文章( PDF 格式). ...
- 特权级概述(哥子就想知道CPU是如何验证特权级的)GATE+TSS
[0]README text description from orange's implemention of a os . [1]特权级概述 当当前代码段试图访问一个段或者门时,目标段的DPL将会 ...
- 通过调用门进行有特权级变换的转移,详细注解 对pmtest5.asm解释很详细.
http://www.myexception.cn/operating-system/484288.html http://www.myexception.cn/operating-system/44 ...
- CPU Rings, Privilege, and Protection.CPU的运行环, 特权级与保护
原文标题:CPU Rings, Privilege, and Protection 原文地址:http://duartes.org/gustavo/blog/ [注:本人水平有限,只好挑一些国外高手的 ...
- 操作系统篇-分段机制与GDT|LDT
|| 版权声明:本文为博主原创文章,未经博主允许不得转载. 一.前言 在<操作系统篇-浅谈实模式与保护模式>中提到了两种模式,我们说在操作系统中,其实大部分时间是待在保护模式中的. ...
- jmp && call && ret 特权级转移 & 进程调度
①jmp是不负责任的调度,不保存任何信息,不考虑会回头.跳过去就什么也不管了.②call,保存eip等,以便程序重新跳回.ret是call的逆过程,是回头的过程.这都是cpu固有指令,因此要保存的信息 ...
- 高特权级代码段转向低特权级代码段(利用 ret(retf) 指令实现 jmp from ring0 to ring3)
[0]写在前面 0.1)本代码旨在演示 从 ring0 转移到 ring3(即,从高特权级 转移到 低特权级) 0.2)本文 只对 与 门相关的 代码进行简要注释,言简意赅: 0.3)文末的个人总结是 ...
- 操作系统篇-hello world(免系统运行程序)
|| 版权声明:本文为博主原创文章,未经博主允许不得转载. 一.前言 今天起开始分享关于操作系统的相关知识,本人也是菜鸟一个,正处于学习阶段,这整个操作系统篇也是我边学习边总结的一些结果,希 ...
随机推荐
- java中的锁
java中有哪些锁 这个问题在我看了一遍<java并发编程>后尽然无法回答,说明自己对于锁的概念了解的不够.于是再次翻看了一下书里的内容,突然有点打开脑门的感觉.看来确实是要学习的最好方式 ...
- Javascript生成二维码(QR)
网络上已经有非常多的二维码编码和解码工具和代码,很多都是服务器端的,也就是说需要一台服务器才能提供二维码的生成.本着对服务器性能的考虑,这种小事情都让服务器去做,感觉对不住服务器,尤其是对于大流量的网 ...
- macOS 我的装机
最近多次配置 Mac 的开发环境,稍微记录一下 1 创建无付费信息的Apple ID 2 Xcode gem 源更改 3 Alfred 4 微信 5 SourceTree 6 Sublime Te ...
- ASP.NET SignaiR 实现消息的即时推送,并使用Push.js实现通知
一.使用背景 1. SignalR是什么? ASP.NET SignalR 是为 ASP.NET 开发人员提供的一个库,可以简化开发人员将实时 Web 功能添加到应用程序的过程.实时 Web 功能是指 ...
- GOF23设计模式之单例模式
·核心作用: -保证一个类只有一个实例,并且提供一个访问该实例的全局访问点. ·常见应用场景: -Windows的Task Manager(任务管理器)就是很典型的单例模式 -Windows的Recy ...
- Android开发学习——动画
帧动画> 一张张图片不断的切换,形成动画效果* 在drawable目录下定义xml文件,子节点为animation-list,在这里定义要显示的图片和每张图片的显示时长 ...
- Android事件分发机制浅谈(一)
---恢复内容开始--- 一.是什么 我们首先要了解什么是事件分发,通俗的讲就是,当一个触摸事件发生的时候,从一个窗口到一个视图,再到一个视图,直至被消费的过程. 二.做什么 在深入学习android ...
- Android中实现APP文本内容的分享发送与接收方法简述
谨记(指定选择器Intent.createChooser()) 开始今天的内容前,先闲聊一下: (1)突然有一天头脑风暴,对很多问题有了新的看法和见解,迫不及待的想要分享给大家,文档已经写好了,我需要 ...
- TFS 安装错误
错误 问题详细: HTTP 错误 500.19 - Internal Server Error 无法访问请求的页面,因为该页的相关配置数据无效. 详细错误信息 模块 Dynam ...
- 希尔排序(java)
时间复杂度为O( n^(3/2) )不是一个稳定的排序算法 如何看一个算法是否稳定:{("scala",12),("python",34),("c++ ...