Linux内核原理之进程地址空间

进程地址空间

用户层进程的虚拟地址空间是Linux的一个重要抽象:它向每个运行进程提供了同样的系统视图,使得多个进程可以同时运行,而不会干扰其他进程内存中的内容

简介

本章主要关注用户管理虚拟地址空间的方法

  • 每个应用程序都有自身的地址空间,与所有其他应用程序分隔开
  • 在巨大的线性结构地址空间中,只有很少的段可用于各个用户空间进程,这些段彼此有一定的距离(内核需要一些数据结构来管理这些随机分布的段)
  • 地址空间只有极小的一部分与物理内存页直接关联,不经常使用的部分,则仅当必要时与页帧关联
  • 各个操作用户地址空间的操作都伴随着各种检查,以确保程序的权限不会超过应有的限制

进程虚拟地址空间

进程地址空间的布局

虚拟地址空间中包含了如下区域:

  • 二进制代码,所处的虚拟内存区域为text段
  • 程序使用的动态库的代码
  • 存储全局变量和动态产生数据的堆
  • 用于保存局部变量和实现函数/过程调用的栈
  • 环境变量和命令行参数的段
  • 将文件内容映射到虚拟地址空间的内存映射

系统的各个进程包含一个struct mm_struct的实例,通过task_struct访问,这个实例保存了进程的内存管理信息

在这里插入图片描述

  • start_code和end_code标记了可执行代码的虚拟地址空间区域的开始和结束,start_data和end_data标记了已初始化数据的区域(注意:在ELF二进制文件映射到地址空间之后,这些区域的长度不再改变)
  • start_brk保存了堆的起始地址,brk表示堆区域当前的结束地址
  • 参数列表和环境变量的位置分别由arg_start和arg_end、env_start和env_end描述,两个区域位于栈中最高的区域
  • mmap_base:表示虚拟地址空间中用于内存映射的起始地址,调用get_unmapped_area在mmap区域中为新映射找到适当的位置

在这里插入图片描述

如图是大多数体系结构虚拟地址空间的分布情况,text如何映射到虚拟地址空间由ELF文件标准确定。每个体系结构指定了特定的其实地址:IA-32系统起始于0x08048000,在text段的起始地址与最低的可用地址之间有大约128MiB的间距,用于捕获NULL指针。堆紧接着text段开始,向上增长

栈起始于STACK_TOP,如果设置了PF_RANDOMIZE,则起始点减少一个小的随机量(大多数体系结构都将STACK_TOP设置为TASK_SIZE)

用于内存映射的区域起始于mm_struct->mmap_base,通常设置为TASK_UNMAPPED_BASE,每个体系结构都需要定义它

内存映射的原理

考察通过文本编辑器操作文件的情况。通常用户只关注文件结尾处,尽管整个文件都映射到内存中,但实际上只使用了几页来存储文件末尾的数据;至于文件开始出的数据,内核只需要在地址空间保存相关信息,如数据在磁盘上的位置以及需要数据时如何读取(text段也是类似,始终只需要其中的一部分)

因此,文本编辑器只需要加载与主要编辑功能相关的代码,其他部分(如帮助系统或web和电子邮件客户端程序)是会在用户明确要求时才加载

如图所示,内核提供了数据结构以建立地址空间区域和相关数据所在位置之间的关联(例如,在映射文本文件时,映射的虚拟内存区必须关联到文件系统在硬盘上存储文件内容的区域)

在这里插入图片描述

内核利用address_space数据结构,提供了一组方法从后备存储器读取数据。例如,从文件系统读取时,address_space形成了一个辅助层,将映射的数据表示为连续的线性区域,提供给内存管理子系统

按需分配和填充页称之为按需调页法,它基于处理器和内核之间的交互,使用的各种数据结构如下图

在这里插入图片描述

数据结构

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值