原文地址:
https://blog.csdn.net/farmwang/article/details/50094959
https://blog.csdn.net/bfboys/article/details/52420211

文章目录

  • 1. 引言
  • 2.CPU 指令上的限制
  • 3.代码分类与相关概念
    • 3.1 代码分类
    • 3.2 相关概念
  • 4.级别切换
    • 4.1 **切换过程中发生的堆栈切换**

1. 引言

在这篇文章里,我们会接触到x86的特权级(privilege level),看看操作系统和CPU是怎么一起合谋来限制用户模式的应用程序的。特权级总共有4个,编号从0(最高特权)到3(最低特权)。有3种主要的资源受到保护:内存,I/O端口以及执行特殊机器指令的能力。在任一时刻,x86 CPU都是在一个特定的特权级下运行的,从而决定了代码可以做什么,不可以做什么。这些特权级经常被描述为保护环(protection ring),最内的环对应于最高特权。

但是,即使是最新的Linux内核也只用到其中的2个特权级:0和3。

2.CPU 指令上的限制

在诸多机器指令中,只有大约15条指令被CPU限制只能在ring 0执行(其余那么多指令的操作数都受到一定的限制)。这些指令如果被用户模式的程序所使用,就会颠覆保护机制或引起混乱,所以它们被保留给内核使用。如果企图在ring 0以外运行这些指令,就会导致一个一般保护错(general-protection exception),就像一个程序使用了非法的内存地址一样。类似的,对内存和I/O端口的访问也受特权级的限制。但是,在我们分析保护机制之前,先让我们看看CPU是怎么记录当前特权级的吧。

数据段选择符的整个内容可由程序直接加载到各个段寄存器当中,比如ss(堆栈段寄存器)和ds(数据段寄存器)。这些内容里包含了请求特权级(Requested Privilege Level,简称RPL)字段,其含义过会儿再说。

代码段寄存器就比较特别了。首先,它的内容不能由装载指令(如MOV)直接设置,而只能被那些会改变程序执行顺序的指令(如CALL)间接的设置。而且,不像那个可以被代码设置的RPL字段,cs拥有一个由CPU自己维护的当前特权级字段(Current Privilege Level,简称CPL),这点对我们来说非常重要。这个代码段寄存器中的2位宽的CPL字段的值总是等于CPU的当前特权级。Intel的文档并未明确指出此事实,而且有时在线文档也对此含糊其辞,但这的确是个硬性规定。在任何时候,不管CPU内部正在发生什么,只要看一眼cs中的CPL,你就可以知道此刻的特权级了。

记住,CPU特权级并不会对操作系统的用户造成什么影响,不管你是根用户,管理员,访客还是一般用户。所有的用户代码都在ring 3上执行,所有的内核代码都在ring 0上执行,跟是以哪个OS用户的身份执行无关。有时一些内核任务可以被放到用户模式中执行,比如Windows Vista上的用户模式驱动程序,但是它们只是替内核执行任务的特殊进程而已,而且往往可以被直接删除而不会引起严重后果。

由于限制了对内存和I/O端口的访问,用户模式代码在不调用系统内核的情况下,几乎不能与外部世界交互。它不能打开文件,发送网络数据包,向屏幕打印信息或分配内存。用户模式进程的执行被严格限制在一个由ring 0之 神所设定的沙盘之中。这就是为什么从设计上就决定了:一个进程所泄漏的内存会在进程结束后被统统回收,之前打开的文件也会被自动关闭。所有的控制着内存或 打开的文件等的数据结构全都不能被用户代码直接使用;一旦进程结束了,这个沙盘就会被内核拆毁。这就是为什么我们的服务器只要硬件和内核不出毛病,就可以 连续正常运行600天,甚至一直运行下去。这也解释了为什么Windows 95/98那么容易死机:这并非因为微软差劲,而是因为系统中的一些重要数据结构,出于兼容的目的被设计成可以由用户直接访问了。这在当时可能是一个很好的折中,当然代价也很大。

3.代码分类与相关概念

3.1 代码分类

系统要安全,必须保证内核与用户程序分离开,内核要安全,必须不能被用户来打扰。但是有的时候,用户程序也是需要访问内核中的部分数据,那怎么办?

于是操作系统就将内核中的段分为共享的代码段和非共享的代码段两部分。
其中一致代码段就是操作系统拿出来被共享的代码段,可以被低特权级的用户直接访问的代码。

一致代码段的限制作用:
(1)特权级高的代码段不允许访问特权级低的代码段:即内核态不允许调用用户态下的代码。
(2)特权级低的代码段可以访问特权级高的代码段,但是当前的特权级不发生变化。即:用户态可以访问内核态的代码,但是用户态仍然是用户态。

非一致代码段:为了避免低特权级的访问而被操作系统保护起来的系统代码,也就是非共享代码。

非一致代码段的限制作用:
(1)只允许同特权级间访问
(2)绝对禁止不同级间访问,即:用户态不能访问内核态,内核态也不访问用户态。

3.2 相关概念

1、CPL(Current PrivilegeLevel)是当前执行的程序或任务的特权级。它被存储在CS和SS的第0位和第1位上。通常情况下,CPL等于代码的段的特权级。在遇到一致代码段时,一致代码段可以被相同或者更低特权级的代码访问。当处理器访问一个与CPL特权级不同的一致代码段时,CPL不会被改变。

2、DPL(DescriptorPrivilege Level):DPL表示段或者门的特权级,它被存储在段描述符或者门描述符的DPL字段中。当当前代码段试图访问一个段或者门时,DPL将会和CPL以及段或门选择子的RPL相比较,根据段或者门类型的不同,DPL将会被区别对待,下面介绍一下各种类型的段或者门的情况。
(1)数据段: CPL(RPL)<= DPL才可以访问
(2)非一致代码段(不使用调用门的情况下): CPL(RPL)=DPL才可以访问
(3)调用门:DPL规定了当前执行的程序或任务可以访问此调用门的最低特权级(这与数据段的规则是一致的)。
(4)一致代码段和通过调用门访问的非一致代码段:CPL(RPL)=> DPL

3、RPL(RequestedPrivilege Level):RPL是通过选择子的第0位和第1位表现出来的。处理器通过检查RPL和CPL来确认一个访问请求是否合法。

4.级别切换

切换的过程有点像trustzone机制。用户程序想调用系统内核代码,通过系统调用+调用门 陷入内核。陷入切换的代码属于内核+硬件机制,系统只要保证这部分属于可信的(共享、一致性代码),该检查的都检查了,则允许通行,执行内核代码。

低优先级的代码通过call SelectorofGate_Ring3_Ring0类似的调用们指令来访问内核代码时,CPU会自动按照顺序完成如下的动作:

  • 根据目标代码段的DPL(新的CPL)从TSS中选择切换至哪个ss和esp
  • 从TSS中读取新的ss和esp。在这个过程中如果发现ss, esp或者TSS界限错误都会报错
  • 暂时性的保存当前的ss和esp
  • 加载新的ss和esp
  • 将刚刚保存起来的ss和esp的值压入新栈
  • 从调用者堆栈中将参数复制到被调用者堆栈(新堆栈)中,复制参数的数目由调用门中Param Count一项决定
  • 将当前的cs和eip压栈
  • 加载调用门中指定的新的cs和eip,开始执行被调用者过程

4.1 切换过程中发生的堆栈切换

(1)进程的用户堆栈 -> 进程的内核堆栈
当中断发生时,中断硬件将程序计数器、程序状态字、有时还有一个或多个寄存器(进程的运行状态信息)压入当前进程的内核堆栈中(这个过程就是第一条介绍的过程),PC随即跳转到中断服务程序入口(根据硬件向量法或软件查询法得到中断服务程序入口地址)去执行中断服务程序。注意,这些工作都是硬件完成的,在这些工作完成的同时完成了一次堆栈切换(从进程的用户堆栈切换到进程的内核堆栈,由中断硬件完成);

(2) 进程的内核堆栈 -> 中断堆栈
然后,PC的控制权转移到了软件(中断服务程序) ,一般地,中断服务程序有一个自己的中断堆栈(就像进程有自己的内核堆栈一样),为了不破坏内核堆栈,在执行中断服务程序的过程中又会发生一次堆栈切换(从内核堆栈切换到中断堆栈,这次的切换是软件完成的),进入到中断上下文之中;

随后中断服务程序会调用处理特定中断请求的中断处理例程,让中断处理例程运行在中断上下文之中。

(3) 中断堆栈切 -> 内核堆栈
中断处理例程完成中断处理之后返回到中断服务程序,返回的过程又会涉及到一次堆栈切换(由中断堆栈切换到内核堆栈,这次的切换也是软件完成的);

(4) 进程 内核堆栈 -> 用户堆栈
最后,中断服务程序执行中断返回指令,由中断硬件将内核堆栈中的状态信息恢复到相应的寄存器中,在恢复寄存器的同时清空内核堆栈中保存的状态信息,系统从内核态返回到用户态,这里又发生了一次堆栈切换(从内核堆栈切换到用户堆栈,由中断硬件完成)。

CPU的运行环, 特权级与保护相关推荐

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

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

  2. 特权级——保护模式的特权级检查 DPL,RPL,CPL, 一致代码段,非一致代码段

    特权级是保护模式下一个重要的概念,CPL,RPL和DPL是其中的核心概念,查阅资料无数,总结如下. 一.CPL.RPL.DPL简单解释     CPL是当前进程的权限级别(Current Privil ...

  3. 【OS学习笔记】二十三 保护模式七:保护模式下任务的隔离与任务的特权级概念

    上一篇文章学习了保护模式下操作系统内核如何加载程序并运行:点击链接查看上一篇文章 本篇文章接着上一篇文章学习保护模式下任务的隔离. 包括以下学习内容: 任务的全局空间和局部空间 任务的TSS 任务的L ...

  4. X86汇编语言从实模式到保护模式16:特权级和特权级保护

    目录 1. 特权级保护机制 1.1 基础段保护机制的不足 1.2 特权级划分 1.3 特权级的表示 1.3.1 当前特权级CPL 1.3.2 描述符特权级DPL 1.3.3 请求特权级RPL 1.4 ...

  5. 保护模式下的CPL,RPL,DPL与特权级检查(二)

    X86汇编语言:从事模式到保护模式读书笔记 ----------特权级保护 PS:此文并没有多长,只不过末尾附上了完整源代码占了90%的篇幅 <这是链接--保护模式下的RPL(一)--–> ...

  6. [书]x86汇编语言:从实模式到保护模式 -- 第14章 任务和特权级保护,调用门、LDT、TSS、TCB

    # 加载用户程序 Part 1.TCB, Task Control Block, 任务控制块 分配内存作为该任务的TCB,并插入至TCB链表. Part 2.LDT, Locak Descriptor ...

  7. 四,中断:中断程序(汇编和C语言)、idt、IDTR、8259A、8253以及发生中断时候的压栈细节和特权级保护

    中断: 由于CPU获知了计算机中发生的某些事,CPU暂停正在执行的程序,转而去执行处理该事件的程序,当这段程序执行完毕后,CPU继续执行刚才的程序,整个过程称为中断处理,也称为中断.没有中断,操作系统 ...

  8. x86 --- 任务隔离特权级保护

    程序是记录在载体上的数据和指令. 程序正在执行时的一个副本叫做任务 所有段描述符都放在GDT --> 不做区分. 内核程序(任务)所占段在GDT中,用户程序(任务)所占段在LDT中 --> ...

  9. 任务和特权级保护(五)——《x86汇编语言:从实模式到保护模式》读书笔记36

    任务和特权级保护(五)--<x86汇编语言:从实模式到保护模式>读书笔记36 修改后的代码,有需要的朋友可以去下载(c14_new文件夹).下载地址是: GitHub: https://g ...

最新文章

  1. php 二维数组排序函数,php自定义二维数组排序函数array
  2. c++ DirectShow播放任意格式的视频
  3. Mybatis 源码探究 (3)创建 SqlSessionFactory对象 执行sqlSession.getMapper()方法
  4. 2.关于QT中数据库操作,简单数据库连接操作,数据库的增删改查,QSqlTableModel和QTableView,事务操作,关于QItemDelegate 代理
  5. deepin-安装问题:unable to find a medium containing a live file
  6. Python学习笔记(四十六)网络编程(2)— UDP编程
  7. P3345 [ZJOI2015]幻想乡战略游戏
  8. ZOJ 1586 QS Network
  9. [vue] 移动端ui你用的是哪个ui库?有遇到过什么问题吗?
  10. Spring整合Mybatis之关联查询示例
  11. 【MySQL】MySQL每秒统计一次showglobal status
  12. CentOS 7.x 默认防火墙 yum install firewalld
  13. 去掉图标_小图标创建|精选博客
  14. 如何选择安全可靠的即时通讯软件
  15. python爬取二手房信息_使用Scrapy爬取链家二手房信息
  16. 生活随笔--拆弹专家
  17. 字符串str.format()方法的个人整理
  18. 微信也能鉴别山寨iPhone【微信高级教程2】
  19. 美颜SDK如何接入到硬件设备实现美颜拍摄?
  20. 简单 python 爬虫(一)

热门文章

  1. python发邮件怎么用服务器每天发_神级程序员的Python爬虫!服务器定时发邮件(知识点全面)...
  2. Arguments(函数参数对象)的属性和使用
  3. Treating Unicode character as whitespace
  4. 被任命为董事后 埃里森所持特斯拉股票账面损失已超过4亿美元
  5. Bentley ORD(openroads designer) 二次开发(BIM)第四节 界面设计数据绑定
  6. MLU100设备插件(Kubernetes)
  7. Python 爬虫批量下载美女图片,给枯燥的工作添加点乐趣!
  8. 一个女大学生手机里的短信
  9. ★★ 人人网开源软件、相关技术架构
  10. MySQL - 07 SQL函数的使用