当前课程知识点:操作系统 > 第七讲 实验二 物理内存管理 > 7.4 了解UCORE建立段/页表 > 7.4 了解ucore建立段/页表
好 我们接下来看看
怎么来建立这个页的映射机制
为了能够理解这个机制
我们首先去了解一下我们整个这个
X86 CPU里面怎么来完成
基于页机制的一个地址映射的
它的硬件操作过程怎么回事
那可以看这幅图
这里面假定已经建好了一个
所谓的页目录表 页表
这一块是它的物理内存
对于一个地址 我们说一个虚拟地址
它分了三块 分了三部分
这实际上是一个典型的二级页表
第一个是Offset这是32位的地址
占了12位 那么中间的二级页表
对应的页表项占了10位
高的页目录项也占了10位
那么高的这10位是用来去查找
作为index查找这个页目录表里面的对应的项
这叫PDE
就是页目录的entry 在PDE记录什么信息
PDE记录的是二级页表里面的起始地址
可以放在这个地方
所以说根据PDE里面的信息
可以找到Page Table的起始地址
同时根据第二级Table这里面的10位
作为index来查这个Page Table对应的项
称之为PTE
这个PTE就是Page Table Entry
它里面存的什么
存的是你这个线性地址
它所对应的一个页的起始地址
这一个页大小多少
其实由它的Offset可以算出来
它12位 那意味着一个页的大小是4K
那这里面PTE里面会存到
这么一个页的起始地址
它会按照4K地址来对齐
那么这个作为Base Address
来加上它Offset
来形成最终的这个物理地址
这就形成了物理地址
这是说在X86里面完成的一个
基于二级页表的一个地址映射关系
那你可以看出来我们的硬件是
这么来查找一个线性地址
怎么转到一个物理地址
那它为什么不是虚拟地址
而称之为线性地址 大家想想
因为我们前面说到了
进入保护模式之后这个段机制是一定存在的
即使这个00映射 我们说的对等映射存在
你也不能说为此把段
这个映射关系给取消掉
这是它必须存在的一个很重要的原因
也是为了上下兼容 所以这是线性地址
那其实这个线性地址和
我们说应用程序虚拟地址是一样的
因为它是对等映射
我们既然知道了这么一个映射关系
我们来看一看 看一个实际的例子
怎么能够把一个所谓的线性地址
或者是虚拟地址转换成一个物理地址
那我们需要建好这个页目录表
需要建好这个页表 以及才能找到对应的页
那么页目录表和页表它其实也是4K大小
那么每一项每一个PTE
或者PTE是32位的一项
那意味着4K存1024项
那我们需要把这里面的信息填对了
才使得对于一个虚拟的地址
这是一个虚拟地址 32位的虚拟地址
0xC后面是1234567
这随便举了一个例子
它这个虚拟地址对应的物理地址多少
可以算出来
它实际上是根据这里面的
PDE PTE来算的
首先来看一下 它的高10位
它的高10位其实是这里面
你数这10项实际上这10项
它其实代表的是304
需要注意了一下这个304
那意味着我们需要查
1024项里面的第0x304项
找到这个地方之后这里面会存一个信息
这个信息比如说存的是0x233
0x233它是按照4K来做一个偏移
偏移了12位 向右偏移12位
所以把它向左再偏移12位
形成0x233000这么一个地址
这个地址实际上是我们说
它存的是Page Table的一个物理地址的基址
找到这个Page Table之后
我们的CPU会查中间10位
中间10位实际上对应的是0x234
234作为index
找到PDE PDE存的什么
存的是0x22333
同样它也是按照4K对齐 右移了12位
所以我们把它通过左移12位
得到正确的你所对应的物理页的基址
就是0x22333后面3个0正好是12位
这是这个物理页的基址
加上它的Offset Offset是它的低12位
0x567 那么合在一起就形成了最终的物理地址
就是0x22333加上567
这就是它的物理地址
所以说可以看到我们需要在lab2里面
来完成对这两个表的建立
从而可以实现正确的映射关系
另外还要提醒一下 就是在这里面存的
就比如说在页表项里面
存放的地址内容是线性地址
那这里面还有一点是
第一个页目录的起始地址在哪儿
这里面其实已经看到了
它是一个特殊的寄存器 称之为CR3寄存器
这个CR3寄存器来保存了
页目录的表的起始地址
那为什么只要一个CR3就够了呢
因为它是二级页表 二级页表里面的
页目录表这个4K的页目录表只有一个
所以我们只需要一个CR3寄存器就够了
好 我们前面已经把页表的映射机制
给大家做了一个介绍
接下来我们可以看看对于页表
或者页目录表里面的一项
到底包含了哪些关键信息 作为一个理解
这里面列出来了页目录表项和页表项
它的一个大致的属性的表示
一共是32位 一个页表项
和一个页目录表项是32位
我们这里面除了关注它
所谓的基址记录之外
还需要关注里面的一些属性位
因为基址 就是存放的无论是页的基址
还是页表的基址
物理页的基址 或者页表的基址都是20位
还有剩下12位形成32位这么一项
那么那12位其实很重要的信息
就是低12位 低12位存了一些属性
就你将来访问页的一些属性
比如说这个页是否是只读的
用R/W位来表示
这个页是内核态访问的还是用户态能访问的
那么有一个U/S 是user还是supervisor
就是属于一般用户访问的
还是超级用户访问的
实际上就对应我们的用户态和内核态
那么其实和我们前面说的
段的安全保护机制有异曲同工之妙
只是说基于段的保护机制它更加灵活
它可以表示一个可大可小的一块区域
到底是属于用户态还是内核态
它的特权级是ring 0 ring 1
ring 2 ring 3它有四级
而对于页表而言 它就两级
就是用户态和内核态 当然这也够了
对我们前面讲到操作系统来说
你只有两级是完全够的
还有其它一些位我们讲内存管理的时候
会再逐步展开
它这些位可以有效的用来
做内存的一些有效的管理
那我们假定你建立好什么 建立好页表
页目录表 都建好了
这是我们ucore操作系统来建立的
建好之后我们要使能页机制
这和我们前面说的段机制是一样的
保护模式一样的
你需要对一个特定的寄存器
这里面是CR0的一个PG寄存器
它最高位 31位
前面是最低位 最低位来enable保护模式
那么我们最高位31位
CR0的寄存器 31位 如果给它置1的话
就代表启动了页机制
这就是这个特殊的寄存器
它是一个需要在内核态访问的一个寄存器
好前面我给大家介绍一下CPU硬件的
一个对内存的页表的机制建立的过程
它的访问过程
那我们操作系统怎么来使这个能正常运作
我们ucore其实为此做了一系列的工作
比如说我们前面说要分配页
因为我们前面已经讲到了
我们的内核以及ucore已经有一套
基于连续内生存的一个
内存分配的一套算法和机制
从而可以说我们分配一个页
分配一个4K来作为一个页目录的一个table
然后再把这个里面的page给清掉
清掉是为了做初始化
然后你需要对除了这个页目录表之外
还要建立对应的页表
来对一定空间的内存来建立对应关系
为此你需要在页目录表和页表里面
填好相应的项
那我们这里面建立的映射关系是什么
0xC0000000到0xF8000000
这块空间会映射到物理地址的
0x00000000到0x38000000这么一个地址
那这个其实是可以看出来
它们的偏移值就是0xC0000000的偏移值
虚拟地址比物理地址要多出来0xC0000000
那实际上映射的是内核空间
使得我们内核态的代码和数据
都是在0xC0000000这个之上的一个空间
那这个和我们在lab2时候
你可以看到它在编译 链接
形成最后的uCore代码的时候
它链接时候用的起始地址就是0xC0000000
这是对应起来的
同时我们又建立了一个很奇怪的一个映射
就是0x00000000-0x00100000虚拟地址
映射到0x00000000-0x00100000这物理地址
这是一个对等映射
按道理说我们建好这个映射就OK了
为什么还要建立一个对等映射
且在enable了
把这个CR0的31位给它置1之后
enable了的页机制之后
我们再次更新了GDT
为什么要update GDT
是由于我们的页机制已经起作用了
页机制来完成从0xC0000000到0的映射
就是0xC0000000是虚拟地址 0是物理地址
这个映射靠页机制完成了
那我们段机制只需要完成对等映射就OK
就0-0映射就行了
那我们说update GDT之后
其实就是让我们段机制映射的关系
从之前的不是那种对等映射变成对等映射
但变成对等映射之后它又做了一次取消操作
就刚才这里面会有一步
就是完成从0到0x100000的映射
这里面又取消了0到0x100000的映射
这个映射是页机制的映射
把它取消了 有点多余好像感觉
做了一步又取消了 为什么
大家思考一下 作为一个练习
大家想一想怎么来解决
那所有的这些代码
是放在pmm.c里面来实现的
这是ucore里面的一个文件
专门属于管理页表机制的
假设我们这个页表建立好了
接下来我可能需要你再去完成
再完成一个特定的内存的映射
这时候你就可能需要去对
这个PTE PDE来做一个处理
甚至还会涉及说
如果我们这个内存它属于
另一块空间我们现在页表
我们现在页表它没有对应到
所以说我们需要干什么建立一个新的页表
这就是我们的一个作业 我们练习
你尝试着给你一个虚拟地址和物理地址
你尝试着能不能分配一个对应的页表项
使得虚拟地址能够正确的
映射到对等的物理地址
这就是我们说在页表里面来建立
页的这个映射关系的这么一个练习
作为我们这个lab2的一个主要的完成部分
需要大家去完成
好我们最后再看一下对于X86而言
它确实比较全面
既包含了段机制 也包含了页机制
虽然我们这里面弱化了段机制这个映射关系
但其实通过这个段和页一个组合
我们可以形成一个更灵活的组织方式
当然在现在操作系统里面主要
还是用页机制来完成了整个的映射
段机制它的作用更多的体现在安全管理上面
那其实即使在安全管理上面
段和页也有一定的重复
在X86里面有一定的重复
所以说可以看到我们会根据
具体的运用情况来了解
好 这是列出来在intel
那个系统软件软件开发手册里面
对应的章节
它对页表机制有更深入的讲解
站在硬件的角度
怎么去便于软件开发人员
去理解这个页机制
可以看一看
好那这就是这一讲的内容 谢谢大家
-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