|| 版权声明:本文为博主原创文章,未经博主允许不得转载。

  一、前言

  在前两篇文章(《操作系统篇-浅谈实模式与保护模式》《操作系统篇-分段机制与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)的更多相关文章

  1. Linux从头学13:想彻底搞懂“系统调用”的底层原理?建议您别错过这篇【调用门】

    作 者:道哥,10+年嵌入式开发老兵,专注于:C/C++.嵌入式.Linux. 关注下方公众号,回复[书籍],获取 Linux.嵌入式领域经典书籍:回复[PDF],获取所有原创文章( PDF 格式). ...

  2. Linux从头学12:读完这篇【特权级】文章,你就比别人更“精通”操作系统!

    作 者:道哥,10+年嵌入式开发老兵,专注于:C/C++.嵌入式.Linux. 关注下方公众号,回复[书籍],获取 Linux.嵌入式领域经典书籍:回复[PDF],获取所有原创文章( PDF 格式). ...

  3. 特权级概述(哥子就想知道CPU是如何验证特权级的)GATE+TSS

    [0]README text description from orange's implemention of a os . [1]特权级概述 当当前代码段试图访问一个段或者门时,目标段的DPL将会 ...

  4. 通过调用门进行有特权级变换的转移,详细注解 对pmtest5.asm解释很详细.

    http://www.myexception.cn/operating-system/484288.html http://www.myexception.cn/operating-system/44 ...

  5. CPU Rings, Privilege, and Protection.CPU的运行环, 特权级与保护

    原文标题:CPU Rings, Privilege, and Protection 原文地址:http://duartes.org/gustavo/blog/ [注:本人水平有限,只好挑一些国外高手的 ...

  6. 操作系统篇-分段机制与GDT|LDT

    || 版权声明:本文为博主原创文章,未经博主允许不得转载. 一.前言     在<操作系统篇-浅谈实模式与保护模式>中提到了两种模式,我们说在操作系统中,其实大部分时间是待在保护模式中的. ...

  7. jmp && call && ret 特权级转移 & 进程调度

    ①jmp是不负责任的调度,不保存任何信息,不考虑会回头.跳过去就什么也不管了.②call,保存eip等,以便程序重新跳回.ret是call的逆过程,是回头的过程.这都是cpu固有指令,因此要保存的信息 ...

  8. 高特权级代码段转向低特权级代码段(利用 ret(retf) 指令实现 jmp from ring0 to ring3)

    [0]写在前面 0.1)本代码旨在演示 从 ring0 转移到 ring3(即,从高特权级 转移到 低特权级) 0.2)本文 只对 与 门相关的 代码进行简要注释,言简意赅: 0.3)文末的个人总结是 ...

  9. 操作系统篇-hello world(免系统运行程序)

     || 版权声明:本文为博主原创文章,未经博主允许不得转载. 一.前言     今天起开始分享关于操作系统的相关知识,本人也是菜鸟一个,正处于学习阶段,这整个操作系统篇也是我边学习边总结的一些结果,希 ...

随机推荐

  1. boosting、adaboost

    1.boosting Boosting方法是一种用来提高弱分类算法准确度的方法,这种方法通过构造一个预测函数系列,然后以一定的方式将他们组合成一个预测函数.他是一种框架算法,主要是通过对样本集的操作获 ...

  2. favicon.ioc使用以及注意事项

    1.效果 2.使用引入方法 2.1 注意事项:(把图标命名为favicon.ico,并且放在根目录下,同时使用Link标签,多重保险) 浏览器默认使用根目录下的favicon.ico 图标(如果你并没 ...

  3. Velocity笔记--使用Velocity获取动态Web项目名的问题

    以前使用jsp开发的时候,可以通过request很轻松的获取到根项目名,现在换到使用velocity渲染视图,因为已经不依赖servlet,request等一些类的环境,而Web项目的根项目名又不是写 ...

  4. JAVA GUI编程学习笔记目录

    2014年暑假JAVA GUI编程学习笔记目录 1.JAVA之GUI编程概述 2.JAVA之GUI编程布局 3.JAVA之GUI编程Frame窗口 4.JAVA之GUI编程事件监听机制 5.JAVA之 ...

  5. %iowait和CPU使用率的正确认知

    resources 理解 %IOWAIT (%WIO) LINUX系统的CPU使用率和LOAD Linux Performance Observability Tools How Linux CPU ...

  6. CSS3新特性应用之结构与布局

    一.自适应内部元素 利用width的新特性min-content实现 width新特性值介绍: fill-available,自动填充盒子模型中剩余的宽度,包含margin.padding.borde ...

  7. AndroidStudio — Error:Failed to resolve: junit:junit:4.12错误解决

    原博客:http://blog.csdn.net/u013443865/article/details/50243193 最近使用AndroidStudio出现以下问题: 解决:打开app下的buil ...

  8. Android Weekly Notes Issue #234

    Android Weekly Issue #234 December 4th, 2016 Android Weekly Issue #234 本期内容包括: ConstraintLayout的使用; ...

  9. keepalive的不足,如何处理

    MySQL(或者其它服务)的keepalived高可用监控脚本 开发脚本需求:我们知道,keepalive是基于虚拟ip的存活来判断是否抢占master的机制的,但是如果我们做了MySQL的keepa ...

  10. 智能头盔 "Livall携全球首款智能骑行头盔亮相CES"

    LIVALL是全球首创集音乐.通讯.智能灯光为一体的智能骑行头盔的研发者,日前Livall携旗下智能骑行头盔BH 100和BH 60参展CES 2017,这也是目前世全球首款智能骑行头盔类产品,同时亮 ...