虚拟内存的作用是什么 虚拟内存有什么用( 六 )


多个进程可共享相同的对象 , 虚拟地址可以有差异 , 但差异必须是页大小的倍数

虚拟内存的作用是什么  虚拟内存有什么用

文章插图

6.3.2 私有的写时复制对象
虚拟内存的作用是什么  虚拟内存有什么用

文章插图

对于每个映射私有对象的进程 , 相应私有区域的页表条目都被标记为只读 , 且该区域被标记为私有的写时复制 。 一旦写入则触发保护错误 , 处理程序在主存中创建试图写私有的写时复制区域中的一个页面该页面的信服本 , 更新页表条目指向该新副本 , 再恢复该页面可写权限 。 指令在处理程序返回时重新执行 , 拷贝尽可能被推迟 。
虚拟内存的作用是什么  虚拟内存有什么用

文章插图

再看fork函数 , 当被当前进程调用时 , 创建当前进程的mm_struct、区域结构和页表的原样副本 。 将两个进程中的每个页面都标记为只读 , 并将两进程中每个区域结构都标记为私有的写时复制 。 fork返回时 , 新进程虚拟内存和调用fork时存在的虚拟内存相同 , 当两进程中任一个后来进行写操作 , 写时复制机制就创建新页面 , 因此也就为每个进程保持私有地址空间的抽象概念 。
再看execve假设执行execve(“a.out”,NULL,NULL)该函数在当前进程中加载并运行包含在可执行目标文件a.out中的程序 , 用a.out替代当前程序 , 需以下步骤:
删除已存在的用户区域:删除当前进程虚拟地址的用户部分中的已存在的区域结构
映射私有区域:为新程序代码、数据、bss和栈区域常见新的区域结构 , 所有这些新区域都是私有的、写时复制的
映射共享区域:若a.out程序与共享对象链接 , 先动态链接 , 再映射到用户虚拟地址空间中的共享区域内
设置程序计数器:设置当前进程上下文中的程序计数器 , 使之指向代码区域入口点
6.3.3 找到可共享的页内核相同页归并:
系统扫描所有物理内存 , 寻找重复页 , 找到则归并为单个页 , 标记为写时拷贝
在2009年的Linux内核实现 , 仅限于标记为可能的页 , 特别是处理器运行许多虚拟机时特别有用
6.3.4 用户模式的内存映射函数void *mmap(void *start, int len,int prot, int flags, int fd, int offset) , 从文件描述副fd指定的文件偏移量offset , 从start地址(可能为0)开始映射len字节 , prot表示权限(PROT_READ、PROT_WRITE、 PROT_EXEC) , flags表示映射权限(MAP_ANON、 MAP_PRIVATE、MAP_SHARED等) , 返回映射区域开始的指针(可能不是start)
虚拟内存的作用是什么  虚拟内存有什么用

文章插图

6.3.5 mmap的使用使用分页机制将大文件读入内存 , 共享数据结构 , 当调用带MAP_SHARED的标签时 , 多进程可访问相同内存区域 , 很危险 。 基于文件的数据结构例如数据库 , 将prot设置为PROT_READ和PROT_WRITE , 当解除映射时 , 文件通过写入被更新 , 通过文件加载/更新/写回文件实现 。
6.3.6 用mmap实现attack lab当机器堆栈不能执行时 , 如何通过代码注入进行攻击 , 解决方法是使用mmap分配内存并标记为可执行 , 转移堆栈到该区域 , 执行攻击代码 , 恢复原来堆栈 , 移除映射区域 。
虚拟内存的作用是什么  虚拟内存有什么用

文章插图

虚拟内存的作用是什么  虚拟内存有什么用

文章插图

7 动态内存分配程序员通过动态内存分配器(如 malloc)让程序在运行时得到虚拟内存 , 因为程序经常直到实际运行时才知道某些数据结构大小 。 动态内存分配器管理一个虚拟内存区域 , 称为堆(heap) 。