当前课程知识点:操作系统 > 第七讲 实验二 物理内存管理 > 7.1 了解x86保护模式中的特权级 > 7.1 了解x86保护模式中的特权级
各位同学我们这次课主要讲的是
操作系统的第二个实验
关于物理内存的管理
那我们原理课里面
其实对这个内存管理做了很深入的讲解
主要是说物理内存它的相关的一些细节
比如说怎么去建立映射关系
物理内存相应的一些它的作用等等
给大家做了一个讲解
那我们这里面是想结合实验让大家对
这个物理内存有一个更深入的理解
看看操作系统怎么来
对物理内存进行有效的管理
这里面有两个比较困难的地方
第一个是关于特权级
因为我们说操作系统加上我们的CPU
给我们不同的应用程序提供一个隔离的空间
这点需要有一个保护机制 那这是一个
第二个我们的应用程序不能够随随便便的去
访问我们的操作系统的空间
这一点也是通过保护机制来实现的
这里面有一个特权级这么一个概念
我们希望通过lab2让大家能够知道
操作系统怎么利用CPU的硬件机制来建立
所谓的保护机制
这是第一个特权级这一块给大家做一个讲解
第二部分是关于内存管理单元
X86的内存管理单元
那我们这里面讲的更多的是基于X86的
MMU 这个内存管理单元
来看我们操作系统怎么利用
这个MMU的功能来实现内存的映射
这实际上就是说可以把
我们的虚拟的连续地址空间
映射到分散的离散的物理空间里面去
这两者之间是有差别的
那么这个差别是通过我们的X86内存管理单元
在操作系统的管理之下来实现的
那这两点需要大家能够理解
所以我们这一讲主要是给大家讲一下
硬件到底做了什么事情
我们操作系统怎么利用
这个相应的一些机制来完成这些功能
从而可以实现操作系统物理内存的管理
首先我们看一下X86的特权级
那首先我们要知道就是这个硬件
我们CPU到底提供了几种特权级
然后我们的程序在跑的时候
我们的CPU到底当前处于哪样特权级
就是说你应用程序到底处于什么特权级
你怎么知道的 你的应用程序是在内核态跑的
还是在用户态跑的
第三个我们说我们的应用程序跑在用户态
但可能过了一会儿又跑到内核态
我们操作系统在运行 那么这个来回的切换
涉及到一个所谓的特权级的切换
那这个切换过程怎么实现的
这是我们说这一节里面要讲的内容
就是X86特权级的一个问题
好 那我们接下来看一下 第一个是了解特权级
我们看一下X86特权级
X86特权级你可以看到它有0 1 2 3
四个特权级 其中内核是处于0特权级
因为就是我们特权级最高的地方就在Level 0
那么我们的应用程序一般是放在Level 3
就是Applications 这个应用程序放在Level 3
那么也意味着应用程序
无法去破坏内核里面的代码或者数据
但是它可以得到内核态代码的服务
它可以得到它的服务
同时看到还有Level 1 Level 2
那么当时intel设计CPU的时候考虑比较灵活
说我们还有其它一些应用
也许需要更多的层级来做区分
但其实在我们现在的
操作系统设计里面一般来说
只需要两级
就是一个操作系统Kernel有一个级别
一个是我们应用程序有一个级别
就够了 基本上就够了
所以说对于我们lab2这个实验来说
它只需用Level 0和Level 3就够了
一个是用来给我们操作系统ucore来跑的
来访问数据和运行
执行一些特权指令等等
那么另外一个是我们应用程序
它跑到Level 3 这是我们说X86特权级里面
我们的操作系统怎么去利用的
那对于我们常见的操作系统
比如说Linux Windows等等
基本上也都是用了0和3这两个级别就够了
这是我们说X86特权级的一个情况
那我们说有一些指令它只能在ring 0里面执行
而这些指令是X86的一些特权指令
那这些指令一般也是我们操作系统来完成的
那我们应用程序
如果它一开始运行在用户态的时候
如果它要去执行这些特权指令
比如我们说的修改页表 响应中断
访问内核区域的数据的时候
比如我们说访问数据段 访问页表
还有访问中断服务例程去执行的时候
那就会产生异常 我们前面讲到
有中断 有异常 这是说的产生异常
产生异常之后就会阻止你继续执行
这是一种典型的保护机制
那么它是靠我们操作系统会做一个设置
在我们CPU这个硬件的管理之下来确保
我们的一般的应用程序处在
我们刚才说的处于ring 3
属于一般的特权级的情况下
它无法去访问ring 0下面的一些
所可以使用的一些特权指令
和对应的那些数据等等
那前面我们看到CPU在很多情况下
会做特权级检查 具体它怎么来做的
我们需要进一步去了解一下细节
接下来我们会接下来给大家介绍一下
包括选择子以及后面的描述符
怎么结合在一起来完成
这一条指令执行的特权级检查
那么为什么要这么做的呢
我们其实很重要的一点就是
我们在完成lab1 lab2以及后续的lab的时候
经常会出现各种各样的错误
而这些错误有一大部分情况
是跟特权级相关的
你如果理解了为什么会产生
这些异常或者错误
那么你就可以知道到底哪些地方你写错了
所以说我们这边需要了解内部CPU
是怎么来完成这个特权级检查的
我们首先介绍个概念
第一个概念是什么呢 段选择子
段选择子是位于我们的段寄存器里面的
那么我们可以说一个段
有代码段 有数据段
也意味着你的程序在代码段里执行
你的数据位于数据段空间中
那么一条指令去执行 它就会去访问
我们的代码段和数据段
而这个RPL以及后续讲到的CPL
它其实就是一个位于数据段
一个位于代码段
合在一起再和我们段描述符里面
所对应的DPL进行比较
有点复杂 没关系
大家可以逐步来看一下是怎么一回事
首先我们介绍的段选择子
这个段选择子第二步我们可以看到
它的DPL是位于什么呢
段描述符里面的 段描述符是什么东西
我们前面已经讲到过
段描述符是用来表示一个段的特征的
一个很重要的数据信息
我们这里面关注的跟特级权相关的
包括了一个DPL
就是跟这个段所相关的一个特权级
我们也看到了
前面说我们一项指令要访问一个段
那这个代表了这一个段
这一个数据段或者代码段
它特级权是什么样的
也意味着它前面讲的RPL和
这里面的DPL做一个比较
看这个特权级是否符合
很简单一个想法
就是我要去访问某一个数据
首先我的特权级要足够高
我才能访问某一个数据
那你的特权级在什么地方呢
那么大家可以看到
其实我们在前面lab1中已经提到过有中断
我们讲过中断
那中断 异常 陷入
其实都还是需要通过一定的特权级检查
所以在里面中断门
中断门是我们说前面讲到的
中断描述符表里面的重要组成部分
中断门 陷入门里面 它都有对应的DPL
这也是用来表明这个中断和
对应的陷入大致特权级的展现
我们前面已经讲到了
有段描述符 有中断门 有陷入门
那么这几个它们都有对应的DPL
而我们在产生中断
或者完成一次内存访问的时候
都会有对应的CPL和RPL
那么这个CPL RPL和DPL之间
有一个对应的特权级检查 从而可以确保
当前这个操作是否会产生特权级的一个错误
或者能够正常的通过特权级的检查
能够继续完成相应的操作 这就是我们说
这个特权级检查里面需要考虑的问题
我们看看怎么来比较
我们知道RPL DPL和CPL
我们是讲三个概念 RPL是处于数据段
比如说我们的DS ES FS和GS
那么它这里面是存了一个RPL
是当前你要访问的数据段对应的特权级
就是RPL 第二个你执行这条指令
指令有个所谓的代码段
那么指令的代码段存在哪呢
CS里面 CS里面对应了一个CPL
就是当前的一个代码段的一个特权级
这个就是CPL 那么也意味着我们一条指令
要访问一个数据段的时候
它有两个特权级的表示
一个是当前的特权级CPL
位于CS的最低两位
第二个是对应的要访问的数据段的RPL
也是处于对应的ES或者FS等等
它那个低两位有个RPL
这两个占了两个bit和前面说的X86里面的
四级特权级是一一对应的
那就是0到3 0代表最高的优先级
数值越低特权级越高 数值越高特权级越低
正好是倒过来的 那这是发出请求的一方
另一方面我们说你要访问的那个段
无论是通过中断访问代码段
还是通过内存访问 访问数据段
它都会有一个那个段的描述
就是无论是门还是段
它都有一个所谓的DPL
这个DPL代表了
你要访问的目标它的特权级
这个在什么情况下
RPL CPL 和DPL处于什么关系的时候
这个访问是合法的
哪些情况是访问的不合法的
这是我们说CPU检查的时候
需要重点考虑的内容
其实这个检查是挺简单的
大家可以看看 有两种情况
一种是针对我们说的中断 陷入 异常
这种情况称之为门情况
访问门的时候 它需要做两个判断
它当前的代码段CPL要小于门所处于的DPL
也意味着这个门的特权级要比较低
而我当前执行的代码段要比较高
这样才允许通过门
第二个CPL要大于等于DPL
这什么意思呢 通过门之后目的是什么呢
是要我们去访问特权级更高的段
有了这个约束之后
其实就可以实现我们的应用程序
一般的特权级的应用程序
就是我们说处于ring 3特权级的应用程序
可以访问处于内核态的操作系统提供的服务
这属于特权级ring 0的这个操作系统的服务
就是从低优先级的可以访问高优先级的代码
这是说通过我们说的中断门
陷阱门或者陷入门可以完成这个功能
那么在我们后续的lab5中
有应用程序的时候就可以看到这一点
我们用户态的进程可以通过这种方式
通过系统调用的方式
来获得我们操作系统的服务
从用户态切换到内核态
后续也会给大家进一步的讲解
第二个是关于访问段的一个表述
对于访问段而言也一样
我们说我们当前的代码段
和我们要访问的这个数据段
我们发出的数据段特权级的请求
一定要小于等于DPL这个段
那么这意味着什么呢 这意味着说
当前发出请求的这一方
就是当前处于代码段执行这条指令
它发出请求 我当前处于这种状态
我要去访问某一个数据段
那么我本身的特权级要高于对应的目标
你作为使用方
我的特权级要比较高一点我才能访问
那么对应的数值的比较呢
说就是小于等于
就是CPL和RPL最大的一个值
就是最低那个权限
要高于它所对应的目标的那个段的特权级
我们这里面数值上是小
在实际特权级比较上是高
这点正好是倒过来的 所以是小于等于
那么有了这两个表示之后
如果说它能够通过这个检查
也就意味着它的特权级的检查是合格的
那么我们这个指令可以正常去访问
如果通不过就会产生所谓的保护错
也是一种异常
-0.1 Piazza讨论区
--html
-0.2 在线实验平台
--实验平台使用帮助
--平台使用帮助
-0.2在线实验平台
--Raw HTML
-1.1 课程概述
--视频
-第一讲 操作系统概述--练习
-1.2 教学安排
--视频
-1.3 什么是操作系统
--Video
-1.4 为什么学习操作系统,如何学习操作系统
--Video
-1.5 操作系统实例
--视频
-1.6 操作系统的演变
--视频
-1.7 操作系统结构
--视频
-2.1 前言和国内外现状
-2.2 OS实验目标
-2.3 8个OS实验概述
-2.4 实验环境搭建
-2.5 x86-32硬件介绍
-2.6 ucore部分编程技巧
-2.7 演示实验操作过程
--Q6
--Q7
--Q10
-3.1 BIOS
--3.1 BIOS
-3.2 系统启动流程
-3.3 中断、异常和系统调用比较
-第三讲 启动、中断、异常和系统调用--3.3 中断、异常和系统调用比较
-3.4 系统调用
--3.4 系统调用
-第三讲 启动、中断、异常和系统调用--3.4 系统调用
-3.5 系统调用示例
-3.6 ucore+系统调用代码
-4.1 启动顺序
--4.1 启动顺序
-4.2 C函数调用的实现
-4.3 GCC内联汇编
-4.4 x86中断处理过程
-4.5 练习一
--4.5 练习一
-4.6 练习二
--4.6 练习二
-4.7 练习三
--4.7 练习三
-4.8 练习四 练习五
-4.9 练习六
--4.9 练习六
-5.1 计算机体系结构和内存层次
-5.2 地址空间和地址生成
-5.3 连续内存分配
-5.4 碎片整理
--5.4 碎片整理
-5.5 伙伴系统
--5.5 伙伴系统
-第五讲 物理内存管理: 连续内存分配--5.6 练习
-6.1 非连续内存分配的需求背景
-6.2 段式存储管理
-- 6.2 段式存储管理
-6.3 页式存储管理
-6.4 页表概述
--6.4 页表概述
-6.5 快表和多级页表
-6.6 反置页表
--6.6 反置页表
-6.7 段页式存储管理
-第六讲 物理内存管理: 非连续内存分配--6.8 练习
-7.1 了解x86保护模式中的特权级
-第七讲 实验二 物理内存管理--7.1 了解x86保护模式中的特权级
-7.2 了解特权级切换过程
-第七讲 实验二 物理内存管理--7.2 了解特权级切换过程
-7.3 了解段/页表
-第七讲 实验二 物理内存管理--7.3 了解段/页表
-7.4 了解UCORE建立段/页表
-第七讲 实验二 物理内存管理--7.4 了解UCORE建立段/页表
-7.5 演示lab2实验环节
-8.1 虚拟存储的需求背景
-8.2 覆盖和交换
-8.3 局部性原理
-8.4 虚拟存储概念
-8.5 虚拟页式存储
-8.6 缺页异常
--8.6 缺页异常
-9.1 页面置换算法的概念
-9.2 最优算法、先进先出算法和最近最久未使用算法
-第九讲 页面置换算法--9.2 最优算法、先进先出算法和最近最久未使用算法
-9.3 时钟置换算法和最不常用算法
-第九讲 页面置换算法--9.3 时钟置换算法和最不常用算法
-9.4 Belady现象和局部置换算法比较
-第九讲 页面置换算法--9.4 Belady现象和局部置换算法比较
-9.5 工作集置换算法
-第九讲 页面置换算法--9.5 工作集置换算法
-9.6 缺页率置换算法
-第九讲 页面置换算法--9.6 缺页率置换算法
-9.7 抖动和负载控制
-10.1 实验目标:虚存管理
-第十讲 实验三 虚拟内存管理--10.1 实验目标:虚存管理
-10.2 回顾历史和了解当下
-第十讲 实验三 虚拟内存管理--10.2 回顾历史和了解当下
-10.3 处理流程、关键数据结构和功能
-第十讲 实验三 虚拟内存管理--10.3 处理流程、关键数据结构和功能
-10.4 页访问异常
-第十讲 实验三 虚拟内存管理--10.4 页访问异常
-10.5 页换入换出机制
-第十讲 实验三 虚拟内存管理--10.5 页换入换出机制
-11.1 进程的概念
-第十一讲 进程和线程--11.1 进程的概念
-11.2 进程控制块
-第十一讲 进程和线程--11.2 进程控制块
-11.3 进程状态
-第十一讲 进程和线程--11.3 进程状态
-11.4 三状态进程模型
-11.5 挂起进程模型
-第十一讲 进程和线程--11.5 挂起进程模型
-11.6 线程的概念
-第十一讲 进程和线程--11.6 线程的概念
-11.7 用户线程
-第十一讲 进程和线程--11.7 用户线程
-11.8 内核线程
-第十一讲 进程和线程--11.8 内核线程
-12.1 进程切换
-第十二讲 进程控制--12.1 进程切换
-12.2 进程创建
-第十二讲 进程控制--12.2 进程创建
-12.3 进程加载
-第十二讲 进程控制--12.3 进程加载
-12.4 进程等待与退出
-第十二讲 进程控制--12.4 进程等待与退出
-13.1 总体介绍
-13.2 关键数据结构
-13.3 执行流程
-13.4 实际操作
-14.1 总体介绍
-14.2 进程的内存布局
-14.3 执行ELF格式的二进制代码-do_execve的实现
--14.3 执行ELF格式的二进制代码-do_execve的实现
-14.4 执行ELF格式的二进制代码-load_icode的实现
--14.4 执行ELF格式的二进制代码-load_icode的实现
-14.5 进程复制
-14.6 内存管理的copy-on-write机制
-15.1 处理机调度概念
-第十五讲 处理机调度--15.1 处理机调度概念
-15.2 调度准则
-15.3 先来先服务、短进程优先和最高响应比优先调度算法
--15.3 先来先服务、短进程优先和最高响应比优先调度算法
-第十五讲 处理机调度--15.3 先来先服务、短进程优先和最高响应比优先调度算法
-15.4 时间片轮转、多级反馈队列、公平共享调度算法和ucore调度框架
--15.4 时间片轮转、多级反馈队列、公平共享调度算法和ucore调度框架
-第十五讲 处理机调度--15.4 时间片轮转、多级反馈队列、公平共享调度算法和uc
-15.5 实时调度和多处理器调度
-第十五讲 处理机调度--15.5 实时调度和多处理器调度
-15.6 优先级反置
-第十五讲 处理机调度--15.6 优先级反置
-16.1 总体介绍和调度过程
-16.2 调度算法支撑框架
-16.3 时间片轮转调度算法
-16.4 Stride调度算法
-17.1 背景
--17.1 背景
-17.2 现实生活中的同步问题
-第十七讲 同步互斥--17.2 现实生活中的同步问题
-17.3 临界区和禁用硬件中断同步方法
-第十七讲 同步互斥--17.3 临界区和禁用硬件中断同步方法
-17.4 基于软件的同步方法
-第十七讲 同步互斥--17.4 基于软件的同步方法
-17.5 高级抽象的同步方法
-第十七讲 同步互斥--17.5 高级抽象的同步方法
-18.1 信号量
--18.1 信号量
-第十八讲 信号量与管程--18.1 信号量
-18.2 信号量使用
-第十八讲 信号量与管程--18.2 信号量使用
-18.3 管程
--18.3 管程
-第十八讲 信号量与管程--18.3 管程
-18.4 哲学家就餐问题
-18.5 读者-写者问题
-19.1 总体介绍
-19.2 底层支撑
-第十九讲 实验七 同步互斥--19.2 底层支撑
-19.3 信号量设计实现
-第十九讲 实验七 同步互斥--19.3 信号量设计实现
-19.4 管程和条件变量设计实现
-第十九讲 实验七 同步互斥--19.4 管程和条件变量设计实现
-19.5 哲学家就餐问题
-20.1 死锁概念
-第二十讲 死锁和进程通信--20.1 死锁概念
-20.2 死锁处理方法
-第二十讲 死锁和进程通信--20.2 死锁处理方法
-20.3 银行家算法
-第二十讲 死锁和进程通信--20.3 银行家算法
-20.4 死锁检测
-第二十讲 死锁和进程通信--20.4 死锁检测
-20.5 进程通信概念
-第二十讲 死锁和进程通信--20.5 进程通信概念
-20.6 信号和管道
-第二十讲 死锁和进程通信--20.6 信号和管道
-20.7 消息队列和共享内存
-第二十讲 死锁和进程通信--20.7 消息队列和共享内存
-21.1 文件系统和文件
-第二十一讲 文件系统--21.1 文件系统和文件
-21.2 文件描述符
-第二十一讲 文件系统--21.2 文件描述符
-21.3 目录、文件别名和文件系统种类
-第二十一讲 文件系统--21.3 目录、文件别名和文件系统种类
-21.4 虚拟文件系统
-第二十一讲 文件系统--21.4 虚拟文件系统
-21.5 文件缓存和打开文件
-第二十一讲 文件系统--21.5 文件缓存和打开文件
-21.6 文件分配
-第二十一讲 文件系统--21.6 文件分配
-21.7 空闲空间管理和冗余磁盘阵列RAID
-第二十一讲 文件系统--21.7 空闲空间管理和冗余磁盘阵列RAID
-22.1 总体介绍
-第二十二讲 实验八 文件系统--22.1 总体介绍
-22.2 ucore 文件系统架构
-第二十二讲 实验八 文件系统--22.2 ucore 文件系统架构
-22.3 Simple File System分析
-第二十二讲 实验八 文件系统--22.3 Simple File System分析
-22.4 Virtual File System分析
-第二十二讲 实验八 文件系统--22.4 Virtual File System分
-22.5 I/O设备接口分析
-第二十二讲 实验八 文件系统--22.5 I/O设备接口分析
-22.6 执行流程分析
-23.1 I/O特点
--视频
-第二十三讲 I/O子系统--23.1 I/O特点
-23.2 I/O结构
--816C80A0F5E3B8809C33DC5901307461
-第二十三讲 I/O子系统--23.2 I/O结构
-23.3 I/O数据传输
--C58221E14388B9DB9C33DC5901307461
-第二十三讲 I/O子系统--23.3 I/O数据传输
-23.4 磁盘调度
--567A3F1FCBFB3F4C9C33DC5901307461
-第二十三讲 I/O子系统--23.4 磁盘调度
-23.5 磁盘缓存
--C327536B80D25CE79C33DC5901307461
-第二十三讲 I/O子系统--23.5 磁盘缓存
-html
--html