一、内存管理架构
内存管理子系统架构可以分为:用户空间、内核空间及硬件部分3个层面,具体结构如
下图所示:
1、用户空间:
应用程序使用malloc()申请内存资源/free()释放内存资源。
2、内核空间:
内核总是驻留在内存中,是操作系统的一部分。内核空间为内核保留,
不允许应用程序读写该区域的内容或直接调用内核代码定义的函数。
3、硬件:
处理器包含一个内存管理单元(Memory Management Uint,MMU)的部
件,负责把虚拟地址转换为物理地址。
Linux内核使用内存描述符mm_struct,描述进程的用户虚拟地址空间,内核源码分析如下图所示:
二、虚拟地址空间布局架构
因为目前应用程序没有那么大的内存需求,所以
ARM64
处理器不支持完全的64位虚拟地址。
在
ARM64
架构的
Linux内核中,内核虚拟地址和用户虚拟地址的宽度相同。
所有进程共享内核虚拟地址空间,每个进程有独立的用户虚拟地址空间,同一个线程
组的用户线程共享用户虚拟地址空间,内核线程没有用户虚拟地址空间。
1、用户虚拟地址空间划分
进程的用户虚拟空间的起始地址是
0
,长度是
TASK_SIZE,由每种处理器架构定义自己的宏
TASK_SIZE
。
ARM64
架构定义的宏
TASK_SIZE如下: 32
位用户空间程序:
TASK_SIZE
的值是
TASK_SIZE_32
,即
0x100000000
,等
4GB
。
64
位用户空间程序:
TASK_SIZE
的值是
TASK_SIZE_64
,即
2^
VA_BITS
字节。
VA_BITS是编译内核的时候选择的虚拟地址位数。
进程的用户地址空间包含区域:
代码段、数据段、未初始化数据段;
动态库的代码段、数据段和未初始化数据段;
存放动态生成的数据的堆;
存放局部变量和实现函数调用的栈;
把文件区间映射到虚拟地址空间的内存映射区域;
存放在栈底部的环境变量和参数字符串。
用户虚拟地址空间
Linux
内核源码分析下图所示:
ARM64处理器架构内核地址空间布局如下图所示
:
KASAN:动态内存错误检查工具
一个进程的虚拟地址空间主要由两个数据结构进行描述。一个是最高层次的mm_struct, 较高层次的vm_area_struct。最高层次的mm_struct结构描述一个进程整个虚拟地址空间。较高层次结构描述虚拟地址空间的一个区间(称为虚拟区)。每个进程只有一个mm_struct,在每个进程的task_struct结构中,有一个专门指向该进程的结构。mm_struct结构是对整个用户空间的描述。