6

我很困惑,是mmap分配一整页内存(不管指定的大小),还是只分配您请求的大小?真的,我很好奇后续调用会发生什么mmap- 第二次调用会分配一个新页面(即使两个调用都使用页面大小以下的数量)还是会分配与前一个调用相邻的块?

同样的事情mprotect- 是保护整个页面,还是只保护指定的部分?

4

2 回答 2

9

是的。

但这不是因为mmap 本身,而是因为内核真的不能做任何不同的事情。内存是按页组织的,而 MMU 以页为单位“思考”,因此没有办法(无论如何都不是理智的、合理的方式)分配半页并将另一半分给其他人。
如果每个进程都分配了半页,例如如何防止进程 2 从进程 1 窃取机密数据?内存保护系统不是那样工作的,不可能防止这种情况发生。

mmap要求长度不为零,否则将失败。除此之外,它对输入参数没有要求(除了相互矛盾的标志),但当然总是允许实现由于其他原因而导致调用失败,由其自行决定(“实现”在这里意味着例如“Linux” )。

映射的有效地址(将通过成功调用返回mmap)是地址提示的实现定义函数。实际上,这意味着将提示向下舍入到前一页(通常为 4096 字节)边界,并将长度四舍五入下一页边界。
不同版本的 Linux 在某些地址范围上表现不同,例如在 2.6 版之前,下面的提示mmap_min_addr会失败,EINVAL而现在它会将地址向上取整,因此它是有效的。

资料来源:POSIX

于 2014-03-18T16:55:08.557 回答
6

如果长度参数不是页面大小的倍数,它将向上舍入为页面大小的倍数。

因此,您的问题的答案是肯定的,mmap()实际上只分配了整个页面。

关于mprotect()手册页清楚地回答您的问题:

mprotect() 更改调用进程的内存页的保护,该内存页包含区间 [addr, addr+len-1] 中的地址范围的任何部分。addr 必须与页面边界对齐。

于 2014-03-18T16:30:07.213 回答