Linux可执行文件如何装载进虚拟内存

2022/1/5 7:08:07

本文主要是介绍Linux可执行文件如何装载进虚拟内存,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

开篇先抛出几个问题,之后逐个击破:

  • 什么是进程的虚拟地址空间?为什么进程要有自己的虚拟地址空间,这样做有什么好处?

  • 我们都听说过页映射,什么是页映射,操作系统为什么要以页映射方式将程序映射到进程地址空间,这样做有什么好处?程序运行过程中发生页错误如何处理?

  • 什么是进程?从操作系统的角度来看,进程是如何被建立的?

  • 进程虚拟地址空间的分布是什么样的?

  • Linux是如何装载并运行ELF程序的?

虚拟地址空间
what:虚拟地址空间就是我们常说的虚拟内存,虚拟内存是计算机系统内存管理的一种技术。它使得应用程序认为它拥有连续可用的内存(一个连续完整的地址空间),而实际上,它通常是被分隔成多个物理内存碎片,还有部分暂时存储在外部磁盘存储器上,在需要时进行数据交换。与没有使用虚拟内存技术的系统相比,使用这种技术的系统使得大型程序的编写变得更容易,对真正的物理内存的使用也更有效率。当处理器读取或写入内存位置时,都会使用虚拟地址。在读取或写入操作过程中,处理器会将虚拟地址转换为物理地址。

why:使用虚拟内存有如下好处:

程序员无需操心如何存储数据或者程序等内容。

程序可以使用一系列连续的虚拟地址来访问物理内存中不连续的大内存区域,用户看到的是连续地址,而无需关心更底层物理地址的排布。

通过使用虚拟内存,程序可以使用大于实际可用物理内存的空间,当物理内存不够用时,操作系统会将物理内存页保存在磁盘文件,数据页或者代码页会根据需要在物理内存和磁盘之间移动。

不同进程使用的虚拟地址彼此隔离,用户无需担心会影响到其它程序内存地址中的数据,操作系统的内存管理模块会将虚拟地址映射到物理地址。

页映射

background:程序运行时所需要的指令和数据必须放在内存中才可以正常执行,最简单的办法就是将运行所需要的指令和数据全部装进内存,但是很多时候程序需要的内存可能大于实际可用的物理内存,为了解决这种不够用的问题引入了动态装入的概念,可以将程序最常用的部分驻留在内存中,而将一些不常用的数据存在磁盘中。

what:页映射不是一次性将所有的程序和数据装入内存,而是将内存和磁盘中的数据和指令按页为单位分成若干份,以后所有的装载和操作的单位就是页。页的大小不固定,但是一般都是4096字节。

how:如下图,举个例子,可执行程序所需要的指令和数据总和占8个页,编号为VP0-VP7,而实际的物理内存只有4个页,编号为PP0-PP3,4个页的物理内存无法同时将8个页的程序都装载进去,所以需要动态装入,假设程序入口地址在VP0,这时内核发现VP0不在内存中,所以将VP0分配给了PP0,将VP0的内容装入了PP0,运行一段后程序需要用到VP2,内核又将VP2分配给了PP1,之后又用到VP4和VP6,内核又分别分配给了PP2和PP3。这时候程序只需要VP0、VP2、VP4和VP6这四个页就可以一直运行下去,如果程序又需要VP5,那内核就必须会放弃正在使用的四个内存页中的一个才可以把VP5装载进去继续执行,至于选择哪个,操作系统内核会有多种换出算法来处理这种问题。

why:其实上面已经介绍了原因,如果一次性把所有指令和数据都加载到内存中,物理内存可能不够用,所以需要使用动态装入,所以引入了页映射的方法。

进程如何被建立
这里首先需要弄清楚程序和进程的区别?程序(可执行文件)是一个静态的概念,它就是预先编译好的指令和数据集合的一个文件,进程则是一个动态的概念,它是程序运行的一个过程。

从操作系统角度看,一个进程最关键的特征是它拥有独立的虚拟地址空间,很多时候一个程序被执行都伴随着一个新的进程被创建,之后装载相应的可执行文件并运行。上述经历了什么步骤?

  • 创建一个独立的虚拟地址空间:这里的创建空间并不是真正的创建空间,而是创建映射函数所需要的数据结构,方便后面映射需要。

  • 读取可执行文件头,建立虚拟空间和可执行文件的映射关系:上面的映射数据结构是为了建立虚拟空间到物理内存的映射关系,这一步是虚拟空间与可执行文件的映射关系。

  • 将CPU的指令寄存器设置成可执行文件入口,启动运行:这里可以简单的理解为操作系统执行了一条跳转指令,跳转到可执行文件的入口地址。

页错误:当程序执行一个地址的指令时,发现是个空页面,所以就认为是个页错误,这时候控制权交由操作系统,操作系统有专门的错误处理程序处理这种情况,查询第二步骤建立的映射数据结构,找到空页面所在的虚拟内存区域,计算出相应的页面在可执行文件中的偏移,然后在物理内存中分配一个物理页面,将进程中的该虚拟页与物理页建立映射关系,控制权返还给进程,进程从页错误的位置继续执行。

link



这篇关于Linux可执行文件如何装载进虚拟内存的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程