操作系统中的页表与三级页表介绍

在操作系统与计组学习中,我们会学习到页表这个概念,可以说,如今计算机的函数内存调用有很大一部分都离不开页表的调用,本文旨在详解页表的概念应用以及操作系统中的三级页表,三级页表对于节省空间起了至关重要的作用

页表

为什么要有页表

首先我们需要了解操作系统中的内存分配,以小而精的操作系统xv6举例,整个系统主要由两部分组成,分别为内核区(kernal)用户区(user),在启动xv6系统后,会优先加载内核区中的代码,给内核区分配物理内存,以便用户能够调用内核区提供的指令,同时用户也可以在用户区自定义指令完成指令的执行,那么问题来了,用户程序执行必然分配内存,那么这个内存是优先分配好的吗?

答案是否定的,如果每个用户程序执行时都分配一定的物理内存,那么运行一定量的程序后系统就会由于内存不足而崩溃,同时每个程序内存需求量不同,固定量的分配也可能导致部分应用内存利用不充沛,其他应用内存不足等,因此操作系统在这里引入了虚拟内存的概念

所谓虚拟内存,就是系统为当前程序虚拟分配的内存,它不是真实存在的,而是在调用时再通过虚拟内存的映射找到对应的物理内存从而进行利用,而虚拟内存与物理内存之间的映射就由页表来实现,这样就保证了即使物理内存只有一部分,各个用户程序也可以通过内存的映射找到对应的物理内存进行使用,同时虚拟内存的存在也保护了内核区等重要代码的安全性,使得用户只可以操作用户区的内存代码

这里并不一定需要虚拟内存一定小于物理内存,虚拟内存可以远远大于物理内存,也可以小于物理内存,这完全由当前用户运行的程序数量及空间利用决定。

页表介绍

虚拟地址会被系统分割为4KB的页面,一般在64位操作系统中,每个虚拟地址(Virtual Address)可被划分为如下:

这里的EXT是并未使用的空间,也就是说,实际上出于硬件原因操作系统使用的只有39位,而这39位被划分为了一个个页面,每个页面为12位,即4kb

页表就是操作系统中存放了各个页面与当前虚拟内存的映射关系,用户程序可以通过页表将调用的虚拟地址转换到实际物理地址中,实际上的调用内存过程如下:

程序执行过程中,CPU 会通过MMU (内存管理单元,每个CPU都有,负责将虚拟地址转换为物理地址),将当前的VA (虚拟地址)转换为PA(物理地址),之后到相应的内存单元执行

页表条目

页表条目构成如下图:

Physical Page Number: 物理地址,44位,指向实际的物理内存地址

RSV: 被MMU忽略

V:当前页表条目是否生效(valid),如果设置说明当前页表条目生效

U:当前页表条目是否可以被用户空间访问

W:当前页表条目是否可写

页表工作流程

首先明确一点,物理地址在当前大多数操作系统中只使用了56位,并未使用全部

程序执行时,首先通过虚拟地址的index得到page number(页码)信息,通过页码信息找到页表中的对应条目,页表条目的44位PPN(Physical Page Number)对应于物理地址的前44位,而后12位页面内偏移量则由虚拟地址的offset决定,因此实际上的物理地址组成为:

物理地址(56位)= 页表(PPN)44位 + 虚拟地址offset(12位)

那么如果按照这样来为虚拟空间分配,实际的页表占用内存是多少呢?

虚拟地址的页码有27位,每个页表条目为8字节,那么占用内存为:

2^27 * 8 bit = 1GB,虽然看似不多,但是如果用户程序只使用了几个页表条目,但是还是要占用1GB的内存还是很恐怖的,因此科学家们想到了使用三级页表来代替单级页表

三级页表

所谓三级页表,就是将原来的虚拟地址的页码27位分为三级,每一级9位:

而原来的页表工作流程也变为下图:

通过虚拟地址转换时,首先通过前9位页码找到第一层页目录,第一层页目录中包含了中间页表的物理地址,通过物理地址找到中间页表,再通过中间页表的44位物理地址找到底层页表,底层页表的44位物理地址便指向了最后的实际调用物理地址,将此物理地址+原来虚拟地址的offset偏移量便找到了最后的实际地址,这里的物理地址表示为:

物理地址(56位) = 底层页表PPN(44位) + 虚拟地址offset(12位)

在三级页表的基础上,假设只使用了几个页面,那么中间层页表只需要加载0号页表即可,底层页表只需要加载要使用的几个页表项即可,中间层页表省了511个页面,底层页表省下了511*512个页面

简单理解,其实单级页表就是用长宽高之积来描述长方体,而三级页表就是用长、宽、高三个坐标来描述长方体,这样做的目的就是大大节省了加载页表所需要的空间

至此,有关于页表与三级页表的介绍就到这里了,页表的存在对于内核区与用户区加载代码起了至关重要的作用,真正理解页表的转换机制有助于我们对操作系统的虚拟内存有更深刻的认识

相关推荐
不穿格子的程序员37 分钟前
操作系统篇3——深入理解操作系统:Linux 常用命令、系统中断与用户态/内核态详解
linux·服务器·操作系统·内核态·用户态·中断
海棠蚀omo3 小时前
Linux信号保存的核心:未决信号集与阻塞信号集——探秘内核如何实现信号的阻塞、暂存与派发
linux·操作系统
不穿格子的程序员5 小时前
操作系统篇4——深入理解操作系统:僵尸进程、孤儿进程与进程调度算法详解
操作系统·僵尸进程·孤儿进程·进程调度
代码AC不AC1 天前
【Linux】计算机的基石:从冯·诺依曼体系结构到操作系统管理
linux·操作系统·冯诺依曼体系结构
序属秋秋秋2 天前
《Linux系统编程之进程环境》【环境变量】
linux·运维·服务器·c语言·c++·操作系统·系统编程
阿巴~阿巴~2 天前
自定义协议设计与实践:从协议必要性到JSON流式处理
服务器·网络·网络协议·json·操作系统·自定义协议
海棠蚀omo4 天前
解读Linux进程的“摩尔斯电码”:信号产生的原理与实践,掌控进程的生死时速
linux·操作系统
ZhengEnCi7 天前
P3H0-Python-os模块完全指南-操作系统接口与文件路径处理利器
python·操作系统
moringlightyn9 天前
Linux---进程状态
linux·运维·服务器·笔记·操作系统·c·进程状态
Live&&learn10 天前
数据结构vs 内存结构
数据结构·操作系统·内存结构