虚拟内存空间的映射和虚拟区域的建立

本文深入探讨了虚拟内存机制,包括其如何使计算机操纵更大的地址空间、硬件的虚拟内存机制、内存映射以及如何实现进程间的内存共享。重点介绍了动态链接库和bash程序在多个进程中的应用,同时详细解释了Linux中内存映像的概念,以及内存映像如何在内存中存放可执行程序文件,并通过do_mmap()函数进行内存区域映射。

虚拟内存可以使计算机操纵更大的地址空间,使系统中的每一给进程拥有独立的虚拟地址空间,所以运行一个程序的进程不会影响到其他进程。

另外,硬件的虚拟内存机制允许对内存区写保护,这可以防止代码和数据被错误的程序覆盖。内存映射可以将cpu的虚拟地址空间映射到物理内存。

虚拟内存机制虽然允许进程拥有独立的地址空间,但有时也需要进程之间共享内存。有些程序会被多个进程运行(bash),此时更好的方法是

再物理内存中只拥有一份bash的代码,所有运行bash的进程共享代码。动态链接库也是一个常见的多个进程共享执行代码的的常见例子。

linux虚存采用动态地址映射方式,也就是说进程的地址空间和存储空间的对应关系是在程序执行的过程中实现的。进程使用的是虚拟地址,因此

他对每个地址的访问都需要通过MMU转化为内存的物理地址。

动态地址映射可以使linux 实现进程在主存中的动态重定位、虚拟内存的动态扩展和移动,也为虚拟内存的实现提供了基础。当linux的进程映像执行

时,需要调入可执行映像的内容(相关代码)。但是不用把这些数据直接调入物理内存,只需要将这些数据与虚拟地址空间关联起来。只有当正真执行

需要先关数据时才真正调入内存。这种进程的映像和虚拟地址空间的连接称为内存映像

当需要将进程的映像调入到进程的虚拟内存空间时,需要申请一段合适的虚拟内存空间,这时linux使用do_mmap()  函数完成可执行映像向虚存区域的

映射,建立有关虚存区域,/include/linux/mm.h文件中:

static inline unsigned long do_mmap(struct file *file, unsigned long addr,
	unsigned long len, unsigned long prot,
	unsigned long flag, unsigned long offset)
{
	unsigned long ret = -EINVAL;
	if ((offset + PAGE_ALIGN(len)) < offset)
		goto out;
	if (!(offset & ~PAGE_MASK))
		ret = do_mmap_pgoff(file, addr, len, prot, flag, offset >> PAGE_SHIFT);
out:
	return ret;
}


file  指向该文件结构体的指针;

addr 虚存区域在虚拟内存空间的起始地址;

len  虚存区域的长度;

prot  指定了虚存区域的访问特性;

flag  制定了虚存区域的属性;

offset  相对于文件起始位置的偏移量;


内存的映像详解:

首先,什么叫做内存映像呢? 进程的内存映像,指的是内核在内存中如何存放可执行程序文件。注意了,这里的可执行程序文件和内存映像是有区别的,,具体是: 
1) 可执行程序是位于硬盘上的,而内存映像位于内存上; 
2) 可执行程序没有堆栈,因为只有当程序被加载到内存上的时候才会分配相应的堆栈 
3) 可执行程序是静态的,因为它还没运行,但是内存映像是动态的,数据是随着运行过程改变的;


尽管程序映像看起来占据了一个连续的内存块,但实际上,操作系统将程序映像映射到不一定连续的物理内存块中。通常的映射将程序映像划分成大小相同的片,这些片被称为页(PAGE)。操作系统将这些页加载到内存中,当处理器引用某页上的内存时,操作系统会从一个表中查找这一页的物理位置。这种映射方式允许栈和堆有很大的逻辑地址空间,除非需要,否则这些栈和堆实际上可以不占用物理内存。操作系统隐藏了这种底层映射的存在,这样,即使有些页实际上并没有驻存在内存中,程序员也可以认为程序映像在逻辑上是连续的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值