简介

在这片文章中,我介绍了关于进程的地址空间的相关内容,首先介绍了进程地址空间的定义,和它的大小,然后介绍了在内核源码中实现的方式mm_struct,之后介绍了其中进程能够访问的部分VMA,以及VMA在内核源码中实现的结构

参考

Linux内核设计与实现 第15章节

https://zhuanlan.zhihu.com/p/66794639

感谢

Photo by Tanguy Sauvin: https://www.pexels.com/photo/turtle-swimming-underwater-10467/

什么是process address space/进程地址空间

所谓进程地址空间(process address space),就是从进程的视角看到的地址空间,是进程运行时所用到的虚拟地址的集合。

进程地址空间是虚拟地址

进程地址空间是程序运行的时候用到的虚拟地址

process address space的大小和分布

进程地址空间有多大呢?在32位有4gb大小,而64位则会上tb的级别,当然,这些都是虚拟出来的!

https://zhuanlan.zhihu.com/p/66794639

内核和用户空间的区别

用户进程和内核进程的进程地址空间会有区别吗?

什么是flat address space/平坦地址空间

什么是memory areas/内存区域

能够被进程访问到的地址空间才是memory areas

进程地址空间对应的内核结构

mm_struct结构描述了一个进程的进程地址空间的全部信息,定义在mm_types.h中

https://elixir.bootlin.com/linux/v5.15.82/source/include/linux/mm_types.h#L402

mm_struct中的重要组成部分

mmap和mm_rb

分别用链表和红黑树记录了该地址空间的全部内存区域

mmlist

操作系统中全部的mm_struct组成的链表

各种特殊区域的地址

1
2
3
unsigned long start_code,end_code,start_data,end_data;
unsigned long start_brk,brk,start_stack;
unsigned long arg_start,arg_end,env_start,env_end;

代码段code,数据段data,堆brk的首尾地址

栈stack的开始地址

命令行参数的首尾地址

环境变量的首尾地址

计数

有两个变量记录了正在使用该内存区域的计数

mm_users是正在使用该区域的线程数

mm_count是待定

mm_users/mm_conut

1
2
https://www.quora.com/Linux-Kernel-Why-are-we-using-two-variables-mm_users-and-mm_count-in-mm_struct
当mm_count为0时,mm_struct就会被撤销

进程地址空间可访问的部分-VMA

什么是VMA

进程地址空间有多大呢?在32位有4gb大小,而64位则会上tb的级别,当然,这些都是虚拟出来的!

而这么大的区域,其实能够被使用的部分才是真正有意义的,毕竟,看的到不一定能摸得到,笑

进程地址空间是一个进程看到的最大的空间,而一个进程能够访问的部分,才是最有价值的,叫做 memory areas/内存区域 ,在内核中使用vm_area_struct描述

memory areas/内存区域,在linux中也叫做 virtual memory areas,虚拟内存区域/VMA,这些名词都是同一个意思

最常被使用的叫法是VMA

定义

The kernel uses virtual memory areas to keep track of the process’s memory mappings; for example, a process has one VMA for its code, one VMA for each type of data, one VMA for each dist7inct memory mapping (if any), and so on. VMAs are processor-independent structures, with permissions and access control flags. Each VMA has a start address, a length, and their sizes are always a multiple of the page size (PAGE_SIZE). A VMA consists of a number of pages, each of which has an entry in the page table.**–by Linux Device Drivers Development

常见的VMA

一般来讲,一个进程都会有以下的vma

text section 代码段 可执行文件代码的内存映射
data section 数据段 可执行文件的已初始化全局变量的内存映射
bss段 可执行文件的未初始化全局变量的内存映射

进程地址空间的所属情况

每一个进程都会有它自己的进程地址空间,一个进程的所有的线程共享一个进程地址空间。在linux中,线程就是一种共享进程地址空间的进程,都是使用task_struct描述的,而没有单独的结构