Linux | 从虚拟地址到物理地址

前言

本章主要讲解虚拟地址是怎么转化成物理地址的,以及页表相关知识;本文环境默认为32位机器下;如果你连什么是虚拟地址都不知道可以先看看下面这篇文章;

Linux | 进程地址空间-CSDN博客

一、概念补充

**页表:**是一种数据结构,与硬件MMU配合可以将虚拟地址转化成物理地址,页表中主要建立虚拟地址与物理地址之间的映射;

**页框:**我们将真实物理内存以4KB为单位进行划分,其中每一个4KB我们称为一个页框;

**页框号:**识别页框的编号;

知识回顾:

之前我们讲解磁盘文件时,我们说过,通常进行一次IO的大小通常为4KB,即使你只修改1字节也是以4KB为单位将数据先加载进内存中;实际上,也正是加载进内存的空闲页框中;我们的磁盘文件也是以4KB进行划分;

我们还说过我们的一个可执行程序在编译后形成可执行程序,这个可执行程序实际上已经在内部进行分段,分好了虚拟地址空间了;我们可以直接使用编译好的虚拟地址;

二、地址转化过程

前面我们说过我们的物理内存会以4KB分为一个又一个页框;而操作系统是否需要维护这些页框呢?答案当然也是肯定的,我们可以将我们的页框用一种结构体描述起来,然后用数组维护这些页框,这样就有一个页框数组了,数组下标可作为页框号;假设一个为4GB的物理内存,可以有多少个页框呢?我们不难计算,4GB = 4 * 1024 * 1024 * 1024 Byte;

一个页框为4KB = 4 * 1024;两者相除,大约就是1024*1024,约一百万个;我们便可以用

struct page[1000000]; 即可表示所有物理内存中所有页框;
首先我要讲解的是我们的虚拟地址通过页表+MMU将我们的虚拟地址转换成物理内存中的物理地址,若我们页表中没有物理内存中的地址,而是只有磁盘中的地址,此时是因为我们的数据没有被加载进磁盘,可能之前发生或换出或本来没有加载进磁盘内;这是我们在物理内存中申请一块空闲的页框,我们找到空闲的页框后,我们将磁盘文件加载进指定的页框,同时我们也在页表上进行更新,将新映射的物理内存地址填上去;这个过程也就是我们常说的缺页中断

如果按上面的结构来看,页表中的每个条目记录一个虚拟地址映射一个物理地址,此时我们一共则需要 4 * 1024 * 1024 * 1024条记录(假设物理内存有4G);假设一条记录需要10个字节,那么一个页表的大小就需要40G;而我们的页表也是存在物理内存中呀!这显然是不可能存的下的,就算存的下也不可能消耗这么多内存资源存页表,况且一个进程就有一张用户级页表;计算机中绝对不止有一个进程;

此时,我们用另一种思路,我们页表中将虚拟地址的32个比特位分开看;其中前10位我们一起看,作为页目录的索引来找到二级页表,然后接着10位用来查找页框号,最后12个比特位用来记录页内偏移;如下图所示;

我们来计算一下,页目录最多有2^10,也就是1024条目录,对应着最多有1024个二级页表;每个二级页表也最有有2^10条目录,每条目录对应一个页框号,所有二级页表可以表示2^10 * 2^10 个页框,而我们的4GB内存最多也只有 2^20 个页框,刚好一一对应;最后12个比特位可以表示0到2^12 - 1,而2^12正好也就是4KB;也正好吻合;设页表每一条目为10字节,计算最大的情况下,总大小为 页目录大小(2^10 * 10 = 10KB)+ 所有二级目录大小(2 ^ 10 * 2 ^ 10 * 10 = 10MB);其中10KB可忽略,总大小最多为10M;这个大小比我们第一种方案要小了很多很多,这也是我们Linux下采用的方案;

相关推荐
阑梦清川1 分钟前
简明linux系统编程--互斥锁--TCP--UDP初识
linux·udp·tcp·互斥锁·信号·解锁·加锁
hardStudy_h5 分钟前
Linux——常用系统设置和快捷键操作指令
linux·运维·服务器
XF鸭44 分钟前
TCP 和 UDP 协议的区别?
linux
Flying_Fish_roe2 小时前
linux-安全管理-防火墙与网络安全
linux·数据库·oracle
不见长安见晨雾2 小时前
Linux:vim编辑技巧
linux·编辑器·vim
神秘的土鸡3 小时前
Linux中使用Docker容器构建Tomcat容器完整教程
linux·运维·服务器·docker·容器·tomcat
TravisBytes3 小时前
linux 系统是如何收发数据包
linux·运维·服务器
ice___Cpu5 小时前
Linux 基本使用和 web 程序部署 ( 8000 字 Linux 入门 )
linux·运维·前端
z202305085 小时前
linux 之0号进程、1号进程、2号进程
linux·运维·服务器
狐心kitsune5 小时前
erlang学习:Linux常用命令1
linux·学习·erlang