用户进程的有效地址空间是什么? (OS X和Linux)

时间:2011-03-05 12:15:34

标签: linux macos mmap

mmap系统调用文档说如果出现以下情况,该函数将失败:

  

指定了MAP_FIXED并添加了地址   参数不是页面对齐或部分   期望的地址空间驻留   超出有效的地址空间   用户流程。

我无法在任何地方找到说明作为有效地址进行映射的文档。 (我有兴趣在OS X和Linux上执行此操作,理想情况下,相同的地址对两者都有效。)。

2 个答案:

答案 0 :(得分:7)

Linux内核将自身的部分虚拟地址空间保留到用户空间(几乎)无法访问且无法映射任何内容的位置。您正在寻找所谓的“userspace / kernelspace split”。

在i386上,arch默认为3G / 1G one - 用户空间低3 GB的虚拟地址空间,内核高1 GB,另外还有2G / 2G和1G / 3G分割:

config PAGE_OFFSET
        hex
        default 0xB0000000 if VMSPLIT_3G_OPT
        default 0x80000000 if VMSPLIT_2G
        default 0x78000000 if VMSPLIT_2G_OPT
        default 0x40000000 if VMSPLIT_1G
        default 0xC0000000
        depends on X86_32

在x86_64上,用户空间位于(当前)48位虚拟地址空间的下半部分:

/*
 * User space process size. 47bits minus one guard page.
 */
#define TASK_SIZE_MAX   ((1UL << 47) - PAGE_SIZE)

答案 1 :(得分:1)

这取决于许多因素,其中许多因素都不在您的控制之下。正如adobriyan所提到的,根据操作系统,您有各种固定的上限,超出了内核代码和数据。通常,这个上限在32位操作系统上至少 2GB;一些操作系统提供额外的地址空间。 64位操作系统通常提供一个上限,由CPU支持的虚拟地址位数控制(通常至少40位地址空间)。但是,还有其他因素无法控制:

  • 在最新版本的linux上,mmap映射
  • 您不能制作与任何现有映射重叠的映射。由于动态链接器可以自由地映射到与可执行文件的固定部分不重叠的任何地方,这意味着可能会拒绝任何地址。
  • 内核可能会注入其他附加映射,例如system call gate
  • /proc/sys/vm/mmap_min_addr可以自行执行mmaps,它们位于某个任意位置

因此,没有办法绝对保证malloc会成功,所以通常应该避免。

我见过的唯一需要MAP_FIXED的地方是葡萄酒启动代码,该代码保留(使用MAP_FIXED)2G以上的所有地址,以避免混淆不相信的Windows代码映射将显示负面地址。当然,这是对旗帜的高度专业化使用。

如果你为了避免在共享内存中处理偏移而试图这样做,一种选择是在类中包装指针以自动处理偏移:

MAP_FIXED

注意:这是未经测试的代码,但应该为您提供基本的想法。