如何在Linux中实现sbrk/brk?

sam*_*moz 19 linux system-calls sbrk brk

我在考虑Linux内核如何实现系统调用,我想知道是否有人可以给我一个关于sbrk/brk如何工作的高级视图?

我已经查看了内核代码,但是它有很多内容而且我不理解它.我希望得到某个人的摘要?

Ces*_*arB 23

在非常高级别的视图中,Linux内核将进程可见的内存跟踪为几个"内存区域"(struct vm_area_struct).还有一种结构表示(再次在非常高级别的视图中)进程的整个地址空间(struct mm_struct).每个进程(除了一些内核线程)都只有一个进程struct mm_struct,它反过来指向struct vm_area_struct它可以访问的所有内存.

sys_brk系统调用(中发现的mm/mmap.c)简单地调整某些内存区域.(sbrk是一个glibc包装brk).它通过比较brk地址的旧值(在里面找到struct mm_struct)和请求的值来实现.

首先看一下mmap函数族是更简单的,因为它brk是一个特例.


Jav*_*ier 18

您必须了解虚拟内存的工作原理,以及MMU映射与真实RAM的关系.

实际RAM分为页面,传统上每个4kB.每个进程都有自己的MMU映射,它为该进程提供了一个线性内存空间(32位linux中为4GB).当然,并非所有这些都是实际分配的.起初,它几乎是空的,也就是没有真正的页面与大多数地址相关联.

当进程遇到未分配的地址(尝试读取,写入或执行它)时,MMU会生成错误(类似于中断),并调用VM系统.如果它决定某些RAM应该在那里,它会选择一个未使用的RAM页面并与该地址范围相关联.

这样,内核不关心进程如何使用内存,并且进程并不关心有多少RAM,它总是具有相同的线性4GB地址空间.

现在,brk/sbrk工作处于稍高的水平:原则上任何内存地址"超出"该标记都是无效的,并且如果被访问将不会获得RAM页面,则该过程将被杀死.用户空间库管理此限制内的内存分配,并且仅在需要时请求内核增加它.

但即使通过设置brk为允许的最大值启动进程,在开始访问所有内存地址之前,也不会分配真正的RAM页面.