【问题标题】:Does mmap allocate a page or part of a page?mmap 是否分配页面或页面的一部分?
【发布时间】:2014-04-24 11:41:38
【问题描述】:

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

mprotect 也一样——是保护整个页面,还是只保护指定的部分?

【问题讨论】:

    标签: c++ c linux mmap mprotect


    【解决方案1】:

    是的。

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

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

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

    来源:POSIX

    【讨论】:

    • 我怀疑是这样的。很高兴得到明确的澄清,谢谢。
    【解决方案2】:

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

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

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

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

    【讨论】:

    • 我认为这并不完全正确。我认为它会将length 向上舍入为页面大小的倍数。
    • @zch 你的意思是如果长度不是页面大小的倍数, mmap 会向上取整吗?
    • 如果我没记错的话,是的。并不是手册页不需要 len 是页面大小的倍数,只有 offset
    • 不清楚手册页的内容 ;-) 我不是英语本地人,但我可以解释为它也是这么说的。但是仔细阅读,你是对的我错了。答案已更新,谢谢
    • @sircodesalot 是的。您可以查看 /proc/XXXX/mmap 进行检查。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-20
    • 2011-07-22
    • 2014-02-02
    • 2012-12-12
    • 1970-01-01
    • 2014-10-06
    相关资源
    最近更新 更多