Linux内存管理 brk(),mmap(),munmap()系统调用源码分析 基础部分

荣涛 2021年4月30日

  • 内核版本:linux-5.10.13
  • 注释版代码:https://github.com/Rtoax/linux-5.10.13

1. 用户态libc封装

1.1. brk

#include <unistd.h>int brk(void *addr);
void *sbrk(intptr_t increment);

1.2. mmap和munmap

#include <sys/mman.h>void *mmap(void *addr, size_t length, int prot, int flags,int fd, off_t offset);
int munmap(void *addr, size_t length);

1.2.1. prot取值

  • PROT_EXEC Pages may be executed.
  • PROT_READ Pages may be read.
  • PROT_WRITE Pages may be written.
  • PROT_NONE Pages may not be accessed.

1.2.2. flags取值

  • MAP_SHARED:进程间共享,共享内存的一种
  • MAP_PRIVATE:进程私有,当malloc一大块内存时,即为该选项
  • MAP_32BIT: 映射到用户地址空间的前2G中;
  • MAP_ANON
  • MAP_ANONYMOUS:初始化为0的匿名映射
  • MAP_DENYWRITE:忽略
  • MAP_EXECUTABLE:忽略
  • MAP_FILE:忽略
  • MAP_FIXED:准确解释地址,如果addr和len指定的内存区域与任何现有映射的页面重叠,则现有映射的重叠部分将被丢弃
  • MAP_GROWSDOWN:用于栈
  • MAP_HUGETLB:大页内存,闻名于DPDK
  • MAP_LOCKED:不会被swap出去
  • MAP_NONBLOCK:仅与MAP_POPULATE结合使用才有意义,不执行预读:仅为RAM中已经存在的页面创建页表条目。 从Linux 2.6.23开始,此标志使MAP_POPULATE不执行任何操作。
  • MAP_NORESERVE:不要为此映射提供swap空间
  • MAP_POPULATE:填充页表以进行映射。 对于文件映射,这将导致文件上的预读。 pagefault不会阻止以后对映射的访问。 仅从Linux 2.6.23开始,专用映射才支持MAP_POPULATE。
  • MAP_STACK:用于栈
  • MAP_UNINITIALIZED:用于提高嵌入式设备的性能

需要注意的是,以上的选项很多,不用每个选项都清楚其原理和使用,就我来说,目前我是用过的只有MAP_SHAREDMAP_PRIVATEMAP_HUGETLBMAP_LOCKED这些常用的,剩下的我也没做过研究。

2. 内核中的入口点

2.1. brk

//mm\mmap.c
SYSCALL_DEFINE1(brk, unsigned long, brk);

2.2. mmap

//mm\mmap.c
SYSCALL_DEFINE6(mmap_pgoff, unsigned long, addr, unsigned long, len,unsigned long, prot, unsigned long, flags,unsigned long, fd, unsigned long, pgoff);//arch\x86\kernel\sys_x86_64.c
SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len,unsigned long, prot, unsigned long, flags,unsigned long, fd, unsigned long, off);

2.3. munmap

//mm\mmap.c
SYSCALL_DEFINE2(munmap, unsigned long, addr, size_t, len);

3. 内核调用栈

3.1. brk

SYSCALL_DEFINE1(brk, unsigned long, brk)check_data_rlimit()if (brk <= mm->brk)__do_munmap(...) -> 见 munmapfind_vmado_brk_flagsget_unmapped_areamunmap_vma_rangemay_expand_vmsecurity_vm_enough_memory_mmvma_mergevm_area_allocvma_set_anonymousvma_linkperf_event_mmapuserfaultfd_unmap_completeif (populate)mm_populate__mm_populate

3.2. mmap

SYSCALL_DEFINE6(mmap_pgoff, ...)
SYSCALL_DEFINE6(mmap,...)ksys_mmap_pgoffif (!(flags & MAP_ANONYMOUS))audit_mmap_fdfgetif (is_file_hugepages(file))else if (flags & MAP_HUGETLB)hstate_sizeloghugetlb_file_setupvm_mmap_pgoffsecurity_mmap_fileif (!ret)do_mmapuserfaultfd_unmap_completeif (populate)mm_populate -> 同 brk

3.3. munmap

SYSCALL_DEFINE2(munmap, unsigned long, addr, size_t, len)untagged_addrprofile_munmap__vm_munmap__do_munmaparch_unmapfind_vmaunmap_regionremove_vma_listuserfaultfd_unmap_complete

4. 相关内核数据结构

以下简化的三个数据结构承载了用户空间地址管理的任务,具体这三个数据结构的架构图

图片链接http://static.duartes.org/img/blogPosts/memoryDescriptorAndMemoryAreas.png

4.1. task_struct

struct task_struct {...struct mm_struct      *mm;struct mm_struct        *active_mm;...
};

4.2. mm_struct

struct mm_struct {...struct vm_area_struct *mmap;struct rb_root mm_rb;unsigned long start_code, end_code, start_data, end_data;   /* brk() */unsigned long start_brk, brk, start_stack;...
};

4.3. vm_area_struct

struct vm_area_struct {...unsigned long vm_start;unsigned long vm_end;struct vm_area_struct *vm_next, *vm_prev;struct rb_node vm_rb;struct file * vm_file;pgd_t * pgd; //全局页目录...
};

在理解了VMA管理后,进行正式的源码分析,但是有必要先说一下进程地址空间的结构,这里我们就以32bit系统为例,64bit系统大同小异。

图片来源https://imgs.developpaper.com/imgs/4192938510-82183e6d4e7dc101_articlex.png

5. 相关链接

  • https://www.cs.unc.edu/~porter/courses/cse506/f12/slides/address-spaces.pdf
  • https://stackoverflow.com/questions/14943990/overlapping-pages-with-mmap-map-fixed

Linux内存管理 brk(),mmap()系统调用源码分析1:基础部分相关推荐

  1. Linux内存管理 brk(),mmap()系统调用源码分析2:brk()的内存释放流程

    Linux brk(),mmap()系统调用源码分析 brk()的内存释放流程 荣涛 2021年4月30日 内核版本:linux-5.10.13 注释版代码:https://github.com/Rt ...

  2. 【Linux 内核 内存管理】mmap 系统调用源码分析 ④ ( do_mmap 函数执行流程 | do_mmap 函数源码 )

    文章目录 一.do_mmap 函数执行流程 二.do_mmap 函数源码 调用 mmap 系统调用 , 先检查 " 偏移 " 是否是 " 内存页大小 " 的 & ...

  3. Linux brk(),mmap()系统调用源码分析3:brk()的内存申请流程

    Linux brk(),mmap()系统调用源码分析 brk()的内存申请流程 荣涛 2021年4月30日 内核版本:linux-5.10.13 注释版代码:https://github.com/Rt ...

  4. 【Linux 内核】进程管理 ( 进程相关系统调用源码分析 | fork() 源码 | vfork() 源码 | clone() 源码 | _do_fork() 源码 | do_fork() 源码 )

    文章目录 一.fork 系统调用源码 二.vfork 系统调用源码 三.clone 系统调用源码 四._do_fork 函数源码 五.do_fork 函数源码 Linux 进程相关 " 系统 ...

  5. 【C++内存管理】loki::allocator 源码分析

    loki 是书籍 <Modern C++ Design>配套发行的一个 C++ 代码库,里面对模板的使用发挥到了极致,对设计模式进行了代码实现.这里是 loki 库的源码. ps. 有空是 ...

  6. (转)Linux设备驱动之HID驱动 源码分析

    //Linux设备驱动之HID驱动 源码分析 http://blog.chinaunix.net/uid-20543183-id-1930836.html HID是Human Interface De ...

  7. 分页池内存持续增长_鸿蒙内核源码分析(从进程/线程视角看内存)

    这篇文章说说内存,内存的管理是极其复杂的模块,涉及到非常多概念,光地址就有逻辑,线性,物理地址三个,网上文章很多,参差不齐,没有很好基础或实战经验的同学基本得懵掉,本篇最后也有这些概念介绍.系列篇打算 ...

  8. 掌握鸿蒙轻内核静态内存的使用,从源码分析开始

    摘要:静态内存实质上是一个静态数组,静态内存池内的块大小在初始化时设定,初始化后块大小不可变更.静态内存池由一个控制块和若干相同大小的内存块构成.控制块位于内存池头部,用于内存块管理.内存块的申请和释 ...

  9. Linux线程同步(三)---互斥锁源码分析

    先给自己打个广告,本人的微信公众号:嵌入式Linux江湖,主要关注嵌入式软件开发,股票基金定投,足球等等,希望大家多多关注,有问题可以直接留言给我,一定尽心尽力回答大家的问题. 一 源码分析 1.li ...

最新文章

  1. 2018python培训-Python学习之路—2018/7/2
  2. 【ASP.NET开发】ASP.NET(MVC)三层架构知识的学习总结
  3. 一道异常处理执行顺序面试题的简单分析
  4. setTimeout and jquery
  5. QML模块定义qmldir文件
  6. NumPy之:理解广播
  7. P3435-[POI2006]OKR-Periods of Words【KMP】
  8. 用友t3显示无法解析服务器名称,用友T3软件进入用友通提示不能解析端口,不能登录服务器...
  9. 力扣93. 复原 IP 地址(JavaScript)
  10. 2013 Multi-University Training Contest 4
  11. Perceptual:英特尔感知计算挑战赛 正式启动
  12. 【Mybatis】maven配置pom.xml时找不到依赖项(已解决)
  13. 【数据结构和算法笔记】:图的储存方式(邻接矩阵,邻接表)
  14. ffmpeg系列-解决ffmpeg获取aac音频文件duration不准
  15. xp的guest访问
  16. python黑帽子学习笔记(三)—— ssh隧道
  17. wsus微软补丁升级服务器不能下发,WSUS配置微软升级服务器操作.doc
  18. 模电课程设计_函数发生器
  19. 浅谈EV证书的作用及思考
  20. c语言求成绩标准差,C语言中求和、计算平均值、方差和标准差的实例

热门文章

  1. 关于Java List 的remove(index)方法
  2. Hanlp得到语义相似度的方法
  3. Python中数组,列表,元组的区别、定义、功能
  4. 【Codeforces Round #507 (Div. 2, based on Olympiad of Metropolises) B】Shashlik Cooking
  5. C++学习笔记(九)——引用
  6. Educational Codeforces Round 25 E. Minimal Labelshdu1258
  7. TCP系列05—连接管理—4、TCP连接的ISN、连接建立超时及TCP的长短连接
  8. 探求Floyd算法的动态规划本质
  9. 公益图书馆-学习笔记五-jquery来动态设置div高度
  10. 图片抓取_小小爬虫批量抓取微信推文里的图片