快捷搜索:  汽车  科技

如何理解虚拟地址空间:虚拟地址空间布局架构

如何理解虚拟地址空间:虚拟地址空间布局架构#include <stdio.h> #include <stdlib.h> #include <unistd.h> #define MAX 1024 int main(int argc char* argv[]) { int *p = sbrk(0); int *old = p; p = sbrk(MAX*MAX); if(p == (void*)(-1)) { perror("sbrk error.\n"); exit(-1); } printf("old:%p\np:%p\n" p old); int *new=sbrk(0); printf("new:%p\n" new); print

内存管理架构

内存管理子系统架构可以分为:用户空间、内核空间及硬件部分3个层面。

用户空间:应用程序使用malloc()申请内存资源/free()释放内存资源。
内核空间:内核总是驻留在内存中,是操作系统的一部分。内核空间为内核保留, 不允许应用程序读写该区域的内容或直接调用内核代码定义的函数。
硬件:处理器包含一个内存管理单元(Memory Management Uint MMU)的部 件,负责把虚拟地址转换为物理地址。
linux内核整体架构及子系统
Linux内核只是操作系统当中的一部分,对下管理系统所有硬件设备;对上通过系统调用向Library Routinue或(或者其它应用程序提供API接口)。

如何理解虚拟地址空间:虚拟地址空间布局架构(1)

重心:管理硬件设备、供应用程序使用。
现在系统标准组成:CPU、Memory内存和外存)、I/O设备、网络设备和其他外围设备。

如何理解虚拟地址空间:虚拟地址空间布局架构(2)

如何理解虚拟地址空间:虚拟地址空间布局架构(3)

更多linux内核视频教程文档资料免费领取后台私信【内核】自行获取.

如何理解虚拟地址空间:虚拟地址空间布局架构(4)

如何理解虚拟地址空间:虚拟地址空间布局架构(5)

Linux内核源码/内存调优/文件系统/进程管理/设备驱动/网络协议栈-学习视频教程-腾讯课堂

用户空间

应用程序使用malloc()申请内存,free()释放内存。malloc()/free()是glibc库的内存分配器ptmalloc提供的接口,ptmalloc使用系统调用brk或mmap向内核以页为单位申请内存,然后进行分成很小的内存块分配给对应的应用程序。

内核空间

虚拟内存管理负责从进程的虚拟地址空间分配虚拟页,sys_brk来扩大或收缩堆,sys_mmap用来在内存映射区域分配虚拟页,sysmunmap用来释放虚拟页。页分配器负责分配物理页,使用的分配器是伙伴分配器。
内核空间扩展功能,不连续页分配器提供分配内存的接口vmalloc和释放内存接口vfree。在内存碎片化的时候,申请连续物理页的成功率比较低,可以申请不连续的物理页,映射到连续的虚拟页,即虚拟地址连续而物理地址不连续。
内存控制组用来控制进程占用的内存资源。当内存碎片化的时候,找不到连续的物理页,内存碎片整理通过迁移方式得到连续的物理页。在内存不足的时候,页回收负责回收物理页。

硬件

MMU包含一个页表缓存,保存最近使用过的页表映射,避免每次把虚拟地址转换为物理地址都需要查询内存中的页表。解决处理器执行速度和内存速度不匹配问题,中间增加一个缓存。一级缓存分为数据缓存和指令缓存。二级作用协调一级缓存和内存之间的工作效率。

系统调用(system call)

如何理解虚拟地址空间:虚拟地址空间布局架构(6)

#include <stdio.h> #include <stdlib.h> #include <unistd.h> #define MAX 1024 int main(int argc char* argv[]) { int *p = sbrk(0); int *old = p; p = sbrk(MAX*MAX); if(p == (void*)(-1)) { perror("sbrk error.\n"); exit(-1); } printf("old:%p\np:%p\n" p old); int *new=sbrk(0); printf("new:%p\n" new); printf("pid=%d\n" getpid()); while(1); sbrk(-MAX*MAX); return 0; }

如何理解虚拟地址空间:虚拟地址空间布局架构(7)

如何理解虚拟地址空间:虚拟地址空间布局架构(8)

虚拟地址空间布局架构

应用程序没有那么大的内存需求,ARM64处理器不支持完全的64位虚拟地址。
在ARM64架构的Linux内核中,内核虚拟地址和用户虚拟地址的宽度相同。 所有进程共享内核虚拟地址空间,每个进程有独立的用户虚拟地址空间,同一个线程组的用户线程共享用户虚拟地址空间,内核线程没有用户虚拟地址空间。

如何理解虚拟地址空间:虚拟地址空间布局架构(9)

用户虚拟地址空间划分

进程的用户虚拟空间的起始地址是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是编译内核时候选择的虚拟地址位数
进程的用户虚拟地址空间包含区域:

代码段、数据段、未初始化的数据段
动态库的代码段、数据段和未初始化的数据段
存放动态生成的数据的堆
存放局部变量和实现函数调用的栈
把文件区间映射到虚拟地址空间的内存映射区域
存放在栈底部的环境变量和参数字符串
内核使用内存描述符mm_struct描述进程的用户虚拟地址空间。
一个进程的虚拟地址空间主要由两个数据结构进行描述。一个是最高层次的mm_struct,一个是较高层次的vm_area_struct。最高层次mm_struct描述一个进程整个虚拟地址空间,较高层次结构描述虚拟地址空间的一个区间(称为虚拟区)。每个进程只有一个mm_struct结构,在每个进程的task_struct结构中,有一个专门用来指向该进程的结构。mm_struct结构是对整个用户空间的描述。

如何理解虚拟地址空间:虚拟地址空间布局架构(10)

内核地址空间布局

KASAN:动态内存错误检查工具
[外链图片转存失败 源站可能有防盗链机制 建议将图片保存下来直接上传(img-yY3P7wzG-1642343462340)(C:\Users\Lenovo\Pictures\2700310-20220107234027970-821637894.png)]

总结

本文介绍了Linux内存管理架构,包括用户空间、内核空间、硬件部分,系统调用作用;虚拟地址空间架构,虚拟地址空间划分,内核地址空间布局等。

转载地址:虚拟地址空间布局架构 - 内存管理 - 我爱内核网 - 构建全国最权威的内核技术交流分享论坛

如何理解虚拟地址空间:虚拟地址空间布局架构(11)

猜您喜欢: